61f069a45fcea16df2c4d71212bc596b5eb4b802
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / tosca / constraints / ConstraintUtil.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 package org.openecomp.sdc.be.model.tosca.constraints;
21
22 import com.fasterxml.jackson.core.type.TypeReference;
23 import com.fasterxml.jackson.databind.ObjectMapper;
24 import java.beans.IntrospectionException;
25 import java.beans.Introspector;
26 import java.beans.PropertyDescriptor;
27 import java.io.IOException;
28 import java.lang.reflect.InvocationTargetException;
29 import lombok.AccessLevel;
30 import lombok.AllArgsConstructor;
31 import lombok.NoArgsConstructor;
32 import org.openecomp.sdc.be.model.tosca.ToscaType;
33 import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
36
37 /**
38  * Utility class to validate constraints types.
39  */
40 @NoArgsConstructor(access = AccessLevel.PRIVATE)
41 public final class ConstraintUtil {
42
43     private static final Logger logger = LoggerFactory.getLogger(ConstraintUtil.class);
44
45     /**
46      * Validates that the {@link ToscaType} specified is a {@link ToscaType#STRING}.
47      *
48      * @param propertyType The property tosca type.
49      * @throws ConstraintValueDoNotMatchPropertyTypeException In case the type is not {@link ToscaType#STRING}.
50      */
51     public static void checkStringType(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
52         if (ToscaType.STRING != propertyType) {
53             throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid property type <" + propertyType.toString() + ">");
54         }
55     }
56
57     /**
58      * Verify that the given tosca type is supported for comparison
59      *
60      * @param propertyType the tosca type to check
61      * @throws ConstraintValueDoNotMatchPropertyTypeException if the property type cannot be compared
62      */
63     public static void checkComparableType(final ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException {
64         // The validity of the value is already assured by us with our ToscaType.convert() method
65         // here we just want to check that the constraint is not used on unsupported type as boolean
66         final ToscaType toscaType = ToscaType.getToscaType(propertyType.getType());
67         switch (toscaType) {
68             case FLOAT:
69             case INTEGER:
70             case TIMESTAMP:
71             case VERSION:
72             case STRING:
73             case SCALAR_UNIT_SIZE:
74             case SCALAR_UNIT_TIME:
75             case SCALAR_UNIT_BITRATE:
76             case SCALAR_UNIT_FREQUENCY:
77                 break;
78             case BOOLEAN:
79             case SCALAR_UNIT:
80                 throw new ConstraintValueDoNotMatchPropertyTypeException("Constraint is invalid for property type <" + propertyType.getType() + ">");
81             default:
82                 throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid property type <" + propertyType.getType() + ">");
83         }
84     }
85
86     /**
87      * Convert a string value following its type throw exception if it cannot be converted to a comparable
88      *
89      * @param propertyType the type of the property
90      * @param value        the value to convert
91      * @return the converted comparable
92      * @throws ConstraintValueDoNotMatchPropertyTypeException if the converted value is not a comparable
93      */
94     @SuppressWarnings("rawtypes")
95     public static Comparable convertToComparable(ToscaType propertyType, String value) {
96         final Object comparableObj = propertyType.convert(value);
97         if (!(comparableObj instanceof Comparable)) {
98             throw new IllegalArgumentException("Try to convert a value of a type which is not comparable [" + propertyType + "] to Comparable");
99         } else {
100             return (Comparable) comparableObj;
101         }
102     }
103
104     public static ConstraintInformation getConstraintInformation(Object constraint) throws IntrospectionException {
105         PropertyDescriptor firstDescriptor = null;
106         for (final PropertyDescriptor propertyDescriptor : Introspector.getBeanInfo(constraint.getClass()).getPropertyDescriptors()) {
107             if (propertyDescriptor.getReadMethod() != null && propertyDescriptor.getWriteMethod() != null) {
108                 firstDescriptor = propertyDescriptor;
109                 break;
110             }
111         }
112         if (firstDescriptor == null) {
113             throw new IntrospectionException("Cannot find constraint name");
114         }
115         try {
116             return new ConstraintInformation(firstDescriptor.getName(), firstDescriptor.getReadMethod().invoke(constraint), null, null);
117         } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
118             throw new IntrospectionException("Cannot retrieve constraint reference " + e.getMessage());
119         }
120     }
121
122     public static <T> T parseToCollection(String value, TypeReference<T> typeReference) throws ConstraintValueDoNotMatchPropertyTypeException {
123         T objectMap;
124         ObjectMapper objectMapper = new ObjectMapper();
125         try {
126             objectMap = objectMapper.readValue(value, typeReference);
127         } catch (IOException e) {
128             logger.error(e.getMessage(), e);
129             throw new ConstraintValueDoNotMatchPropertyTypeException("The value [" + value + "] is not valid");
130         }
131         return objectMap;
132     }
133
134     @AllArgsConstructor
135     public static class ConstraintInformation {
136
137         private final String name;
138         private final Object reference;
139         private final String value;
140         private final String type;
141     }
142 }