Fixing Blueprint Typo's and docs
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / blueprints / 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.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
43
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 {
48         id = annotation.name
49         version = annotation.version
50         derivedFrom = annotation.derivedFrom
51         description = annotation.description
52     }
53     dataType.properties = this.asPropertyDefinitionMap()
54     return dataType
55 }
56
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()
61     }
62     return properties
63 }
64
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()
73     }
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())
84             }
85             is InputExpression -> {
86                 property.value = getInput(fieldAnnotation.propertyName)
87             }
88             is PropertyExpression -> {
89                 property.value = getNodeTemplateProperty(
90                     fieldAnnotation.modelableEntityName,
91                     fieldAnnotation.propertyName, fieldAnnotation.subPropertyName
92                 )
93             }
94             is AttributeExpression -> {
95                 property.value = getNodeTemplateAttribute(
96                     fieldAnnotation.modelableEntityName,
97                     fieldAnnotation.attributeName, fieldAnnotation.subAttributeName
98                 )
99             }
100             is ArtifactExpression -> {
101                 property.value = getNodeTemplateArtifact(
102                     fieldAnnotation.modelableEntityName,
103                     fieldAnnotation.artifactName
104                 )
105             }
106             is OperationOutputExpression -> {
107                 property.value = getNodeTemplateOperationOutput(
108                     fieldAnnotation.modelableEntityName,
109                     fieldAnnotation.interfaceName, fieldAnnotation.propertyName, fieldAnnotation.subPropertyName
110                 )
111             }
112             is DSLExpression -> {
113                 property.value = dslExpression(fieldAnnotation.propertyName)
114             }
115         }
116     }
117     return property
118 }
119
120 internal fun BluePrintsConstrain.asBluePrintConstraintClause(): ConstraintClause {
121     TODO()
122 }
123
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("")
130     }
131     return entrySchema
132 }
133
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
146         else -> simpleName
147     }
148 }