Use annotations to do validation
[policy/models.git] / models-tosca / src / main / java / org / onap / policy / models / tosca / simple / concepts / JpaToscaNodeType.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2020 Nordix Foundation.
4  * Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.models.tosca.simple.concepts;
23
24 import java.util.Collection;
25 import java.util.LinkedHashMap;
26 import java.util.LinkedHashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import java.util.Set;
31 import javax.persistence.CascadeType;
32 import javax.persistence.ElementCollection;
33 import javax.persistence.Entity;
34 import javax.persistence.FetchType;
35 import javax.persistence.Inheritance;
36 import javax.persistence.InheritanceType;
37 import javax.persistence.JoinColumn;
38 import javax.persistence.JoinColumns;
39 import javax.persistence.Lob;
40 import javax.persistence.OneToOne;
41 import javax.persistence.Table;
42 import lombok.Data;
43 import lombok.EqualsAndHashCode;
44 import lombok.NonNull;
45 import org.apache.commons.collections4.CollectionUtils;
46 import org.apache.commons.lang3.ObjectUtils;
47 import org.onap.policy.common.parameters.BeanValidationResult;
48 import org.onap.policy.common.parameters.annotations.Entries;
49 import org.onap.policy.common.parameters.annotations.Items;
50 import org.onap.policy.common.parameters.annotations.NotNull;
51 import org.onap.policy.common.parameters.annotations.Valid;
52 import org.onap.policy.models.base.PfAuthorative;
53 import org.onap.policy.models.base.PfConcept;
54 import org.onap.policy.models.base.PfConceptKey;
55 import org.onap.policy.models.base.PfKey;
56 import org.onap.policy.models.base.PfReferenceKey;
57 import org.onap.policy.models.base.PfUtils;
58 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
59 import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
60 import org.onap.policy.models.tosca.utils.ToscaUtils;
61
62 /**
63  * Class to represent the node type in TOSCA definition.
64  */
65
66 @Entity
67 @Table(name = "ToscaNodeType")
68 @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
69 @Data
70 @EqualsAndHashCode(callSuper = true)
71 public class JpaToscaNodeType extends JpaToscaEntityType<ToscaNodeType> implements PfAuthorative<ToscaNodeType> {
72     private static final long serialVersionUID = -563659852901842616L;
73
74     @ElementCollection
75     @Lob
76     @Entries(key = @Items(notNull = {@NotNull}), value = @Items(notNull = {@NotNull}, valid = {@Valid}))
77     private Map<String, JpaToscaProperty> properties;
78
79
80     // formatter:off
81     @OneToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
82     @JoinColumns({@JoinColumn(name = "requirementsName", referencedColumnName = "name"),
83         @JoinColumn(name = "requirementsVersion", referencedColumnName = "version")})
84     // @formatter:on
85     @Valid
86     private JpaToscaRequirements requirements;
87
88     /**
89      * The Default Constructor creates a {@link JpaToscaNodeType} object with a null key.
90      */
91     public JpaToscaNodeType() {
92         this(new PfConceptKey());
93     }
94
95     /**
96      * The Key Constructor creates a {@link JpaToscaNodeType} object with the given concept key.
97      *
98      * @param key the key
99      */
100     public JpaToscaNodeType(@NonNull final PfConceptKey key) {
101         super(key);
102     }
103
104     /**
105      * Copy constructor.
106      *
107      * @param copyConcept the concept to copy from
108      */
109     public JpaToscaNodeType(final JpaToscaNodeType copyConcept) {
110         super(copyConcept);
111         this.properties = PfUtils.mapMap(copyConcept.properties, JpaToscaProperty::new);
112         this.requirements =
113                 (copyConcept.requirements != null ? new JpaToscaRequirements(copyConcept.requirements) : null);
114     }
115
116     /**
117      * Authorative constructor.
118      *
119      * @param authorativeConcept the authorative concept to copy from
120      */
121     public JpaToscaNodeType(final ToscaNodeType authorativeConcept) {
122         this.fromAuthorative(authorativeConcept);
123     }
124
125     @Override
126     public ToscaNodeType toAuthorative() {
127         ToscaNodeType toscaNodeType = new ToscaNodeType();
128         super.setToscaEntity(toscaNodeType);
129         super.toAuthorative();
130
131         toscaNodeType.setProperties(PfUtils.mapMap(properties, JpaToscaProperty::toAuthorative));
132
133         if (requirements != null) {
134             toscaNodeType.setRequirements(requirements.toAuthorative());
135         }
136
137         return toscaNodeType;
138     }
139
140     @Override
141     public void fromAuthorative(final ToscaNodeType toscaNodeType) {
142         super.fromAuthorative(toscaNodeType);
143
144         // Set properties
145         if (toscaNodeType.getProperties() != null) {
146             properties = new LinkedHashMap<>();
147             for (Entry<String, ToscaProperty> toscaPropertyEntry : toscaNodeType.getProperties().entrySet()) {
148                 JpaToscaProperty jpaProperty = new JpaToscaProperty(toscaPropertyEntry.getValue());
149                 jpaProperty.setKey(new PfReferenceKey(getKey(), toscaPropertyEntry.getKey()));
150                 properties.put(toscaPropertyEntry.getKey(), jpaProperty);
151             }
152         }
153
154         if (toscaNodeType.getRequirements() != null) {
155             requirements = new JpaToscaRequirements();
156             requirements.fromAuthorative(toscaNodeType.getRequirements());
157         }
158     }
159
160     @Override
161     public List<PfKey> getKeys() {
162         final List<PfKey> keyList = super.getKeys();
163
164         if (properties != null) {
165             for (JpaToscaProperty property : properties.values()) {
166                 keyList.addAll(property.getKeys());
167             }
168         }
169
170         if (requirements != null) {
171             keyList.addAll(requirements.getKeys());
172         }
173
174         return keyList;
175     }
176
177     @Override
178     public void clean() {
179         super.clean();
180
181         if (properties != null) {
182             for (JpaToscaProperty property : properties.values()) {
183                 property.clean();
184             }
185         }
186
187         if (requirements != null) {
188             requirements.clean();
189         }
190     }
191
192     @Override
193     public BeanValidationResult validate(String fieldName) {
194         BeanValidationResult result = super.validate(fieldName);
195
196         result.addResult(validateKeyVersionNotNull("key", getKey()));
197
198         return result;
199     }
200
201     @Override
202     public int compareTo(final PfConcept otherConcept) {
203         if (otherConcept == null) {
204             return -1;
205         }
206         if (this == otherConcept) {
207             return 0;
208         }
209         if (getClass() != otherConcept.getClass()) {
210             return getClass().getName().compareTo(otherConcept.getClass().getName());
211         }
212
213         final JpaToscaNodeType other = (JpaToscaNodeType) otherConcept;
214         int result = super.compareTo(other);
215         if (result != 0) {
216             return result;
217         }
218
219         result = PfUtils.compareMaps(properties, other.properties);
220         if (result != 0) {
221             return result;
222         }
223
224         return ObjectUtils.compare(requirements, other.requirements);
225     }
226
227     /**
228      * Get the data types referenced in a node type.
229      *
230      * @return the data types referenced in a node type
231      */
232     public Collection<PfConceptKey> getReferencedDataTypes() {
233         if (properties == null) {
234             return CollectionUtils.emptyCollection();
235         }
236
237         Set<PfConceptKey> referencedDataTypes = new LinkedHashSet<>();
238
239         for (JpaToscaProperty property : properties.values()) {
240             referencedDataTypes.add(property.getType());
241
242             if (property.getEntrySchema() != null) {
243                 referencedDataTypes.add(property.getEntrySchema().getType());
244             }
245         }
246
247         referencedDataTypes.removeAll(ToscaUtils.getPredefinedDataTypes());
248
249         return referencedDataTypes;
250     }
251 }