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