Replace copyTo methods with copy constructors
[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 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.List;
28 import javax.persistence.Column;
29 import javax.persistence.ElementCollection;
30 import javax.persistence.EmbeddedId;
31 import javax.persistence.Entity;
32 import javax.persistence.Inheritance;
33 import javax.persistence.InheritanceType;
34 import javax.persistence.Table;
35 import lombok.Data;
36 import lombok.EqualsAndHashCode;
37 import lombok.NonNull;
38 import org.apache.commons.lang3.ObjectUtils;
39 import org.onap.policy.models.base.PfAuthorative;
40 import org.onap.policy.models.base.PfConcept;
41 import org.onap.policy.models.base.PfConceptKey;
42 import org.onap.policy.models.base.PfKey;
43 import org.onap.policy.models.base.PfReferenceKey;
44 import org.onap.policy.models.base.PfUtils;
45 import org.onap.policy.models.base.PfValidationMessage;
46 import org.onap.policy.models.base.PfValidationResult;
47 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaConstraint;
49 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
50 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty.Status;
51
52 /**
53  * Class to represent the property in TOSCA definition.
54  *
55  * @author Chenfei Gao (cgao@research.att.com)
56  * @author Liam Fallon (liam.fallon@est.tech)
57  */
58 @Entity
59 @Table(name = "ToscaProperty")
60 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
61 @Data
62 @EqualsAndHashCode(callSuper = false)
63 public class JpaToscaProperty extends PfConcept implements PfAuthorative<ToscaProperty> {
64     private static final long serialVersionUID = 1675770231921107988L;
65
66     @EmbeddedId
67     private PfReferenceKey key;
68
69     @Column
70     private PfConceptKey type;
71
72     @Column
73     private String description;
74
75     @Column
76     private boolean required = false;
77
78     @Column(name = "default")
79     private String defaultValue;
80
81     @Column
82     private Status status = Status.SUPPORTED;
83
84     @ElementCollection
85     private List<JpaToscaConstraint> constraints;
86
87     @Column
88     private JpaToscaEntrySchema entrySchema;
89
90     /**
91      * The Default Constructor creates a {@link JpaToscaProperty} object with a null key.
92      */
93     public JpaToscaProperty() {
94         this(new PfReferenceKey());
95     }
96
97     /**
98      * The Key Constructor creates a {@link JpaToscaProperty} object with the given concept key.
99      *
100      * @param key the key
101      */
102     public JpaToscaProperty(@NonNull final PfReferenceKey key) {
103         this(key, new PfConceptKey());
104     }
105
106     /**
107      * The Key Constructor creates a {@link JpaToscaProperty} object with the given concept key.
108      *
109      * @param key the key
110      * @param type the key of the property type
111      */
112     public JpaToscaProperty(@NonNull final PfReferenceKey key, @NonNull final PfConceptKey type) {
113         this.key = key;
114         this.type = type;
115     }
116
117     /**
118      * Copy constructor.
119      *
120      * @param copyConcept the concept to copy from
121      */
122     public JpaToscaProperty(final JpaToscaProperty copyConcept) {
123         super(copyConcept);
124         this.key = new PfReferenceKey(copyConcept.key);
125         this.type = new PfConceptKey(copyConcept.type);
126         this.description = copyConcept.description;
127         this.required = copyConcept.required;
128         this.defaultValue = copyConcept.defaultValue;
129         this.status = copyConcept.status;
130         // Constraints are immutable
131         this.constraints = (copyConcept.constraints != null ? new ArrayList<>(copyConcept.constraints) : null);
132         this.entrySchema = (copyConcept.entrySchema != null ? new JpaToscaEntrySchema(copyConcept.entrySchema) : null);
133     }
134
135     /**
136      * Authorative constructor.
137      *
138      * @param authorativeConcept the authorative concept to copy from
139      */
140     public JpaToscaProperty(final ToscaProperty authorativeConcept) {
141         this.fromAuthorative(authorativeConcept);
142     }
143
144     @Override
145     public ToscaProperty toAuthorative() {
146         ToscaProperty toscaProperty = new ToscaProperty();
147
148         toscaProperty.setName(key.getLocalName());
149
150         toscaProperty.setType(type.getName());
151         toscaProperty.setTypeVersion(type.getVersion());
152
153         toscaProperty.setDescription(description);
154         toscaProperty.setRequired(required);
155         toscaProperty.setDefaultValue(defaultValue);
156         toscaProperty.setStatus(status);
157
158         if (constraints != null) {
159             List<ToscaConstraint> toscaConstraints = new ArrayList<>();
160
161             for (JpaToscaConstraint constraint : constraints) {
162                 toscaConstraints.add(constraint.toAuthorative());
163             }
164
165             toscaProperty.setConstraints(toscaConstraints);
166         }
167
168         if (entrySchema != null) {
169             toscaProperty.setEntrySchema(entrySchema.toAuthorative());
170         }
171
172         return toscaProperty;
173     }
174
175     @Override
176     public void fromAuthorative(ToscaProperty toscaProperty) {
177         this.setKey(new PfReferenceKey());
178         getKey().setLocalName(toscaProperty.getName());
179
180         if (toscaProperty.getTypeVersion() != null) {
181             type = new PfConceptKey(toscaProperty.getType(), toscaProperty.getTypeVersion());
182         } else {
183             type = new PfConceptKey(toscaProperty.getType(), PfKey.NULL_KEY_VERSION);
184         }
185
186         description = toscaProperty.getDescription();
187         required = toscaProperty.isRequired();
188         defaultValue = toscaProperty.getDefaultValue();
189         status = toscaProperty.getStatus();
190
191         if (toscaProperty.getConstraints() != null) {
192             constraints = new ArrayList<>();
193
194             for (ToscaConstraint toscaConstraint : toscaProperty.getConstraints()) {
195                 constraints.add(JpaToscaConstraint.newInstance(toscaConstraint));
196             }
197         }
198
199         if (toscaProperty.getEntrySchema() != null) {
200             entrySchema = new JpaToscaEntrySchema(toscaProperty.getEntrySchema());
201         }
202     }
203
204     @Override
205     public List<PfKey> getKeys() {
206         final List<PfKey> keyList = getKey().getKeys();
207
208         keyList.addAll(type.getKeys());
209
210         if (entrySchema != null) {
211             keyList.addAll(entrySchema.getKeys());
212         }
213
214         return keyList;
215     }
216
217     @Override
218     public void clean() {
219         key.clean();
220
221         type.clean();
222
223         if (description != null) {
224             description = description.trim();
225         }
226
227         if (defaultValue != null) {
228             defaultValue = defaultValue.trim();
229         }
230
231         if (entrySchema != null) {
232             entrySchema.clean();
233         }
234     }
235
236     @Override
237     public PfValidationResult validate(final PfValidationResult resultIn) {
238         PfValidationResult result = resultIn;
239
240         if (key.isNullKey()) {
241             result.addValidationMessage(
242                     new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
243         }
244
245         result = key.validate(result);
246
247         if (type == null || type.isNullKey()) {
248             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
249                     "property type may not be null"));
250         }
251
252         return validateFields(result);
253     }
254
255     /**
256      * Validate the property fields.
257      *
258      * @param resultIn the incoming validation results so far
259      * @return the validation results including this validation
260      */
261     private PfValidationResult validateFields(final PfValidationResult resultIn) {
262         PfValidationResult result = resultIn;
263
264         if (description != null && description.trim().length() == 0) {
265             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
266                     "property description may not be blank"));
267         }
268
269         if (defaultValue != null && defaultValue.trim().length() == 0) {
270             result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
271                     "property default value may not be null"));
272         }
273
274         if (constraints != null) {
275             for (JpaToscaConstraint constraint : constraints) {
276                 if (constraint == null) {
277                     result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
278                             "property constraint may not be null "));
279                 }
280             }
281         }
282         return (entrySchema != null ? entrySchema.validate(result) : result);
283     }
284
285     @Override
286     public int compareTo(final PfConcept otherConcept) {
287         if (otherConcept == null) {
288             return -1;
289         }
290         if (this == otherConcept) {
291             return 0;
292         }
293         if (getClass() != otherConcept.getClass()) {
294             return getClass().getName().compareTo(otherConcept.getClass().getName());
295         }
296
297         final JpaToscaProperty other = (JpaToscaProperty) otherConcept;
298         if (!key.equals(other.key)) {
299             return key.compareTo(other.key);
300         }
301
302         return compareFields(other);
303     }
304
305     /**
306      * Compare the fields of this ToscaProperty object with the fields of the other ToscaProperty object.
307      *
308      * @param other the other ToscaProperty object
309      */
310     private int compareFields(final JpaToscaProperty other) {
311         if (!type.equals(other.type)) {
312             return type.compareTo(other.type);
313         }
314
315         int result = ObjectUtils.compare(description, other.description);
316         if (result != 0) {
317             return result;
318         }
319
320         result = ObjectUtils.compare(required, other.required);
321         if (result != 0) {
322             return result;
323         }
324
325         result = ObjectUtils.compare(defaultValue, other.defaultValue);
326         if (result != 0) {
327             return result;
328         }
329
330         result = ObjectUtils.compare(status, other.status);
331         if (result != 0) {
332             return result;
333         }
334
335         result = PfUtils.compareObjects(constraints, other.constraints);
336         if (result != 0) {
337             return result;
338         }
339
340         return entrySchema.compareTo(other.entrySchema);
341     }
342 }