Add version on legacy get/delete
[policy/models.git] / models-base / src / main / java / org / onap / policy / models / base / PfConceptKey.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  *  ModificationsCopyright (C) 2019 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.base;
23
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import javax.persistence.Column;
28 import javax.persistence.Embeddable;
29
30 import lombok.EqualsAndHashCode;
31 import lombok.Getter;
32 import lombok.NonNull;
33 import lombok.ToString;
34
35 import org.onap.policy.common.utils.validation.Assertions;
36 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
37
38 /**
39  * An concept key uniquely identifies every first order entity in the system. Every first order concept in the system
40  * must have an {@link PfConceptKey} to identify it. Concepts that are wholly contained in another concept are
41  * identified using a {@link PfReferenceKey} key.
42  *
43  * <p>Key validation checks that the name and version fields match the NAME_REGEXP and VERSION_REGEXP
44  * regular expressions respectively.
45  */
46 @Embeddable
47 @Getter
48 @ToString
49 @EqualsAndHashCode(callSuper = false)
50 public class PfConceptKey extends PfKey {
51     private static final long serialVersionUID = 8932717618579392561L;
52
53     private static final String NAME_TOKEN = "name";
54     private static final String VERSION_TOKEN = "version";
55
56     @Column(name = NAME_TOKEN, length = 120)
57     private String name;
58
59     @Column(name = VERSION_TOKEN, length = 20)
60     private String version;
61
62     /**
63      * The default constructor creates a null concept key.
64      */
65     public PfConceptKey() {
66         this(NULL_KEY_NAME, NULL_KEY_VERSION);
67     }
68
69     /**
70      * Copy constructor.
71      *
72      * @param copyConcept the concept to copy from
73      */
74     public PfConceptKey(@NonNull final PfConceptKey copyConcept) {
75         super(copyConcept);
76     }
77
78     /**
79      * Constructor to create a key with the specified name and version.
80      *
81      * @param name the key name
82      * @param version the key version
83      */
84     public PfConceptKey(@NonNull final String name, @NonNull final String version) {
85         super();
86         this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
87         this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
88     }
89
90     /**
91      * Constructor to create a key using the key and version from the specified key ID.
92      *
93      * @param id the key ID in a format that respects the KEY_ID_REGEXP
94      */
95     public PfConceptKey(@NonNull final String id) {
96         // Check the incoming ID is valid
97         Assertions.validateStringParameter("id", id, KEY_ID_REGEXP);
98
99         // Split on colon, if the id passes the regular expression test above
100         // it'll have just one colon separating the name and version
101         // No need for range checks or size checks on the array
102         final String[] nameVersionArray = id.split(":");
103
104         // Return the new key
105         name = Assertions.validateStringParameter(NAME_TOKEN, nameVersionArray[0], NAME_REGEXP);
106         version = Assertions.validateStringParameter(VERSION_TOKEN, nameVersionArray[1], VERSION_REGEXP);
107     }
108
109     /**
110      * Get a null concept key.
111      *
112      * @return a null concept key
113      */
114     public static final PfConceptKey getNullKey() {
115         return new PfConceptKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION);
116     }
117
118     @Override
119     public PfConceptKey getKey() {
120         return this;
121     }
122
123     public void setName(@NonNull final String name) {
124         this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
125     }
126
127     public void setVersion(@NonNull final String version) {
128         this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
129     }
130
131     @Override
132     public List<PfKey> getKeys() {
133         final List<PfKey> keyList = new ArrayList<>();
134         keyList.add(getKey());
135         return keyList;
136     }
137
138     @Override
139     public String getId() {
140         return name + ':' + version;
141     }
142
143     @Override
144     public boolean isNullKey() {
145         return this.equals(PfConceptKey.getNullKey());
146     }
147
148     /**
149      * Determines if the version is "null".
150      *
151      * @return {@code true} if the version is null, {@code false} otherwise
152      */
153     public boolean isNullVersion() {
154         return PfKey.NULL_KEY_VERSION.equals(getVersion());
155     }
156
157     @Override
158     public PfKey.Compatibility getCompatibility(@NonNull final PfKey otherKey) {
159         if (!(otherKey instanceof PfConceptKey)) {
160             return Compatibility.DIFFERENT;
161         }
162         final PfConceptKey otherConceptKey = (PfConceptKey) otherKey;
163
164         if (this.equals(otherConceptKey)) {
165             return Compatibility.IDENTICAL;
166         }
167         if (!this.getName().equals(otherConceptKey.getName())) {
168             return Compatibility.DIFFERENT;
169         }
170
171         final String[] thisVersionArray = getVersion().split("\\.");
172         final String[] otherVersionArray = otherConceptKey.getVersion().split("\\.");
173
174         // There must always be at least one element in each version
175         if (!thisVersionArray[0].equals(otherVersionArray[0])) {
176             return Compatibility.MAJOR;
177         }
178
179         if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
180                         && !thisVersionArray[1].equals(otherVersionArray[1])) {
181             return Compatibility.MINOR;
182         }
183
184         return Compatibility.PATCH;
185     }
186
187     @Override
188     public boolean isCompatible(@NonNull final PfKey otherKey) {
189         if (!(otherKey instanceof PfConceptKey)) {
190             return false;
191         }
192         final PfConceptKey otherConceptKey = (PfConceptKey) otherKey;
193
194         final Compatibility compatibility = this.getCompatibility(otherConceptKey);
195
196         return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR);
197     }
198
199     @Override
200     public boolean isNewerThan(@NonNull final PfKey otherKey) {
201         Assertions.instanceOf(otherKey, PfConceptKey.class);
202
203         final PfConceptKey otherConceptKey = (PfConceptKey) otherKey;
204
205         if (this.equals(otherConceptKey)) {
206             return false;
207         }
208
209         if (!this.getName().equals(otherConceptKey.getName())) {
210             return this.getName().compareTo(otherConceptKey.getName()) > 0;
211         }
212
213         final String[] thisVersionArray = getVersion().split("\\.");
214         final String[] otherVersionArray = otherConceptKey.getVersion().split("\\.");
215
216         // There must always be at least one element in each version
217         if (!thisVersionArray[0].equals(otherVersionArray[0])) {
218             return Integer.valueOf(thisVersionArray[0]) > Integer.valueOf(otherVersionArray[0]);
219         }
220
221         if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
222                         && !thisVersionArray[1].equals(otherVersionArray[1])) {
223             return Integer.valueOf(thisVersionArray[1]) > Integer.valueOf(otherVersionArray[1]);
224         }
225
226         if (thisVersionArray.length >= 3 && otherVersionArray.length >= 3
227                         && !thisVersionArray[2].equals(otherVersionArray[2])) {
228             return Integer.valueOf(thisVersionArray[2]) > Integer.valueOf(otherVersionArray[2]);
229         }
230
231         return false;
232     }
233
234     @Override
235     public int getMajorVersion() {
236         final String[] versionArray = getVersion().split("\\.");
237
238         // There must always be at least one element in each version
239         return Integer.parseInt(versionArray[0]);
240     }
241
242     @Override
243     public int getMinorVersion() {
244         final String[] versionArray = getVersion().split("\\.");
245
246         if (versionArray.length >= 2) {
247             return Integer.parseInt(versionArray[1]);
248         }
249         else {
250             return 0;
251         }
252     }
253
254     @Override
255     public int getPatchVersion() {
256         final String[] versionArray = getVersion().split("\\.");
257
258         if (versionArray.length >= 3) {
259             return Integer.parseInt(versionArray[2]);
260         }
261         else {
262             return 0;
263         }
264     }
265
266     @Override
267     public PfValidationResult validate(final PfValidationResult result) {
268         final String nameValidationErrorMessage = Assertions.getStringParameterValidationMessage(NAME_TOKEN, name,
269                         NAME_REGEXP);
270         if (nameValidationErrorMessage != null) {
271             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
272                             "name invalid-" + nameValidationErrorMessage));
273         }
274
275         final String versionValidationErrorMessage = Assertions.getStringParameterValidationMessage(VERSION_TOKEN,
276                         version, VERSION_REGEXP);
277         if (versionValidationErrorMessage != null) {
278             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
279                             "version invalid-" + versionValidationErrorMessage));
280         }
281
282         return result;
283     }
284
285     @Override
286     public void clean() {
287         name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
288         version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
289     }
290
291     @Override
292     public PfConcept copyTo(final PfConcept target) {
293         Assertions.argumentNotNull(target, "target may not be null");
294
295         final PfConcept copyObject = target;
296         Assertions.instanceOf(copyObject, PfConceptKey.class);
297
298         final PfConceptKey copy = ((PfConceptKey) copyObject);
299         copy.setName(name);
300         copy.setVersion(version);
301
302         return copyObject;
303     }
304
305     @Override
306     public int compareTo(@NonNull final PfConcept otherObj) {
307         Assertions.argumentNotNull(otherObj, "comparison object may not be null");
308
309         if (this == otherObj) {
310             return 0;
311         }
312         if (getClass() != otherObj.getClass()) {
313             return this.hashCode() - otherObj.hashCode();
314         }
315
316         final PfConceptKey other = (PfConceptKey) otherObj;
317
318         if (!name.equals(other.name)) {
319             return name.compareTo(other.name);
320         }
321         return version.compareTo(other.version);
322     }
323 }