JPA concepts for TOSCA
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaRequirement.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Requirement Model
4  * ================================================================================
5  * Copyright (C) 2019-2020 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 javax.persistence.Column;
31 import javax.persistence.ElementCollection;
32 import javax.persistence.Entity;
33 import javax.persistence.Inheritance;
34 import javax.persistence.InheritanceType;
35 import javax.persistence.Lob;
36 import javax.persistence.Table;
37 import lombok.Data;
38 import lombok.EqualsAndHashCode;
39 import lombok.NonNull;
40 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
41 import org.onap.policy.models.base.PfAuthorative;
42 import org.onap.policy.models.base.PfConcept;
43 import org.onap.policy.models.base.PfConceptKey;
44 import org.onap.policy.models.base.PfKey;
45 import org.onap.policy.models.base.PfUtils;
46 import org.onap.policy.models.base.PfValidationMessage;
47 import org.onap.policy.models.base.PfValidationResult;
48 import org.onap.policy.models.tosca.authorative.concepts.ToscaRequirement;
49
50 /**
51  * Class to represent the requirement in TOSCA definition.
52  *
53  * @author Chenfei Gao (cgao@research.att.com)
54  * @author Liam Fallon (liam.fallon@est.tech)
55  */
56 @Entity
57 @Table(name = "ToscaRequirement")
58 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
59 @Data
60 @EqualsAndHashCode(callSuper = true)
61 public class JpaToscaRequirement extends JpaToscaEntityType<ToscaRequirement>
62         implements PfAuthorative<ToscaRequirement> {
63
64     private static final long serialVersionUID = 2785481541573683089L;
65     private static final String AUTHORATIVE_UNBOUNDED_LITERAL = "UNBOUNDED";
66     private static final Double JPA_UNBOUNDED_VALUE = -1.0;
67
68     @Column
69     private String capability;
70
71     @Column
72     private String node;
73
74     @Column
75     private String relationship;
76
77     @ElementCollection
78     private List<Double> occurrences;
79
80     @ElementCollection
81     @Lob
82     private Map<String, String> properties;
83
84     /**
85      * The Default Constructor creates a {@link JpaToscaRequirement} object with a null key.
86      */
87     public JpaToscaRequirement() {
88         this(new PfConceptKey());
89     }
90
91     /**
92      * The Key Constructor creates a {@link JpaToscaRequirement} object with the given concept key.
93      *
94      * @param key the key
95      */
96     public JpaToscaRequirement(@NonNull final PfConceptKey key) {
97         super(key);
98     }
99
100     /**
101      * Copy constructor.
102      *
103      * @param copyConcept the concept to copy from
104      */
105     public JpaToscaRequirement(@NonNull final JpaToscaRequirement copyConcept) {
106         super(copyConcept);
107         this.capability = copyConcept.capability;
108         this.node = copyConcept.node;
109         this.relationship = copyConcept.relationship;
110         this.occurrences = new ArrayList<>(copyConcept.occurrences);
111         this.properties = PfUtils.mapMap(copyConcept.properties, String::new);
112     }
113
114     /**
115      * Authorative constructor.
116      *
117      * @param authorativeConcept the authorative concept to copy from
118      */
119     public JpaToscaRequirement(final ToscaRequirement authorativeConcept) {
120         super(new PfConceptKey());
121         this.fromAuthorative(authorativeConcept);
122     }
123
124     @Override
125     public ToscaRequirement toAuthorative() {
126         ToscaRequirement toscaRequirement = new ToscaRequirement();
127         super.setToscaEntity(toscaRequirement);
128         super.toAuthorative();
129
130         toscaRequirement.setCapability(capability);
131         toscaRequirement.setNode(node);
132         toscaRequirement.setRelationship(relationship);
133
134         if (occurrences != null) {
135             List<Object> occurrencesList = new ArrayList<>(occurrences);
136             for (Double occurrence : occurrences) {
137                 if (occurrence == JPA_UNBOUNDED_VALUE) {
138                     occurrencesList.add(AUTHORATIVE_UNBOUNDED_LITERAL);
139                 } else {
140                     occurrencesList.add(occurrence.doubleValue());
141                 }
142             }
143             toscaRequirement.setOccurrences(occurrencesList);
144         }
145
146         if (properties != null) {
147             Map<String, Object> propertiesMap = new LinkedHashMap<>();
148
149             for (Map.Entry<String, String> entry : properties.entrySet()) {
150                 propertiesMap.put(entry.getKey(), new YamlJsonTranslator().fromYaml(entry.getValue(), Object.class));
151             }
152
153             toscaRequirement.setProperties(propertiesMap);
154         }
155
156         return toscaRequirement;
157     }
158
159     @Override
160     public void fromAuthorative(@NonNull final ToscaRequirement toscaRequirement) {
161         super.fromAuthorative(toscaRequirement);
162
163         capability = toscaRequirement.getCapability();
164         node = toscaRequirement.getNode();
165         relationship = toscaRequirement.getRelationship();
166
167         if (toscaRequirement.getOccurrences() != null) {
168             occurrences = new ArrayList<>();
169             for (Object occurrence : toscaRequirement.getOccurrences()) {
170                 if (occurrence.equals(AUTHORATIVE_UNBOUNDED_LITERAL)) {
171                     occurrences.add(JPA_UNBOUNDED_VALUE);
172                 } else {
173                     occurrences.add((Double) occurrence);
174                 }
175             }
176         }
177
178         if (toscaRequirement.getProperties() != null) {
179             properties = new LinkedHashMap<>();
180             for (Map.Entry<String, Object> toscaPropertyEntry : toscaRequirement.getProperties().entrySet()) {
181                 String jpaProperty = new YamlJsonTranslator().toYaml(toscaPropertyEntry.getValue());
182                 properties.put(toscaPropertyEntry.getKey(), jpaProperty);
183             }
184         }
185
186     }
187
188     @Override
189     public List<PfKey> getKeys() {
190         return super.getKeys();
191     }
192
193     @Override
194     public void clean() {
195         super.clean();
196
197         capability = capability.trim();
198         node = node.trim();
199         relationship = relationship.trim();
200
201         properties = PfUtils.mapMap(properties, String::trim);
202     }
203
204     @Override
205     public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
206         PfValidationResult result = super.validate(resultIn);
207
208         if (properties != null) {
209             result = validateProperties(result);
210         }
211
212         if (occurrences != null) {
213             result = validateOccurrences(result);
214         }
215
216         return result;
217     }
218
219     /**
220      * Validate the properties.
221      *
222      * @param resultIn The result of validations up to now
223      * @return the validation result
224      */
225     private PfValidationResult validateProperties(final PfValidationResult resultIn) {
226         PfValidationResult result = resultIn;
227
228         for (String property : properties.values()) {
229             if (property == null) {
230                 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(),
231                         PfValidationResult.ValidationResult.INVALID, "topology template property may not be null "));
232             }
233         }
234         return result;
235     }
236
237     /**
238      * Validate the occurrences.
239      *
240      * @param resultIn The result of validations up to now
241      * @return the validation result
242      */
243     private PfValidationResult validateOccurrences(final PfValidationResult resultIn) {
244         PfValidationResult result = resultIn;
245
246         for (Double occurrence : occurrences) {
247             if (occurrence == null) {
248                 result.addValidationMessage(new PfValidationMessage(getKey(), this.getClass(),
249                         PfValidationResult.ValidationResult.INVALID, "requirement occurrence value may not be null "));
250             }
251             if (occurrence < -1.0) {
252                 result.addValidationMessage(
253                         new PfValidationMessage(getKey(), this.getClass(), PfValidationResult.ValidationResult.INVALID,
254                                 "requirement occurrence value may not be negative"));
255             }
256         }
257
258         return result;
259     }
260
261     @Override
262     public int compareTo(final PfConcept otherConcept) {
263         if (otherConcept == null) {
264             return -1;
265         }
266
267         if (this == otherConcept) {
268             return 0;
269         }
270
271         if (getClass() != otherConcept.getClass()) {
272             return getClass().getName().compareTo(otherConcept.getClass().getName());
273         }
274
275         final JpaToscaRequirement other = (JpaToscaRequirement) otherConcept;
276         int result = super.compareTo(other);
277         if (result != 0) {
278             return result;
279         }
280
281         result = capability.compareTo(other.capability);
282         if (result != 0) {
283             return result;
284         }
285
286         result = node.compareTo(other.node);
287         if (result != 0) {
288             return result;
289         }
290
291         result = relationship.compareTo(other.relationship);
292         if (result != 0) {
293             return result;
294         }
295
296         result = PfUtils.compareCollections(occurrences, other.occurrences);
297         if (result != 0) {
298             return result;
299         }
300
301         return PfUtils.compareMaps(properties, other.properties);
302     }
303 }