summaryrefslogtreecommitdiffstats
path: root/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DataTypePropertyConverter.java
blob: f3b842e0cf07c31aab6bdb1720c15f51b31e9cb7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package org.openecomp.sdc.be.model.tosca.converters;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import org.openecomp.sdc.be.model.DataTypeDefinition;
import org.openecomp.sdc.be.model.PropertyDefinition;
import org.openecomp.sdc.common.util.JsonUtils;

import java.io.StringReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataTypePropertyConverter {

    private static final DataTypePropertyConverter INSTANCE = new DataTypePropertyConverter();
    private static final JsonParser jsonParser = new JsonParser();
    private static final Gson gson = new Gson();

    private DataTypePropertyConverter() {
    }

    public static DataTypePropertyConverter getInstance() {
        return INSTANCE;
    }

    /**
     *
     * @param propertyDataType the data type
     * @param dataTypes all data types in the system mapped by their name
     * @return a json representation of all the given data type properties default values and recursively their data type properties
     */
    public String getDataTypePropertiesDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
        JsonObject defaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
        return !JsonUtils.isJsonNullOrEmpty(defaultValues) ? gson.toJson(defaultValues) : null;
    }

    /**
     * Takes a json representation of a tosca property value and merges all the default values of the property data type
     * @param value the json representation of a tosca property value
     * @param propertyDataType data type from which to merge default values
     * @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: {d: e}} (property a has two sub properties but only b was overridden)
     * so the complete value is {a: {b: c, d: e}}
     */
    public void mergeDataTypeDefaultValuesWithPropertyValue(JsonObject value, String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
        JsonObject dataTypeDefaultValues = getDataTypePropsDefaultValuesRec(propertyDataType, dataTypes);
        mergeDefaultValuesRec(dataTypeDefaultValues, value);
    }

    private void mergeDefaultValuesRec(JsonObject defaultValue, JsonObject value) {
        if (ToscaConverterUtils.isGetInputValue(value)) {
            return;
        }
        for (Map.Entry<String, JsonElement> defVal : defaultValue.entrySet()) {
            mergeDefaultValue(value, defVal.getKey(), defVal.getValue());
        }
    }

    private void mergeDefaultValue(JsonObject value, String propName, JsonElement defValue) {
        if (defValueWasNotOverridden(value, propName)) {
            value.add(propName, defValue);
        } else if (notPrimitivePropValue(value, defValue, propName)) {
            JsonElement propValue = value.get(propName);
            mergeDefaultValuesRec(defValue.getAsJsonObject(), propValue.getAsJsonObject());
        }
    }

    private boolean notPrimitivePropValue(JsonObject value, JsonElement defValue, String propName) {
        return value.get(propName).isJsonObject() && defValue.isJsonObject();
    }

    private boolean defValueWasNotOverridden(JsonObject value, String propName) {
        return !value.has(propName);
    }

    private JsonObject getDataTypePropsDefaultValuesRec(String propertyDataType, Map<String, DataTypeDefinition> dataTypes) {
        Map<String, PropertyDefinition> allParentsProps = getAllDataTypeProperties(dataTypes.get(propertyDataType));
        JsonObject dataTypeDefaultsJson = new JsonObject();
        for (Map.Entry<String, PropertyDefinition> propertyEntry : allParentsProps.entrySet()) {
            PropertyDefinition propertyDefinition = propertyEntry.getValue();
            addDefaultValueToJson(dataTypes, dataTypeDefaultsJson, propertyDefinition);
        }
        return dataTypeDefaultsJson;
    }

    private void addDefaultValueToJson(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults, PropertyDefinition propertyDefinition) {
        String propName = propertyDefinition.getName();
        JsonElement defVal = getDefaultValue(dataTypes, dataTypePropsDefaults, propertyDefinition);
        if (!JsonUtils.isEmptyJson(defVal)) {
            dataTypePropsDefaults.add(propName, defVal);
        }
    }

    private JsonElement getDefaultValue(Map<String, DataTypeDefinition> dataTypes, JsonObject dataTypePropsDefaults, PropertyDefinition propertyDefinition) {
        JsonElement defVal = new JsonObject();
        String propName = propertyDefinition.getName();
        String propDefaultVal = propertyDefinition.getDefaultValue();
        if(!JsonUtils.containsEntry(dataTypePropsDefaults, propName) && propDefaultVal != null){
            defVal = convertToJson(propDefaultVal);
        } else if (!JsonUtils.containsEntry(dataTypePropsDefaults, propName)) {
            defVal = getDataTypePropsDefaultValuesRec(propertyDefinition.getType(), dataTypes);
        }
        return defVal;
    }

    private JsonElement convertToJson(String propDefaultVal) {
        JsonReader jsonReader = new JsonReader(new StringReader(propDefaultVal));
        jsonReader.setLenient(true);
        return jsonParser.parse(jsonReader);
    }

    private Map<String, PropertyDefinition> getAllDataTypeProperties(DataTypeDefinition dataTypeDefinition) {
        Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
        while (dataTypeDefinition != null) {

            List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
            if (currentParentsProps != null) {
                currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
            }

            dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
        }
        return allParentsProps;
    }

}