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.ArtifactExpression
20 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.AttributeExpression
21 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.BluePrintsConstrain
22 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.BluePrintsDataType
23 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.BluePrintsProperty
24 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.DSLExpression
25 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.InputExpression
26 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.OperationOutputExpression
27 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.PropertyDefaultValue
28 import org.onap.ccsdk.cds.controllerblueprints.core.annotations.PropertyExpression
29 import org.onap.ccsdk.cds.controllerblueprints.core.data.ConstraintClause
30 import org.onap.ccsdk.cds.controllerblueprints.core.data.DataType
31 import org.onap.ccsdk.cds.controllerblueprints.core.data.EntrySchema
32 import org.onap.ccsdk.cds.controllerblueprints.core.data.PropertyDefinition
33 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.dslExpression
34 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getInput
35 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getNodeTemplateArtifact
36 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getNodeTemplateAttribute
37 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getNodeTemplateOperationOutput
38 import org.onap.ccsdk.cds.controllerblueprints.core.dsl.getNodeTemplateProperty
39 import kotlin.reflect.KClass
40 import kotlin.reflect.KProperty1
41 import kotlin.reflect.KType
42 import kotlin.reflect.full.declaredMemberProperties
44 fun <T : KClass<*>> T.asBluePrintsDataTypes(): DataType {
45 val annotation = this.annotations.filter { it is BluePrintsDataType }.single() as BluePrintsDataType
46 checkNotNull(annotation) { "BluePrintsDataType annotation definition not found" }
47 val dataType = DataType().apply {
49 version = annotation.version
50 derivedFrom = annotation.derivedFrom
51 description = annotation.description
53 dataType.properties = this.asPropertyDefinitionMap()
57 fun <T : KClass<*>> T.asPropertyDefinitionMap(): MutableMap<String, PropertyDefinition> {
58 val properties: MutableMap<String, PropertyDefinition> = hashMapOf()
59 this.declaredMemberProperties.forEach { member ->
60 properties[member.name] = member.asPropertyDefinition()
65 fun <T> KProperty1<T, *>.asPropertyDefinition(): PropertyDefinition {
66 val property = PropertyDefinition()
67 property.id = this.name
68 val getter = this.getter
69 property.required = !this.returnType.isMarkedNullable
70 property.type = this.returnType.asBluePrintsDataType(this.name)
71 if (this.returnType.arguments.isNotEmpty()) {
72 property.entrySchema = this.returnType.entitySchema()
74 this.annotations.forEach { fieldAnnotation ->
75 // println("Field : ${this.name} : Annotation : $fieldAnnotation")
76 when (fieldAnnotation) {
77 is BluePrintsProperty ->
78 property.description = fieldAnnotation.description
79 is PropertyDefaultValue ->
80 property.value = fieldAnnotation.value.asJsonType(property.type)
81 is BluePrintsConstrain -> {
82 if (property.constraints == null) property.constraints = arrayListOf()
83 property.constraints!!.add(fieldAnnotation.asBluePrintConstraintClause())
85 is InputExpression -> {
86 property.value = getInput(fieldAnnotation.propertyName)
88 is PropertyExpression -> {
89 property.value = getNodeTemplateProperty(
90 fieldAnnotation.modelableEntityName,
91 fieldAnnotation.propertyName, fieldAnnotation.subPropertyName
94 is AttributeExpression -> {
95 property.value = getNodeTemplateAttribute(
96 fieldAnnotation.modelableEntityName,
97 fieldAnnotation.attributeName, fieldAnnotation.subAttributeName
100 is ArtifactExpression -> {
101 property.value = getNodeTemplateArtifact(
102 fieldAnnotation.modelableEntityName,
103 fieldAnnotation.artifactName
106 is OperationOutputExpression -> {
107 property.value = getNodeTemplateOperationOutput(
108 fieldAnnotation.modelableEntityName,
109 fieldAnnotation.interfaceName, fieldAnnotation.propertyName, fieldAnnotation.subPropertyName
112 is DSLExpression -> {
113 property.value = dslExpression(fieldAnnotation.propertyName)
120 internal fun BluePrintsConstrain.asBluePrintConstraintClause(): ConstraintClause {
124 internal fun <T : KType> T.entitySchema(): EntrySchema {
125 val entrySchema = EntrySchema()
126 if (this.arguments.size == 1) {
127 entrySchema.type = this.arguments[0].type!!.asBluePrintsDataType("")
128 } else if (this.arguments.size == 2) {
129 entrySchema.type = this.arguments[1].type!!.asBluePrintsDataType("")
134 internal fun <T : KType> T.asBluePrintsDataType(propertyName: String): String {
135 val simpleName = (this.classifier as? KClass<*>)?.java?.simpleName
136 ?: throw BluePrintException("filed to get simple name.")
137 return when (simpleName) {
138 "String", "Date" -> BluePrintConstants.DATA_TYPE_STRING
139 "int" -> BluePrintConstants.DATA_TYPE_INTEGER
140 "Boolean" -> BluePrintConstants.DATA_TYPE_BOOLEAN
141 "Float" -> BluePrintConstants.DATA_TYPE_FLOAT
142 "Double" -> BluePrintConstants.DATA_TYPE_DOUBLE
143 "List" -> BluePrintConstants.DATA_TYPE_LIST
144 "Map" -> BluePrintConstants.DATA_TYPE_MAP
145 "Object", "JsonNode", "ObjectNode", "ArrayNode" -> BluePrintConstants.DATA_TYPE_JSON