dafd076fbb9d279020512590d3e861676cecfde3
[ccsdk/cds.git] / ms / controllerblueprints / modules / blueprint-core / src / main / kotlin / org / onap / ccsdk / cds / controllerblueprints / core / BluePrintExtensionFunctions.kt
1 /*
2  *  Copyright © 2019 IBM.
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 org.onap.ccsdk.cds.controllerblueprints.core
18
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
29
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 {
34         id = annotation.name
35         version = annotation.version
36         derivedFrom = annotation.derivedFrom
37         description = annotation.description
38     }
39     dataType.properties = this.asPropertyDefinitionMap()
40     return dataType
41 }
42
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()
47     }
48     return properties
49 }
50
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()
59     }
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())
70             }
71             is InputExpression -> {
72                 property.value = getInput(fieldAnnotation.propertyName)
73             }
74             is PropertyExpression -> {
75                 property.value = getNodeTemplateProperty(fieldAnnotation.modelableEntityName,
76                         fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
77             }
78             is AttributeExpression -> {
79                 property.value = getNodeTemplateAttribute(fieldAnnotation.modelableEntityName,
80                         fieldAnnotation.attributeName, fieldAnnotation.subAttributeName)
81             }
82             is ArtifactExpression -> {
83                 property.value = getNodeTemplateArtifact(fieldAnnotation.modelableEntityName,
84                         fieldAnnotation.artifactName)
85             }
86             is OperationOutputExpression -> {
87                 property.value = getNodeTemplateOperationOutput(fieldAnnotation.modelableEntityName,
88                         fieldAnnotation.interfaceName, fieldAnnotation.propertyName, fieldAnnotation.subPropertyName)
89             }
90             is DSLExpression -> {
91                 property.value = dslExpression(fieldAnnotation.propertyName)
92             }
93         }
94     }
95     return property
96 }
97
98 internal fun BluePrintsConstrain.asBluePrintConstraintClause(): ConstraintClause {
99     TODO()
100 }
101
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("")
108     }
109     return entrySchema
110 }
111
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
124         else -> simpleName
125     }
126 }