re base code
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / tosca / converters / DataTypePropertyConverter.java
1 package org.openecomp.sdc.be.model.tosca.converters;
2
3 import com.google.gson.Gson;
4 import com.google.gson.JsonElement;
5 import com.google.gson.JsonObject;
6 import com.google.gson.JsonParser;
7 import com.google.gson.stream.JsonReader;
8 import org.openecomp.sdc.be.model.DataTypeDefinition;
9 import org.openecomp.sdc.be.model.PropertyDefinition;
10 import org.openecomp.sdc.common.util.JsonUtils;
11
12 import java.io.StringReader;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 public class DataTypePropertyConverter {
18
19     private static final DataTypePropertyConverter INSTANCE = new DataTypePropertyConverter();
20     private static final JsonParser jsonParser = new JsonParser();
21     private static final Gson gson = new Gson();
22
23     private DataTypePropertyConverter() {
24     }
25
26     public static DataTypePropertyConverter getInstance() {
27         return INSTANCE;
28     }
29
30     /**
31      *
32      * @param propertyDataType the data type
33      * @param dataTypes all data types in the system mapped by their name
34      * @return a json representation of all the given data type properties default values and recursively their data type properties
35      */
36     public String getDataTypePropertiesDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
37         JsonObject defaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
38         return !JsonUtils.isJsonNullOrEmpty(defaultValues) ? gson.toJson(defaultValues) : null;
39     }
40
41     /**
42      * Takes a json representation of a tosca property value and merges all the default values of the property data type
43      * @param value the json representation of a tosca property value
44      * @param propertyDataType data type from which to merge default values
45      * @param dataTypes all data types in the system mapped by their name
46      * for example: for value {a: {b: c}} we could have a default value {a: {d: e}} (property a has two sub properties but only b was overridden)
47      * so the complete value is {a: {b: c, d: e}}
48      */
49     public void mergeDataTypeDefaultValuesWithPropertyValue(JsonObject value, String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
50         JsonObject dataTypeDefaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
51         mergeDefaultValuesRec(dataTypeDefaultValues, value);
52     }
53
54     private void mergeDefaultValuesRec(JsonObject defaultValue, JsonObject value) {
55         if (ToscaConverterUtils.isGetInputValue(value)) {
56             return;
57         }
58         for (Map.Entry<String, JsonElement> defVal : defaultValue.entrySet()) {
59             mergeDefaultValue(value, defVal.getKey(), defVal.getValue());
60         }
61     }
62
63     private void mergeDefaultValue(JsonObject value, String propName, JsonElement defValue) {
64         if (defValueWasNotOverridden(value, propName)) {
65             value.add(propName, defValue);
66         } else if (notPrimitivePropValue(value, defValue, propName)) {
67             JsonElement propValue = value.get(propName);
68             mergeDefaultValuesRec(defValue.getAsJsonObject(), propValue.getAsJsonObject());
69         }
70     }
71
72     private boolean notPrimitivePropValue(JsonObject value, JsonElement defValue, String propName) {
73         return value.get(propName).isJsonObject() && defValue.isJsonObject();
74     }
75
76     private boolean defValueWasNotOverridden(JsonObject value, String propName) {
77         return !value.has(propName);
78     }
79
80     private JsonObject getDataTypePropsDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
81         Map<String, PropertyDefinition> allParentsProps = getAllDataTypeProperties(dataTypes.get(propertyDataType));
82         JsonObject dataTypeDefaultsJson = new JsonObject();
83         for (Map.Entry<String, PropertyDefinition> propertyEntry : allParentsProps.entrySet()) {
84             PropertyDefinition propertyDefinition = propertyEntry.getValue();
85             addDefaultValueToJson(dataTypes, dataTypeDefaultsJson, propertyDefinition);
86         }
87         return dataTypeDefaultsJson;
88     }
89
90     private void addDefaultValueToJson(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults, PropertyDefinition propertyDefinition) {
91         String propName = propertyDefinition.getName();
92         JsonElement defVal = getDefaultValue(dataTypes, dataTypePropsDefaults, propertyDefinition);
93         if (!JsonUtils.isEmptyJson(defVal)) {
94             dataTypePropsDefaults.add(propName, defVal);
95         }
96     }
97
98     private JsonElement getDefaultValue(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults, PropertyDefinition propertyDefinition) {
99         JsonElement defVal = new JsonObject();
100         String propName = propertyDefinition.getName();
101         String propDefaultVal = propertyDefinition.getDefaultValue();
102         if(!JsonUtils.containsEntry(dataTypePropsDefaults, propName) && propDefaultVal != null){
103             defVal = convertToJson(propDefaultVal);
104         } else if (!JsonUtils.containsEntry(dataTypePropsDefaults, propName)) {
105             defVal = getDataTypePropsDefaultValuesRec(propertyDefinition.getType(), dataTypes);
106         }
107         return defVal;
108     }
109
110     private JsonElement convertToJson(String propDefaultVal) {
111         JsonReader jsonReader = new JsonReader(new StringReader(propDefaultVal));
112         jsonReader.setLenient(true);
113         return jsonParser.parse(jsonReader);
114     }
115
116     private Map<String, PropertyDefinition> getAllDataTypeProperties(DataTypeDefinition dataTypeDefinition) {
117         Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
118         while (dataTypeDefinition != null) {
119
120             List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
121             if (currentParentsProps != null) {
122                 currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
123             }
124
125             dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
126         }
127         return allParentsProps;
128     }
129
130 }