2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 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.onap.sdc.toscaparser.api.elements.constraints;
23 import org.onap.sdc.toscaparser.api.common.JToscaValidationIssue;
24 import org.onap.sdc.toscaparser.api.elements.ScalarUnit;
25 import org.onap.sdc.toscaparser.api.functions.Function;
26 import org.onap.sdc.toscaparser.api.utils.ThreadLocalsHolder;
28 import java.util.ArrayList;
29 import java.util.LinkedHashMap;
30 import java.util.List;
32 public abstract class Constraint {
34 // Parent class for constraints for a Property or Input
36 protected static final String EQUAL = "equal";
37 protected static final String GREATER_THAN = "greater_than";
38 protected static final String GREATER_OR_EQUAL = "greater_or_equal";
39 protected static final String LESS_THAN = "less_than";
40 protected static final String LESS_OR_EQUAL = "less_or_equal";
41 protected static final String IN_RANGE = "in_range";
42 protected static final String VALID_VALUES = "valid_values";
43 protected static final String LENGTH = "length";
44 protected static final String MIN_LENGTH = "min_length";
45 protected static final String MAX_LENGTH = "max_length";
46 protected static final String PATTERN = "pattern";
48 protected static final String[] CONSTRAINTS = {
49 EQUAL, GREATER_THAN, GREATER_OR_EQUAL, LESS_THAN, LESS_OR_EQUAL,
50 IN_RANGE, VALID_VALUES, LENGTH, MIN_LENGTH, MAX_LENGTH, PATTERN};
52 @SuppressWarnings("unchecked")
53 public static Constraint factory(String constraintClass, String propname, String proptype, Object constraint) {
55 // a factory for the different Constraint classes
56 // replaces Python's __new__() usage
58 if (!(constraint instanceof LinkedHashMap)
59 || ((LinkedHashMap<String, Object>) constraint).size() != 1) {
60 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE101",
61 "InvalidSchemaError: Invalid constraint schema " + constraint.toString()));
64 switch (constraintClass) {
66 return new Equal(propname, proptype, constraint);
68 return new GreaterThan(propname, proptype, constraint);
69 case GREATER_OR_EQUAL:
70 return new GreaterOrEqual(propname, proptype, constraint);
72 return new LessThan(propname, proptype, constraint);
74 return new LessOrEqual(propname, proptype, constraint);
76 return new InRange(propname, proptype, constraint);
78 return new ValidValues(propname, proptype, constraint);
80 return new Length(propname, proptype, constraint);
82 return new MinLength(propname, proptype, constraint);
84 return new MaxLength(propname, proptype, constraint);
86 return new Pattern(propname, proptype, constraint);
88 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE102", String.format(
89 "InvalidSchemaError: Invalid property \"%s\"", constraintClass)));
94 private String constraintKey = "TBD";
95 protected ArrayList<String> validTypes = new ArrayList<>();
96 protected ArrayList<String> validPropTypes = new ArrayList<>();
98 protected String propertyName;
99 private String propertyType;
100 protected Object constraintValue;
101 protected Object constraintValueMsg;
102 protected Object valueMsg;
104 @SuppressWarnings("unchecked")
105 public Constraint(String propname, String proptype, Object constraint) {
109 propertyName = propname;
110 propertyType = proptype;
111 constraintValue = ((LinkedHashMap<String, Object>) constraint).get(constraintKey);
112 constraintValueMsg = constraintValue;
113 boolean bFound = false;
114 for (String s : ScalarUnit.SCALAR_UNIT_TYPES) {
115 if (s.equals(propertyType)) {
121 constraintValue = _getScalarUnitConstraintValue();
123 // check if constraint is valid for property type
125 for (String s : validPropTypes) {
126 if (s.equals(propertyType)) {
132 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE103", String.format(
133 "InvalidSchemaError: Property \"%s\" is not valid for data type \"%s\"",
134 constraintKey, propertyType)));
138 public ArrayList<String> getValidTypes() {
142 public void addValidTypes(List<String> validTypes) {
143 this.validTypes.addAll(validTypes);
146 public ArrayList<String> getValidPropTypes() {
147 return validPropTypes;
150 public String getPropertyType() {
154 public Object getConstraintValue() {
155 return constraintValue;
158 public Object getConstraintValueMsg() {
159 return constraintValueMsg;
162 public Object getValueMsg() {
166 public void setConstraintKey(String constraintKey) {
167 this.constraintKey = constraintKey;
170 public void setValidTypes(ArrayList<String> validTypes) {
171 this.validTypes = validTypes;
174 public void setValidPropTypes(ArrayList<String> validPropTypes) {
175 this.validPropTypes = validPropTypes;
178 public void setPropertyType(String propertyType) {
179 this.propertyType = propertyType;
182 public void setConstraintValue(Object constraintValue) {
183 this.constraintValue = constraintValue;
186 public void setConstraintValueMsg(Object constraintValueMsg) {
187 this.constraintValueMsg = constraintValueMsg;
190 public void setValueMsg(Object valueMsg) {
191 this.valueMsg = valueMsg;
194 @SuppressWarnings("unchecked")
195 private Object _getScalarUnitConstraintValue() {
196 // code differs from Python because of class creation
197 if (constraintValue instanceof ArrayList) {
198 ArrayList<Object> ret = new ArrayList<>();
199 for (Object v : (ArrayList<Object>) constraintValue) {
200 ScalarUnit su = ScalarUnit.getScalarunitClass(propertyType, v);
201 ret.add(su.getNumFromScalarUnit(null));
205 ScalarUnit su = ScalarUnit.getScalarunitClass(propertyType, constraintValue);
206 return su.getNumFromScalarUnit(null);
210 public void validate(Object value) {
211 if (Function.isFunction(value)) {
212 //skipping constraints check for functions
217 boolean bFound = false;
218 for (String s : ScalarUnit.SCALAR_UNIT_TYPES) {
219 if (s.equals(propertyType)) {
225 value = ScalarUnit.getScalarunitValue(propertyType, value, null);
227 if (!isValid(value)) {
228 ThreadLocalsHolder.getCollector().appendValidationIssue(new JToscaValidationIssue("JE008", "ValidationError: " + errMsg(value)));
232 protected abstract boolean isValid(Object value);
234 protected abstract void setValues();
236 protected abstract String errMsg(Object value);
242 class Constraint(object):
243 '''Parent class for constraints for a Property or Input.'''
245 CONSTRAINTS = (EQUAL, GREATER_THAN,
246 GREATER_OR_EQUAL, LESS_THAN, LESS_OR_EQUAL, IN_RANGE,
247 VALID_VALUES, LENGTH, MIN_LENGTH, MAX_LENGTH, PATTERN) = \
248 ('equal', 'greater_than', 'greater_or_equal', 'less_than',
249 'less_or_equal', 'in_range', 'valid_values', 'length',
250 'min_length', 'max_length', 'pattern')
252 def __new__(cls, property_name, property_type, constraint):
253 if cls is not Constraint:
254 return super(Constraint, cls).__new__(cls)
256 if(not isinstance(constraint, collections.Mapping) or
257 len(constraint) != 1):
258 ValidationIssueCollector.appendException(
259 InvalidSchemaError(message=_('Invalid constraint schema.')))
261 for type in constraint.keys():
262 ConstraintClass = get_constraint_class(type)
263 if not ConstraintClass:
264 msg = _('Invalid property "%s".') % type
265 ValidationIssueCollector.appendException(
266 InvalidSchemaError(message=msg))
268 return ConstraintClass(property_name, property_type, constraint)
270 def __init__(self, property_name, property_type, constraint):
271 self.property_name = property_name
272 self.property_type = property_type
273 self.constraint_value = constraint[self.constraint_key]
274 self.constraint_value_msg = self.constraint_value
275 if self.property_type in scalarunit.ScalarUnit.SCALAR_UNIT_TYPES:
276 self.constraint_value = self._get_scalarunit_constraint_value()
277 # check if constraint is valid for property type
278 if property_type not in self.valid_prop_types:
279 msg = _('Property "%(ctype)s" is not valid for data type '
280 '"%(dtype)s".') % dict(
281 ctype=self.constraint_key,
283 ValidationIssueCollector.appendException(InvalidSchemaError(message=msg))
285 def _get_scalarunit_constraint_value(self):
286 if self.property_type in scalarunit.ScalarUnit.SCALAR_UNIT_TYPES:
287 ScalarUnit_Class = (scalarunit.
288 get_scalarunit_class(self.property_type))
289 if isinstance(self.constraint_value, list):
290 return [ScalarUnit_Class(v).get_num_from_scalar_unit()
291 for v in self.constraint_value]
293 return (ScalarUnit_Class(self.constraint_value).
294 get_num_from_scalar_unit())
296 def _err_msg(self, value):
297 return _('Property "%s" could not be validated.') % self.property_name
299 def validate(self, value):
300 self.value_msg = value
301 if self.property_type in scalarunit.ScalarUnit.SCALAR_UNIT_TYPES:
302 value = scalarunit.get_scalarunit_value(self.property_type, value)
303 if not self._is_valid(value):
304 err_msg = self._err_msg(value)
305 ValidationIssueCollector.appendException(
306 ValidationError(message=err_msg))