2 * Copyright © 2019 IBM.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package org.onap.ccsdk.cds.controllerblueprints.core
19 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.*
20 import org.onap.ccsdk.cds.controllerblueprints.core.data.ConstraintClause
21 import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
22 import org.onap.ccsdk.cds.controllerblueprints.core.data.EntrySchema
23 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
24 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.*
25 import kotlin.reflect.KClass
26 import kotlin.reflect.KProperty1
27 import kotlin.reflect.KType
28 import kotlin.reflect.full.declaredMemberProperties
30 fun <T : KClass<*>> T.asBluePrintsDataTypes(): DataType {
31 val annotation = this.annotations.filter { it is BluePrintsDataType }.single() as BluePrintsDataType
32 checkNotNull(annotation) { "BluePrintsDataType annotation definition not found" }
33 val dataType = DataType().apply {
35 version = annotation.version
36 derivedFrom = annotation.derivedFrom
37 description = annotation.description
39 dataType.properties = this.asPropertyDefinitionMap()
43 fun <T : KClass<*>> T.asPropertyDefinitionMap(): MutableMap<String, PropertyDefinition> {
44 val properties: MutableMap<String, PropertyDefinition> = hashMapOf()
45 this.declaredMemberProperties.forEach { member ->
46 properties[member.name] = member.asPropertyDefinition()
51 fun <T> KProperty1<T, *>.asPropertyDefinition(): PropertyDefinition {
52 val property = PropertyDefinition()
53 property.id = this.name
54 val getter = this.getter
55 property.required = !this.returnType.isMarkedNullable
56 property.type = this.returnType.asBluePrintsDataType(this.name)
57 if (this.returnType.arguments.isNotEmpty()) {
58 property.entrySchema = this.returnType.entitySchema()
60 this.annotations.forEach { fieldAnnotation ->
61 //println("Field : ${this.name} : Annotation : $fieldAnnotation")
62 when (fieldAnnotation) {
63 is BluePrintsProperty ->
64 property.description = fieldAnnotation.description
65 is PropertyDefaultValue ->
66 property.value = fieldAnnotation.value.asJsonType(property.type)
67 is BluePrintsConstrain -> {
68 if (property.constraints == null) property.constraints = arrayListOf()
69 property.constraints!!.add(fieldAnnotation.asBluePrintConstraintClause())
71 is InputExpression -> {
72 property.value = getInput(fieldAnnotation.propertyName)
74 is PropertyExpression -> {
75 property.value = getNodeTemplateProperty(fieldAnnotation.modelableEntityName,
76 fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
78 is AttributeExpression -> {
79 property.value = getNodeTemplateAttribute(fieldAnnotation.modelableEntityName,
80 fieldAnnotation.attributeName, fieldAnnotation.subAttributeName)
82 is ArtifactExpression -> {
83 property.value = getNodeTemplateArtifact(fieldAnnotation.modelableEntityName,
84 fieldAnnotation.artifactName)
86 is OperationOutputExpression -> {
87 property.value = getNodeTemplateOperationOutput(fieldAnnotation.modelableEntityName,
88 fieldAnnotation.interfaceName, fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
91 property.value = dslExpression(fieldAnnotation.propertyName)
98 internal fun BluePrintsConstrain.asBluePrintConstraintClause(): ConstraintClause {
102 internal fun <T : KType> T.entitySchema(): EntrySchema {
103 val entrySchema = EntrySchema()
104 if (this.arguments.size == 1) {
105 entrySchema.type = this.arguments[0].type!!.asBluePrintsDataType("")
106 } else if (this.arguments.size == 2) {
107 entrySchema.type = this.arguments[1].type!!.asBluePrintsDataType("")
112 internal fun <T : KType> T.asBluePrintsDataType(propertyName: String): String {
113 val simpleName = (this.classifier as? KClass<*>)?.java?.simpleName
114 ?: throw BluePrintException("filed to get simple name.")
115 return when (simpleName) {
116 "String", "Date" -> BluePrintConstants.DATA_TYPE_STRING
117 "int" -> BluePrintConstants.DATA_TYPE_INTEGER
118 "Boolean" -> BluePrintConstants.DATA_TYPE_BOOLEAN
119 "Float" -> BluePrintConstants.DATA_TYPE_FLOAT
120 "Double" -> BluePrintConstants.DATA_TYPE_DOUBLE
121 "List" -> BluePrintConstants.DATA_TYPE_LIST
122 "Map" -> BluePrintConstants.DATA_TYPE_MAP
123 "Object", "JsonNode", "ObjectNode", "ArrayNode" -> BluePrintConstants.DATA_TYPE_JSON