Support TOSCA functions in operation inputs
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / tosca / converters / ToscaValueBaseConverter.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 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
21 package org.openecomp.sdc.be.model.tosca.converters;
22
23 import com.google.gson.Gson;
24 import com.google.gson.JsonArray;
25 import com.google.gson.JsonElement;
26 import com.google.gson.JsonObject;
27 import com.google.gson.JsonParser;
28 import com.google.gson.JsonPrimitive;
29 import com.google.gson.JsonSyntaxException;
30 import com.google.gson.stream.JsonReader;
31 import java.io.StringReader;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Map.Entry;
37 import org.apache.commons.lang3.math.NumberUtils;
38 import org.openecomp.sdc.be.model.DataTypeDefinition;
39 import org.openecomp.sdc.be.model.PropertyDefinition;
40 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
41 import org.openecomp.sdc.common.log.wrappers.Logger;
42
43 public class ToscaValueBaseConverter {
44
45     private static final Logger log = Logger.getLogger(ToscaValueBaseConverter.class.getName());
46     protected Gson gson = new Gson();
47
48     /**
49      * checks is received Object empty or equals null or not It is relevant only if received Object is instance of String, Map or List class.
50      *
51      * @param convertedValue
52      * @return
53      */
54     public static boolean isEmptyObjectValue(Object convertedValue) {
55         if ((convertedValue == null) || (convertedValue instanceof String && ((String) convertedValue).isEmpty()) || (convertedValue instanceof Map
56             && ((Map) convertedValue).isEmpty()) || (convertedValue instanceof List && ((List) convertedValue).isEmpty())) {
57             return true;
58         }
59         return false;
60     }
61
62     protected Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
63         Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
64         while (dataTypeDefinition != null) {
65             List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
66             if (currentParentsProps != null) {
67                 currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
68             }
69             dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
70         }
71         return allParentsProps;
72     }
73
74     public ToscaPropertyType isScalarType(DataTypeDefinition dataTypeDef) {
75         ToscaPropertyType result = null;
76         DataTypeDefinition dataType = dataTypeDef;
77         while (dataType != null) {
78             String name = dataType.getName();
79             ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
80             if (typeIfScalar != null) {
81                 result = typeIfScalar;
82                 break;
83             }
84             dataType = dataType.getDerivedFrom();
85         }
86         return result;
87     }
88
89     public Object handleComplexJsonValue(final JsonElement jsonElement) {
90         if (jsonElement.isJsonNull()) {
91             return null;
92         }
93         if (jsonElement.isJsonObject()) {
94             return handleJsonObject(jsonElement);
95         }
96         if (jsonElement.isJsonArray()) {
97             return handleJsonArray(jsonElement);
98         }
99         if (jsonElement.isJsonPrimitive()) {
100             if (!isJsonElementAJsonPrimitive(jsonElement)) {
101                 return handleComplexJsonValue(parseToJson(jsonElement.getAsString()));
102             }
103             return json2JavaPrimitive(jsonElement.getAsJsonPrimitive());
104         }
105         log.debug("JSON type '{}' not supported", jsonElement);
106         return null;
107     }
108
109     private Map<String, Object> handleJsonObject(final JsonElement jsonElement) {
110         final JsonObject jsonObject = jsonElement.getAsJsonObject();
111         if (jsonObject.entrySet().isEmpty()) {
112             return null;
113         }
114         final Map<String, Object> jsonObjectAsMap = new HashMap<>();
115         for (final Entry<String, JsonElement> entry : jsonObject.entrySet()) {
116             final Object value = handleComplexJsonValue(entry.getValue());
117             if (value != null) {
118                 jsonObjectAsMap.put(entry.getKey(), value);
119             }
120
121         }
122         return jsonObjectAsMap.isEmpty() ? null : jsonObjectAsMap;
123     }
124
125     private List<Object> handleJsonArray(final JsonElement entry) {
126         final List<Object> jsonAsArray = new ArrayList<>();
127         final JsonArray jsonArray = entry.getAsJsonArray();
128         for (final JsonElement jsonElement : jsonArray) {
129             jsonAsArray.add(handleComplexJsonValue(jsonElement));
130         }
131         return jsonAsArray;
132     }
133
134     public Object json2JavaPrimitive(final JsonPrimitive jsonPrimitive) {
135         if (jsonPrimitive.isBoolean()) {
136             return jsonPrimitive.getAsBoolean();
137         }
138         if (jsonPrimitive.isString() && !NumberUtils.isCreatable(jsonPrimitive.getAsString())) {
139             return jsonPrimitive.getAsString();
140         }
141         if (jsonPrimitive.isNumber() ||
142             (jsonPrimitive.isString() && NumberUtils.isCreatable(jsonPrimitive.getAsString()))) {
143             if (jsonPrimitive.getAsString().contains(".")) {
144                 return jsonPrimitive.getAsDouble();
145             }
146             return jsonPrimitive.getAsInt();
147         }
148         throw new IllegalStateException(String.format("JSON primitive not supported: %s", jsonPrimitive));
149     }
150
151     public JsonElement parseToJson(final String value) {
152         try {
153             final StringReader reader = new StringReader(value);
154             final JsonReader jsonReader = new JsonReader(reader);
155             jsonReader.setLenient(true);
156             return JsonParser.parseReader(jsonReader);
157         } catch (final JsonSyntaxException e) {
158             log.debug("convertToToscaValue failed to parse json value :", e);
159             return null;
160         }
161     }
162
163     public boolean isJsonElementAJsonPrimitive(JsonElement jsonElement) {
164         if (!jsonElement.isJsonPrimitive()) {
165             return false;
166         }
167         String elementAsString = jsonElement.getAsString();
168         JsonElement elementAsJson = parseToJson(elementAsString);
169         if (elementAsJson.isJsonPrimitive() || elementAsJson.isJsonNull()) {
170             return true;
171         }
172         return false;
173     }
174 }