Reformat catalog-model
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / tosca / converters / DataTypePropertyConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.model.tosca.converters;
21
22 import com.google.gson.Gson;
23 import com.google.gson.JsonElement;
24 import com.google.gson.JsonObject;
25 import com.google.gson.JsonParser;
26 import com.google.gson.stream.JsonReader;
27 import java.io.StringReader;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import org.openecomp.sdc.be.model.DataTypeDefinition;
32 import org.openecomp.sdc.be.model.PropertyDefinition;
33 import org.openecomp.sdc.common.util.JsonUtils;
34
35 public class DataTypePropertyConverter {
36
37     private static final DataTypePropertyConverter INSTANCE = new DataTypePropertyConverter();
38     private static final JsonParser jsonParser = new JsonParser();
39     private static final Gson gson = new Gson();
40
41     private DataTypePropertyConverter() {
42     }
43
44     public static DataTypePropertyConverter getInstance() {
45         return INSTANCE;
46     }
47
48     /**
49      * @param propertyDataType the data type
50      * @param dataTypes        all data types in the system mapped by their name
51      * @return a json representation of all the given data type properties default values and recursively their data type properties
52      */
53     public String getDataTypePropertiesDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
54         JsonObject defaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
55         return !JsonUtils.isJsonNullOrEmpty(defaultValues) ? gson.toJson(defaultValues) : null;
56     }
57
58     /**
59      * Takes a json representation of a tosca property value and merges all the default values of the property data type
60      *
61      * @param value            the json representation of a tosca property value
62      * @param propertyDataType data type from which to merge default values
63      * @param dataTypes        all data types in the system mapped by their name for example: for value {a: {b: c}} we could have a default value {a:
64      *                         {d: e}} (property a has two sub properties but only b was overridden) so the complete value is {a: {b: c, d: e}}
65      */
66     public void mergeDataTypeDefaultValuesWithPropertyValue(JsonObject value, String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
67         JsonObject dataTypeDefaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
68         mergeDefaultValuesRec(dataTypeDefaultValues, value);
69     }
70
71     private void mergeDefaultValuesRec(JsonObject defaultValue, JsonObject value) {
72         if (ToscaConverterUtils.isGetInputValue(value) || ToscaConverterUtils.isGetPolicyValue(value)) {
73             return;
74         }
75         for (Map.Entry<String, JsonElement> defVal : defaultValue.entrySet()) {
76             mergeDefaultValue(value, defVal.getKey(), defVal.getValue());
77         }
78     }
79
80     private void mergeDefaultValue(JsonObject value, String propName, JsonElement defValue) {
81         if (defValueWasNotOverridden(value, propName)) {
82             value.add(propName, defValue);
83         } else if (notPrimitivePropValue(value, defValue, propName)) {
84             JsonElement propValue = value.get(propName);
85             mergeDefaultValuesRec(defValue.getAsJsonObject(), propValue.getAsJsonObject());
86         }
87     }
88
89     private boolean notPrimitivePropValue(JsonObject value, JsonElement defValue, String propName) {
90         return value.get(propName).isJsonObject() && defValue.isJsonObject();
91     }
92
93     private boolean defValueWasNotOverridden(JsonObject value, String propName) {
94         return !value.has(propName);
95     }
96
97     private JsonObject getDataTypePropsDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
98         Map<String, PropertyDefinition> allParentsProps = getAllDataTypeProperties(dataTypes.get(propertyDataType));
99         JsonObject dataTypeDefaultsJson = new JsonObject();
100         for (Map.Entry<String, PropertyDefinition> propertyEntry : allParentsProps.entrySet()) {
101             PropertyDefinition propertyDefinition = propertyEntry.getValue();
102             addDefaultValueToJson(dataTypes, dataTypeDefaultsJson, propertyDefinition);
103         }
104         return dataTypeDefaultsJson;
105     }
106
107     private void addDefaultValueToJson(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults,
108                                        PropertyDefinition propertyDefinition) {
109         String propName = propertyDefinition.getName();
110         JsonElement defVal = getDefaultValue(dataTypes, dataTypePropsDefaults, propertyDefinition);
111         if (!JsonUtils.isEmptyJson(defVal)) {
112             dataTypePropsDefaults.add(propName, defVal);
113         }
114     }
115
116     private JsonElement getDefaultValue(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults,
117                                         PropertyDefinition propertyDefinition) {
118         JsonElement defVal = new JsonObject();
119         String propName = propertyDefinition.getName();
120         String propDefaultVal = propertyDefinition.getDefaultValue();
121         if (!JsonUtils.containsEntry(dataTypePropsDefaults, propName) && propDefaultVal != null) {
122             defVal = convertToJson(propDefaultVal);
123         } else if (!JsonUtils.containsEntry(dataTypePropsDefaults, propName)) {
124             defVal = getDataTypePropsDefaultValuesRec(propertyDefinition.getType(), dataTypes);
125         }
126         return defVal;
127     }
128
129     private JsonElement convertToJson(String propDefaultVal) {
130         JsonReader jsonReader = new JsonReader(new StringReader(propDefaultVal));
131         jsonReader.setLenient(true);
132         return jsonParser.parse(jsonReader);
133     }
134
135     private Map<String, PropertyDefinition> getAllDataTypeProperties(DataTypeDefinition dataTypeDefinition) {
136         Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
137         while (dataTypeDefinition != null) {
138             List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
139             if (currentParentsProps != null) {
140                 currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
141             }
142             dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
143         }
144         return allParentsProps;
145     }
146 }