2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.model.tosca.validators;
22 import com.google.gson.JsonElement;
23 import com.google.gson.JsonObject;
24 import com.google.gson.JsonParser;
25 import com.google.gson.JsonPrimitive;
26 import com.google.gson.JsonSyntaxException;
27 import java.util.HashMap;
28 import java.util.List;
30 import java.util.Map.Entry;
32 import org.apache.commons.lang3.tuple.ImmutablePair;
33 import org.openecomp.sdc.be.model.DataTypeDefinition;
34 import org.openecomp.sdc.be.model.PropertyDefinition;
35 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
36 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
37 import org.openecomp.sdc.common.log.wrappers.Logger;
39 public class DataTypeValidatorConverter {
41 private static final Logger log = Logger.getLogger(DataTypeValidatorConverter.class.getName());
42 private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter();
43 JsonParser jsonParser = new JsonParser();
44 ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<>(null, false);
45 ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<>(null, true);
46 ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<>(null, true);
47 ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<>(null, true);
49 private DataTypeValidatorConverter() {
52 public static DataTypeValidatorConverter getInstance() {
53 return dataTypeValidatorConverter;
56 private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) {
57 ToscaPropertyType result = null;
58 DataTypeDefinition dataType = dataTypeDef;
59 while (dataType != null) {
60 String name = dataType.getName();
61 ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
62 if (typeIfScalar != null) {
63 result = typeIfScalar;
66 dataType = dataType.getDerivedFrom();
71 private ImmutablePair<JsonElement, Boolean> validateAndUpdate(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition,
72 Map<String, DataTypeDefinition> allDataTypes) {
73 Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
74 ToscaPropertyType toscaPropertyType = null;
75 if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
76 PropertyTypeValidator validator = toscaPropertyType.getValidator();
77 PropertyValueConverter converter = toscaPropertyType.getConverter();
78 if (jsonElement == null || jsonElement.isJsonNull()) {
79 boolean valid = validator.isValid(null, null, allDataTypes);
81 log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
84 return new ImmutablePair<>(jsonElement, true);
86 if (jsonElement.isJsonPrimitive()) {
88 if (jsonElement != null) {
89 if (jsonElement.toString().isEmpty()) {
92 value = jsonElement.toString();
95 boolean valid = validator.isValid(value, null, null);
97 log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(),
98 dataTypeDefinition.getName(), value);
101 String convertedValue = converter.convert(value, null, allDataTypes);
102 JsonElement element = null;
104 element = jsonParser.parse(convertedValue);
105 } catch (JsonSyntaxException e) {
106 log.debug("Failed to parse value {} of property {} {}", convertedValue, dataTypeDefinition.getName(), e);
109 return new ImmutablePair<>(element, true);
111 // MAP, LIST, OTHER types cannot be applied data type
113 // definition scalar type. We currently cannot derived from
115 // map/list. (cannot add the entry schema to it)
116 log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one",
117 dataTypeDefinition.getName());
122 if (jsonElement == null || jsonElement.isJsonNull()) {
123 return new ImmutablePair<>(jsonElement, true);
125 if (jsonElement.isJsonObject()) {
126 JsonObject buildJsonObject = new JsonObject();
127 JsonObject asJsonObject = jsonElement.getAsJsonObject();
128 Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
129 for (Entry<String, JsonElement> entry : entrySet) {
130 String propName = entry.getKey();
131 JsonElement elementValue = entry.getValue();
132 PropertyDefinition propertyDefinition = allProperties.get(propName);
133 if (propertyDefinition == null) {
134 log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName());
137 String type = propertyDefinition.getType();
138 boolean isScalarType = ToscaPropertyType.isScalarType(type);
140 ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
141 if (propertyType == null) {
142 log.debug("cannot find the {} under default tosca property types", type);
145 PropertyTypeValidator validator = propertyType.getValidator();
146 String innerType = null;
147 if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
148 if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
149 innerType = propertyDefinition.getSchema().getProperty().getType();
150 if (innerType == null) {
151 log.debug("Property type {} must have inner type in its declaration.", propertyType);
157 if (elementValue != null) {
158 if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
161 value = elementValue.toString();
164 boolean isValid = validator.isValid(value, innerType, allDataTypes);
166 log.debug("Failed to validate the value {} from type {}", value, propertyType);
169 PropertyValueConverter converter = propertyType.getConverter();
170 String convertedValue = converter.convert(value, innerType, allDataTypes);
171 JsonElement element = null;
172 if (convertedValue != null) {
173 if (convertedValue.isEmpty()) {
174 element = new JsonPrimitive("");
177 element = jsonParser.parse(convertedValue);
178 } catch (JsonSyntaxException e) {
179 log.debug("Failed to parse value {} of type {}", convertedValue, propertyType, e);
184 buildJsonObject.add(propName, element);
186 DataTypeDefinition typeDefinition = allDataTypes.get(type);
187 if (typeDefinition == null) {
188 log.debug("The data type {} cannot be found in the given data type list.", type);
191 ImmutablePair<JsonElement, Boolean> isValid = validateAndUpdate(elementValue, typeDefinition, allDataTypes);
192 if (!isValid.getRight().booleanValue()) {
193 log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null),
194 typeDefinition.getName());
197 buildJsonObject.add(propName, isValid.getLeft());
200 return new ImmutablePair<>(buildJsonObject, true);
202 log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null),
203 dataTypeDefinition.getName());
210 public ImmutablePair<JsonElement, Boolean> validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition,
211 Map<String, DataTypeDefinition> allDataTypes) {
212 if (value == null || value.isEmpty()) {
213 return trueEmptyResult;
215 JsonElement jsonElement = null;
217 jsonElement = jsonParser.parse(value);
218 } catch (JsonSyntaxException e) {
221 return validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes);
224 private Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
225 Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
226 while (dataTypeDefinition != null) {
227 List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
228 if (currentParentsProps != null) {
229 currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
231 dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
233 return allParentsProps;
236 public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
237 if (value == null || value.isEmpty()) {
240 JsonElement jsonElement = null;
242 jsonElement = jsonParser.parse(value);
243 } catch (JsonSyntaxException e) {
244 log.debug("Failed to parse the value {} from type {}", value, dataTypeDefinition, e);
247 return isValid(jsonElement, dataTypeDefinition, allDataTypes);
250 private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
251 Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
252 ToscaPropertyType toscaPropertyType = null;
253 if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
254 PropertyTypeValidator validator = toscaPropertyType.getValidator();
255 if (jsonElement == null || jsonElement.isJsonNull()) {
256 boolean valid = validator.isValid(null, null, allDataTypes);
258 log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
263 if (jsonElement.isJsonPrimitive()) {
265 if (jsonElement != null) {
266 if (jsonElement.toString().isEmpty()) {
269 value = jsonElement.toString();
272 boolean valid = validator.isValid(value, null, allDataTypes);
274 log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(),
275 dataTypeDefinition.getName(), value);
280 // MAP, LIST, OTHER types cannot be applied data type
282 // definition scalar type. We currently cannot derived from
284 // map/list. (cannot add the entry schema to it)
285 log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one",
286 dataTypeDefinition.getName());
291 if (jsonElement == null || jsonElement.isJsonNull()) {
294 if (jsonElement.isJsonObject()) {
295 JsonObject asJsonObject = jsonElement.getAsJsonObject();
296 Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
297 for (Entry<String, JsonElement> entry : entrySet) {
298 String propName = entry.getKey();
299 JsonElement elementValue = entry.getValue();
300 PropertyDefinition propertyDefinition = allProperties.get(propName);
301 if (propertyDefinition == null) {
302 log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName());
305 String type = propertyDefinition.getType();
306 boolean isScalarType = ToscaPropertyType.isScalarType(type);
308 ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
309 if (propertyType == null) {
310 log.debug("cannot find the {} under default tosca property types", type);
313 PropertyTypeValidator validator = propertyType.getValidator();
314 String innerType = null;
315 if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
316 if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
317 innerType = propertyDefinition.getSchema().getProperty().getType();
318 if (innerType == null) {
319 log.debug("Property type {} must have inner type in its declaration.", propertyType);
325 if (elementValue != null) {
326 if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
329 value = elementValue.toString();
332 boolean isValid = validator.isValid(value, innerType, allDataTypes);
334 log.debug("Failed to validate the value {} from type {}", value, propertyType);
338 DataTypeDefinition typeDefinition = allDataTypes.get(type);
339 if (typeDefinition == null) {
340 log.debug("The data type {} cannot be found in the given data type list.", type);
343 boolean isValid = isValid(elementValue, typeDefinition, allDataTypes);
345 log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null),
346 typeDefinition.getName());
353 log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null),
354 dataTypeDefinition.getName());