1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.libraries.pcc.chronicle.analysis 18 19 import com.android.libraries.pcc.chronicle.api.Connection 20 import com.android.libraries.pcc.chronicle.api.ConnectionProvider 21 import com.android.libraries.pcc.chronicle.api.DataTypeDescriptor 22 import com.android.libraries.pcc.chronicle.api.DataTypeDescriptorSet 23 import com.android.libraries.pcc.chronicle.api.ManagementStrategy 24 import com.android.libraries.pcc.chronicle.api.ProcessorNode 25 import com.android.libraries.pcc.chronicle.api.error.ConnectionTypeAmbiguity 26 import com.android.libraries.pcc.chronicle.util.TypedMap 27 28 /** 29 * Default implementation of [ChronicleContext] configured and intended to represent the data-flow 30 * characteristics and requirements of Chronicle in the process. 31 */ 32 class DefaultChronicleContext( 33 override val connectionProviders: Set<ConnectionProvider>, 34 override val processorNodes: Set<ProcessorNode>, 35 override val policySet: PolicySet, 36 override val dataTypeDescriptorSet: DataTypeDescriptorSet, 37 override val connectionContext: TypedMap = TypedMap() 38 ) : ChronicleContext { 39 private val connectionProviderByType: Map<Class<out Connection>, ConnectionProvider> 40 private val dtdByType: Map<Class<out Connection>, DataTypeDescriptor> 41 private val mgmtStrategyByType: Map<Class<out Connection>, ManagementStrategy> 42 43 // Note: It would be nice to not have to do this much work each time we create a new 44 // ChronicleContextImpl when adding a node. 45 init { 46 val tempConnectionProviders = mutableMapOf<Class<out Connection>, ConnectionProvider>() 47 val tempDtds = mutableMapOf<Class<out Connection>, DataTypeDescriptor>() 48 val tempMgmtProperties = mutableMapOf<Class<out Connection>, ManagementStrategy>() 49 50 connectionProviders.forEach { connectionProvider -> 51 val dataType = connectionProvider.dataType 52 dataType.connectionTypes.forEach { connectionType -> 53 // Make sure we do not have connection ambiguity. 54 val existingConnectionProvider = tempConnectionProviders[connectionType] 55 if (existingConnectionProvider != null) { 56 throw ConnectionTypeAmbiguity( 57 connectionType, 58 setOf(existingConnectionProvider, connectionProvider) 59 ) 60 } 61 tempConnectionProviders[connectionType] = connectionProvider 62 tempDtds[connectionType] = dataType.descriptor 63 tempMgmtProperties[connectionType] = dataType.managementStrategy 64 } 65 } 66 67 connectionProviderByType = tempConnectionProviders 68 dtdByType = tempDtds 69 mgmtStrategyByType = tempMgmtProperties 70 } 71 72 override fun <T : Connection> findConnectionProvider( 73 connectionType: Class<T> 74 ): ConnectionProvider? { 75 return connectionProviderByType[connectionType] 76 } 77 78 override fun <T : Connection> findDataType(connectionType: Class<T>): DataTypeDescriptor? { 79 return dtdByType[connectionType] 80 } 81 82 override fun withNode(node: ProcessorNode): ChronicleContext { 83 return DefaultChronicleContext( 84 connectionProviders = connectionProviders, 85 processorNodes = processorNodes + node, 86 policySet = policySet, 87 dataTypeDescriptorSet = dataTypeDescriptorSet, 88 connectionContext = connectionContext 89 ) 90 } 91 92 /** 93 * Returns a copy of the current [ChronicleContext] containing the provided [connectionContext]. 94 */ 95 override fun withConnectionContext(connectionContext: TypedMap): ChronicleContext { 96 return DefaultChronicleContext( 97 connectionProviders = connectionProviders, 98 processorNodes = processorNodes, 99 policySet = policySet, 100 dataTypeDescriptorSet = dataTypeDescriptorSet, 101 connectionContext = connectionContext 102 ) 103 } 104 105 override fun equals(other: Any?): Boolean { 106 if (this === other) return true 107 if (javaClass != other?.javaClass) return false 108 109 other as DefaultChronicleContext 110 111 if (connectionProviders != other.connectionProviders) return false 112 if (processorNodes != other.processorNodes) return false 113 if (policySet != other.policySet) return false 114 if (connectionContext != other.connectionContext) return false 115 116 return true 117 } 118 119 override fun hashCode(): Int { 120 var result = connectionProviders.hashCode() 121 result = 31 * result + processorNodes.hashCode() 122 result = 31 * result + policySet.hashCode() 123 result = 31 * result + connectionContext.hashCode() 124 return result 125 } 126 } 127