a2127f37c715fc100974a0dfc9dfaf82763e3a76
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaProperty.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Model
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019-2020 Nordix Foundation.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  * SPDX-License-Identifier: Apache-2.0
21  * ============LICENSE_END=========================================================
22  */
23
24 package org.onap.policy.models.tosca.simple.concepts;
25
26 import java.util.ArrayList;
27 import java.util.LinkedHashMap;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Map.Entry;
31
32 import javax.persistence.Column;
33 import javax.persistence.ElementCollection;
34 import javax.persistence.EmbeddedId;
35 import javax.persistence.Entity;
36 import javax.persistence.Inheritance;
37 import javax.persistence.InheritanceType;
38 import javax.persistence.Table;
39
40 import lombok.Data;
41 import lombok.EqualsAndHashCode;
42 import lombok.NonNull;
43
44 import org.apache.commons.lang3.ObjectUtils;
45 import org.onap.policy.models.base.PfAuthorative;
46 import org.onap.policy.models.base.PfConcept;
47 import org.onap.policy.models.base.PfConceptKey;
48 import org.onap.policy.models.base.PfKey;
49 import org.onap.policy.models.base.PfReferenceKey;
50 import org.onap.policy.models.base.PfUtils;
51 import org.onap.policy.models.base.PfValidationMessage;
52 import org.onap.policy.models.base.PfValidationResult;
53 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
54 import org.onap.policy.models.tosca.authorative.concepts.ToscaConstraint;
55 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
56 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty.Status;
57
58 /**
59  * Class to represent the property in TOSCA definition.
60  *
61  * @author Chenfei Gao (cgao@research.att.com)
62  * @author Liam Fallon (liam.fallon@est.tech)
63  */
64 @Entity
65 @Table(name = "ToscaProperty")
66 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
67 @Data
68 @EqualsAndHashCode(callSuper = false)
69 public class JpaToscaProperty extends PfConcept implements PfAuthorative<ToscaProperty> {
70     private static final long serialVersionUID = 1675770231921107988L;
71
72     @EmbeddedId
73     private PfReferenceKey key;
74
75     @Column
76     private PfConceptKey type;
77
78     @Column
79     private String description;
80
81     @Column
82     private boolean required = false;
83
84     @Column(name = "default")
85     private String defaultValue;
86
87     @Column
88     private Status status = Status.SUPPORTED;
89
90     @ElementCollection
91     private List<JpaToscaConstraint> constraints = new ArrayList<>();
92
93     @Column
94     private JpaToscaEntrySchema entrySchema;
95
96     @ElementCollection
97     private Map<String, String> metadata = new LinkedHashMap<>();
98
99     /**
100      * The Default Constructor creates a {@link JpaToscaProperty} object with a null key.
101      */
102     public JpaToscaProperty() {
103         this(new PfReferenceKey());
104     }
105
106     /**
107      * The Key Constructor creates a {@link JpaToscaProperty} object with the given concept key.
108      *
109      * @param key the key
110      */
111     public JpaToscaProperty(@NonNull final PfReferenceKey key) {
112         this(key, new PfConceptKey());
113     }
114
115     /**
116      * The Key Constructor creates a {@link JpaToscaProperty} object with the given concept key.
117      *
118      * @param key the key
119      * @param type the key of the property type
120      */
121     public JpaToscaProperty(@NonNull final PfReferenceKey key, @NonNull final PfConceptKey type) {
122         this.key = key;
123         this.type = type;
124     }
125
126     /**
127      * Copy constructor.
128      *
129      * @param copyConcept the concept to copy from
130      */
131     public JpaToscaProperty(final JpaToscaProperty copyConcept) {
132         super(copyConcept);
133         this.key = new PfReferenceKey(copyConcept.key);
134         this.type = new PfConceptKey(copyConcept.type);
135         this.description = copyConcept.description;
136         this.required = copyConcept.required;
137         this.defaultValue = copyConcept.defaultValue;
138         this.status = copyConcept.status;
139         // Constraints are immutable
140         this.constraints = (copyConcept.constraints != null ? new ArrayList<>(copyConcept.constraints) : null);
141         this.entrySchema = (copyConcept.entrySchema != null ? new JpaToscaEntrySchema(copyConcept.entrySchema) : null);
142         this.metadata = (copyConcept.metadata != null ? new LinkedHashMap<>(copyConcept.metadata) : null);
143     }
144
145     /**
146      * Authorative constructor.
147      *
148      * @param authorativeConcept the authorative concept to copy from
149      */
150     public JpaToscaProperty(final ToscaProperty authorativeConcept) {
151         this.fromAuthorative(authorativeConcept);
152     }
153
154     @Override
155     public ToscaProperty toAuthorative() {
156         ToscaProperty toscaProperty = new ToscaProperty();
157
158         toscaProperty.setName(key.getLocalName());
159
160         toscaProperty.setType(type.getName());
161         toscaProperty.setTypeVersion(type.getVersion());
162
163         toscaProperty.setDescription(description);
164         toscaProperty.setRequired(required);
165         toscaProperty.setDefaultValue(defaultValue);
166         toscaProperty.setStatus(status);
167
168         if (constraints != null) {
169             List<ToscaConstraint> toscaConstraints = new ArrayList<>();
170
171             for (JpaToscaConstraint constraint : constraints) {
172                 toscaConstraints.add(constraint.toAuthorative());
173             }
174
175             toscaProperty.setConstraints(toscaConstraints);
176         }
177
178         if (entrySchema != null) {
179             toscaProperty.setEntrySchema(entrySchema.toAuthorative());
180         }
181
182         if (metadata != null) {
183             toscaProperty.setMetadata(new LinkedHashMap<>(metadata));
184         }
185
186         return toscaProperty;
187     }
188
189     @Override
190     public void fromAuthorative(ToscaProperty toscaProperty) {
191         this.setKey(new PfReferenceKey());
192         getKey().setLocalName(toscaProperty.getName());
193
194         if (toscaProperty.getTypeVersion() != null) {
195             type = new PfConceptKey(toscaProperty.getType(), toscaProperty.getTypeVersion());
196         } else {
197             type = new PfConceptKey(toscaProperty.getType(), PfKey.NULL_KEY_VERSION);
198         }
199
200         description = toscaProperty.getDescription();
201         required = toscaProperty.isRequired();
202         defaultValue = toscaProperty.getDefaultValue();
203         status = toscaProperty.getStatus();
204
205         if (toscaProperty.getConstraints() != null) {
206             constraints = new ArrayList<>();
207
208             for (ToscaConstraint toscaConstraint : toscaProperty.getConstraints()) {
209                 constraints.add(JpaToscaConstraint.newInstance(toscaConstraint));
210             }
211         }
212
213         if (toscaProperty.getEntrySchema() != null) {
214             entrySchema = new JpaToscaEntrySchema(toscaProperty.getEntrySchema());
215         }
216
217         // Add the property metadata if it doesn't exist already
218         if (toscaProperty.getMetadata() != null) {
219             metadata = new LinkedHashMap<>(toscaProperty.getMetadata());
220         }
221
222     }
223
224     @Override
225     public List<PfKey> getKeys() {
226         final List<PfKey> keyList = getKey().getKeys();
227
228         keyList.addAll(type.getKeys());
229
230         if (entrySchema != null) {
231             keyList.addAll(entrySchema.getKeys());
232         }
233
234         return keyList;
235     }
236
237     @Override
238     public void clean() {
239         key.clean();
240
241         type.clean();
242
243         if (description != null) {
244             description = description.trim();
245         }
246
247         if (defaultValue != null) {
248             defaultValue = defaultValue.trim();
249         }
250
251         if (entrySchema != null) {
252             entrySchema.clean();
253         }
254
255         if (metadata != null) {
256             for (Entry<String, String> metadataEntry : metadata.entrySet()) {
257                 metadataEntry.setValue(metadataEntry.getValue().trim());
258             }
259         }
260     }
261
262     @Override
263     public PfValidationResult validate(final PfValidationResult resultIn) {
264         PfValidationResult result = resultIn;
265
266         if (key.isNullKey()) {
267             result.addValidationMessage(
268                     new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
269         }
270
271         result = key.validate(result);
272
273         if (type == null || type.isNullKey()) {
274             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
275                     "property type may not be null"));
276         }
277
278         return validateFields(result);
279     }
280
281     /**
282      * Validate the property fields.
283      *
284      * @param resultIn the incoming validation results so far
285      * @return the validation results including this validation
286      */
287     private PfValidationResult validateFields(final PfValidationResult resultIn) {
288         PfValidationResult result = resultIn;
289
290         if (description != null && description.trim().length() == 0) {
291             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
292                     "property description may not be blank"));
293         }
294
295         if (defaultValue != null && defaultValue.trim().length() == 0) {
296             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
297                     "property default value may not be null"));
298         }
299
300         if (constraints != null) {
301             for (JpaToscaConstraint constraint : constraints) {
302                 if (constraint == null) {
303                     result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
304                             "property constraint may not be null "));
305                 }
306             }
307         }
308         return (entrySchema != null ? entrySchema.validate(result) : result);
309     }
310
311     @Override
312     public int compareTo(final PfConcept otherConcept) {
313         if (otherConcept == null) {
314             return -1;
315         }
316         if (this == otherConcept) {
317             return 0;
318         }
319         if (getClass() != otherConcept.getClass()) {
320             return getClass().getName().compareTo(otherConcept.getClass().getName());
321         }
322
323         final JpaToscaProperty other = (JpaToscaProperty) otherConcept;
324         if (!key.equals(other.key)) {
325             return key.compareTo(other.key);
326         }
327
328         return compareFields(other);
329     }
330
331     /**
332      * Compare the fields of this ToscaProperty object with the fields of the other ToscaProperty object.
333      *
334      * @param other the other ToscaProperty object
335      */
336     private int compareFields(final JpaToscaProperty other) {
337         if (!type.equals(other.type)) {
338             return type.compareTo(other.type);
339         }
340
341         int result = ObjectUtils.compare(description, other.description);
342         if (result != 0) {
343             return result;
344         }
345
346         result = ObjectUtils.compare(required, other.required);
347         if (result != 0) {
348             return result;
349         }
350
351         result = ObjectUtils.compare(defaultValue, other.defaultValue);
352         if (result != 0) {
353             return result;
354         }
355
356         result = ObjectUtils.compare(status, other.status);
357         if (result != 0) {
358             return result;
359         }
360
361         result = PfUtils.compareObjects(constraints, other.constraints);
362         if (result != 0) {
363             return result;
364         }
365
366         return entrySchema.compareTo(other.entrySchema);
367     }
368 }