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=========================================================
21 package org.openecomp.sdc.be.model.tosca.validators;
23 import com.google.gson.*;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.openecomp.sdc.be.model.DataTypeDefinition;
26 import org.openecomp.sdc.be.model.PropertyDefinition;
27 import org.openecomp.sdc.be.model.tosca.ToscaPropertyType;
28 import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter;
29 import org.openecomp.sdc.common.log.wrappers.Logger;
31 import java.util.HashMap;
32 import java.util.List;
34 import java.util.Map.Entry;
37 public class DataTypeValidatorConverter {
39 private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter();
41 public static DataTypeValidatorConverter getInstance() {
42 return dataTypeValidatorConverter;
45 private DataTypeValidatorConverter() {
49 private static final Logger log = Logger.getLogger(DataTypeValidatorConverter.class.getName());
51 JsonParser jsonParser = new JsonParser();
53 ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<>(null, false);
54 ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<>(null, true);
56 ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<>(null, true);
57 ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<>(null, true);
59 private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) {
61 ToscaPropertyType result = null;
63 DataTypeDefinition dataType = dataTypeDef;
65 while (dataType != null) {
67 String name = dataType.getName();
68 ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name);
69 if (typeIfScalar != null) {
70 result = typeIfScalar;
74 dataType = dataType.getDerivedFrom();
80 private ImmutablePair<JsonElement, Boolean> validateAndUpdate(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
82 Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
84 ToscaPropertyType toscaPropertyType = null;
85 if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
87 PropertyTypeValidator validator = toscaPropertyType.getValidator();
88 PropertyValueConverter converter = toscaPropertyType.getConverter();
89 if (jsonElement == null || jsonElement.isJsonNull()) {
90 boolean valid = validator.isValid(null, null, allDataTypes);
92 log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
95 return new ImmutablePair<>(jsonElement, true);
98 if (jsonElement.isJsonPrimitive()) {
100 if (jsonElement != null) {
101 if (jsonElement.toString().isEmpty()) {
104 value = jsonElement.toString();
107 boolean valid = validator.isValid(value, null, null);
109 log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
113 String convertedValue = converter.convert(value, null, allDataTypes);
114 JsonElement element = null;
116 element = jsonParser.parse(convertedValue);
117 } catch (JsonSyntaxException e) {
118 log.debug("Failed to parse value {} of property {} {}", convertedValue, dataTypeDefinition.getName(), e);
122 return new ImmutablePair<>(element, true);
125 // MAP, LIST, OTHER types cannot be applied data type
126 // definition scalar type. We currently cannot derived from
127 // map/list. (cannot add the entry schema to it)
128 log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
135 if (jsonElement == null || jsonElement.isJsonNull()) {
137 return new ImmutablePair<>(jsonElement, true);
141 if (jsonElement.isJsonObject()) {
143 JsonObject buildJsonObject = new JsonObject();
145 JsonObject asJsonObject = jsonElement.getAsJsonObject();
146 Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
148 for (Entry<String, JsonElement> entry : entrySet) {
149 String propName = entry.getKey();
151 JsonElement elementValue = entry.getValue();
153 PropertyDefinition propertyDefinition = allProperties.get(propName);
154 if (propertyDefinition == null) {
155 log.debug("The property {} was not found under data type {}" ,propName, dataTypeDefinition.getName());
158 String type = propertyDefinition.getType();
159 boolean isScalarType = ToscaPropertyType.isScalarType(type);
162 ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
163 if (propertyType == null) {
164 log.debug("cannot find the {} under default tosca property types", type);
167 PropertyTypeValidator validator = propertyType.getValidator();
168 String innerType = null;
169 if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
170 if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
171 innerType = propertyDefinition.getSchema().getProperty().getType();
172 if (innerType == null) {
173 log.debug("Property type {} must have inner type in its declaration.", propertyType);
180 if (elementValue != null) {
181 if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
184 value = elementValue.toString();
188 boolean isValid = validator.isValid(value, innerType, allDataTypes);
190 log.debug("Failed to validate the value {} from type {}", value, propertyType);
194 PropertyValueConverter converter = propertyType.getConverter();
195 String convertedValue = converter.convert(value, innerType, allDataTypes);
197 JsonElement element = null;
198 if (convertedValue != null) {
199 if (convertedValue.isEmpty()) {
200 element = new JsonPrimitive("");
203 element = jsonParser.parse(convertedValue);
204 } catch (JsonSyntaxException e) {
205 log.debug("Failed to parse value {} of type {}", convertedValue, propertyType, e);
210 buildJsonObject.add(propName, element);
214 DataTypeDefinition typeDefinition = allDataTypes.get(type);
215 if (typeDefinition == null) {
216 log.debug("The data type {} cannot be found in the given data type list.", type);
220 ImmutablePair<JsonElement, Boolean> isValid = validateAndUpdate(elementValue, typeDefinition, allDataTypes);
222 if (!isValid.getRight().booleanValue()) {
223 log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
227 buildJsonObject.add(propName, isValid.getLeft());
232 return new ImmutablePair<>(buildJsonObject, true);
234 log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());
243 public ImmutablePair<JsonElement, Boolean> validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
244 if (value == null || value.isEmpty()) {
245 return trueEmptyResult;
248 JsonElement jsonElement = null;
250 jsonElement = jsonParser.parse(value);
251 } catch (JsonSyntaxException e) {
255 return validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes);
258 private Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) {
260 Map<String, PropertyDefinition> allParentsProps = new HashMap<>();
262 while (dataTypeDefinition != null) {
264 List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties();
265 if (currentParentsProps != null) {
266 currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p));
269 dataTypeDefinition = dataTypeDefinition.getDerivedFrom();
272 return allParentsProps;
275 public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
276 if (value == null || value.isEmpty()) {
280 JsonElement jsonElement = null;
282 jsonElement = jsonParser.parse(value);
283 } catch (JsonSyntaxException e) {
284 log.debug("Failed to parse the value {} from type {}", value, dataTypeDefinition, e);
288 return isValid(jsonElement, dataTypeDefinition, allDataTypes);
291 private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) {
293 Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition);
295 ToscaPropertyType toscaPropertyType = null;
296 if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) {
298 PropertyTypeValidator validator = toscaPropertyType.getValidator();
299 if (jsonElement == null || jsonElement.isJsonNull()) {
300 boolean valid = validator.isValid(null, null, allDataTypes);
302 log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName());
309 if (jsonElement.isJsonPrimitive()) {
311 if (jsonElement != null) {
312 if (jsonElement.toString().isEmpty()) {
315 value = jsonElement.toString();
318 boolean valid = validator.isValid(value, null, allDataTypes);
320 log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value);
327 // MAP, LIST, OTHER types cannot be applied data type
328 // definition scalar type. We currently cannot derived from
329 // map/list. (cannot add the entry schema to it)
330 log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName());
337 if (jsonElement == null || jsonElement.isJsonNull()) {
343 if (jsonElement.isJsonObject()) {
345 JsonObject asJsonObject = jsonElement.getAsJsonObject();
346 Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
348 for (Entry<String, JsonElement> entry : entrySet) {
349 String propName = entry.getKey();
351 JsonElement elementValue = entry.getValue();
353 PropertyDefinition propertyDefinition = allProperties.get(propName);
354 if (propertyDefinition == null) {
355 log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName());
358 String type = propertyDefinition.getType();
359 boolean isScalarType = ToscaPropertyType.isScalarType(type);
362 ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type);
363 if (propertyType == null) {
364 log.debug("cannot find the {} under default tosca property types", type);
367 PropertyTypeValidator validator = propertyType.getValidator();
368 String innerType = null;
369 if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) {
370 if (propertyDefinition.getSchema() != null && propertyDefinition.getSchema().getProperty() != null) {
371 innerType = propertyDefinition.getSchema().getProperty().getType();
372 if (innerType == null) {
373 log.debug("Property type {} must have inner type in its declaration.", propertyType);
380 if (elementValue != null) {
381 if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) {
384 value = elementValue.toString();
388 boolean isValid = validator.isValid(value, innerType, allDataTypes);
390 log.debug("Failed to validate the value {} from type {}", value, propertyType);
396 DataTypeDefinition typeDefinition = allDataTypes.get(type);
397 if (typeDefinition == null) {
398 log.debug("The data type {} cannot be found in the given data type list.", type);
402 boolean isValid = isValid(elementValue, typeDefinition, allDataTypes);
405 log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName());
415 log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName());