Changes for Checkstyle 8.32
[policy/models.git] / models-base / src / main / java / org / onap / policy / models / base / PfReferenceKey.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2019 Nordix Foundation.
4  *  Modifications Copyright (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 import javax.persistence.Column;
27 import javax.persistence.Embeddable;
28 import lombok.Data;
29 import lombok.EqualsAndHashCode;
30 import lombok.NonNull;
31 import org.onap.policy.common.utils.validation.Assertions;
32 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
33
34 /**
35  * A reference key identifies entities in the system that are contained in other entities. Every contained concept in
36  * the system must have an {@link PfReferenceKey} to identify it. Non-contained first order concepts are identified
37  * using an {@link PfConceptKey} key.
38  *
39  * <p>An {@link PfReferenceKey} contains an {@link PfConceptKey} key reference to the first order entity that contains
40  * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained
41  * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key
42  * of all its children must be unique.
43  *
44  * <p>If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference
45  * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL.
46  *
47  * <p>Key validation checks that the parent name and parent version fields match the NAME_REGEXP and
48  * VERSION_REGEXP regular expressions respectively and that the local name fields match the
49  * LOCAL_NAME_REGEXP regular expression.
50  */
51 @Embeddable
52 @Data
53 @EqualsAndHashCode(callSuper = false)
54 public class PfReferenceKey extends PfKey {
55     private static final String PARENT_KEY_NAME = "parentKeyName";
56     private static final String PARENT_KEY_VERSION = "parentKeyVersion";
57     private static final String PARENT_LOCAL_NAME = "parentLocalName";
58     private static final String LOCAL_NAME = "localName";
59
60     private static final long serialVersionUID = 8932717618579392561L;
61
62     /** Regular expression to specify the structure of local names in reference keys. */
63     public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$";
64
65     /** Regular expression to specify the structure of IDs in reference keys. */
66     public static final String REFERENCE_KEY_ID_REGEXP =
67                     "[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+";
68
69     private static final int PARENT_NAME_FIELD = 0;
70     private static final int PARENT_VERSION_FIELD = 1;
71     private static final int PARENT_LOCAL_NAME_FIELD = 2;
72     private static final int LOCAL_NAME_FIELD = 3;
73
74     @Column(name = PARENT_KEY_NAME, length = 120)
75     private String parentKeyName;
76
77     @Column(name = PARENT_KEY_VERSION, length = 15)
78     private String parentKeyVersion;
79
80     @Column(name = PARENT_LOCAL_NAME, length = 120)
81     private String parentLocalName;
82
83     @Column(name = LOCAL_NAME, length = 120)
84     private String localName;
85
86     /**
87      * The default constructor creates a null reference key.
88      */
89     public PfReferenceKey() {
90         this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
91     }
92
93     /**
94      * The Copy Constructor creates a key by copying another key.
95      *
96      * @param referenceKey
97      *        the reference key to copy from
98      */
99     public PfReferenceKey(final PfReferenceKey referenceKey) {
100         this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
101                         referenceKey.getLocalName());
102     }
103
104     /**
105      * Constructor to create a null reference key for the specified parent concept key.
106      *
107      * @param pfConceptKey
108      *        the parent concept key of this reference key
109      */
110     public PfReferenceKey(final PfConceptKey pfConceptKey) {
111         this(pfConceptKey.getName(), pfConceptKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
112     }
113
114     /**
115      * Constructor to create a reference key for the given parent concept key with the given local name.
116      *
117      * @param pfConceptKey
118      *        the parent concept key of this reference key
119      * @param localName
120      *        the local name of this reference key
121      */
122     public PfReferenceKey(final PfConceptKey pfConceptKey, final String localName) {
123         this(pfConceptKey, NULL_KEY_NAME, localName);
124     }
125
126     /**
127      * Constructor to create a reference key for the given parent reference key with the given local name.
128      *
129      * @param parentReferenceKey
130      *        the parent reference key of this reference key
131      * @param localName
132      *        the local name of this reference key
133      */
134     public PfReferenceKey(final PfReferenceKey parentReferenceKey, final String localName) {
135         this(parentReferenceKey.getParentConceptKey(), parentReferenceKey.getLocalName(), localName);
136     }
137
138     /**
139      * Constructor to create a reference key for the given parent reference key (specified by the parent reference key's
140      * concept key and local name) with the given local name.
141      *
142      * @param pfConceptKey
143      *        the concept key of the parent reference key of this reference key
144      * @param parentLocalName
145      *        the local name of the parent reference key of this reference key
146      * @param localName
147      *        the local name of this reference key
148      */
149     public PfReferenceKey(final PfConceptKey pfConceptKey, final String parentLocalName, final String localName) {
150         this(pfConceptKey.getName(), pfConceptKey.getVersion(), parentLocalName, localName);
151     }
152
153     /**
154      * Constructor to create a reference key for the given parent concept key (specified by the parent concept key's
155      * name and version) with the given local name.
156      *
157      * @param parentKeyName
158      *        the name of the parent concept key of this reference key
159      * @param parentKeyVersion
160      *        the version of the parent concept key of this reference key
161      * @param localName
162      *        the local name of this reference key
163      */
164     public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
165         this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
166     }
167
168     /**
169      * Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad
170      * local name) with the given local name.
171      *
172      * @param parentKeyName
173      *        the parent key name of this reference key
174      * @param parentKeyVersion
175      *        the parent key version of this reference key
176      * @param parentLocalName
177      *        the parent local name of this reference key
178      * @param localName
179      *        the local name of this reference key
180      */
181     public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
182                     final String localName) {
183         super();
184         this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
185         this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
186                         VERSION_REGEXP);
187         this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
188                         LOCAL_NAME_REGEXP);
189         this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
190     }
191
192     /**
193      * Constructor to create a key from the specified key ID.
194      *
195      * @param id
196      *        the key ID in a format that respects the KEY_ID_REGEXP
197      */
198     public PfReferenceKey(final String id) {
199         final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
200
201         // Split on colon, if the id passes the regular expression test above
202         // it'll have just three colons separating the parent name,
203         // parent version, parent local name, and and local name
204         // No need for range checks or size checks on the array
205         final String[] nameVersionNameArray = conditionedId.split(":");
206
207         // Initiate the new key
208         parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
209                         NAME_REGEXP);
210         parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION,
211                         nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP);
212         parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME,
213                         nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP);
214         localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD],
215                         LOCAL_NAME_REGEXP);
216     }
217
218     /**
219      * Get a null reference key.
220      *
221      * @return a null reference key
222      */
223     public static PfReferenceKey getNullKey() {
224         return new PfReferenceKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION, PfKey.NULL_KEY_NAME,
225                         PfKey.NULL_KEY_NAME);
226     }
227
228     @Override
229     public PfReferenceKey getKey() {
230         return this;
231     }
232
233     @Override
234     public List<PfKey> getKeys() {
235         final List<PfKey> keyList = new ArrayList<>();
236         keyList.add(getKey());
237         return keyList;
238     }
239
240     @Override
241     public String getId() {
242         return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName;
243     }
244
245     @Override
246     public boolean isNullKey() {
247         return this.equals(PfReferenceKey.getNullKey());
248     }
249
250     /**
251      * Gets the parent concept key of this reference key.
252      *
253      * @return the parent concept key of this reference key
254      */
255     public PfConceptKey getParentConceptKey() {
256         return new PfConceptKey(parentKeyName, parentKeyVersion);
257     }
258
259     /**
260      * Gets the parent reference key of this reference key.
261      *
262      * @return the parent reference key of this reference key
263      */
264     public PfReferenceKey getParentReferenceKey() {
265         return new PfReferenceKey(parentKeyName, parentKeyVersion, parentLocalName);
266     }
267
268     /**
269      * Sets the parent concept key of this reference key.
270      *
271      * @param parentKey
272      *        the parent concept key of this reference key
273      */
274     public void setParentConceptKey(final PfConceptKey parentKey) {
275         Assertions.argumentNotNull(parentKey, "parentKey may not be null");
276
277         parentKeyName = parentKey.getName();
278         parentKeyVersion = parentKey.getVersion();
279         parentLocalName = NULL_KEY_NAME;
280     }
281
282     /**
283      * Sets the parent reference key of this reference key.
284      *
285      * @param parentKey
286      *        the parent reference key of this reference key
287      */
288     public void setParentReferenceKey(final PfReferenceKey parentKey) {
289         Assertions.argumentNotNull(parentKey, "parentKey may not be null");
290
291         parentKeyName = parentKey.getParentKeyName();
292         parentKeyVersion = parentKey.getParentKeyVersion();
293         parentLocalName = parentKey.getLocalName();
294     }
295
296     @Override
297     public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
298         if (!(otherKey instanceof PfReferenceKey)) {
299             return Compatibility.DIFFERENT;
300         }
301         final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
302
303         return this.getParentConceptKey().getCompatibility(otherReferenceKey.getParentConceptKey());
304     }
305
306     @Override
307     public boolean isCompatible(@NonNull final PfKey otherKey) {
308         if (!(otherKey instanceof PfReferenceKey)) {
309             return false;
310         }
311         final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
312
313         return this.getParentConceptKey().isCompatible(otherReferenceKey.getParentConceptKey());
314     }
315
316     @Override
317     public int getMajorVersion() {
318         return this.getParentConceptKey().getMajorVersion();
319     }
320
321     @Override
322     public int getMinorVersion() {
323         return this.getParentConceptKey().getMinorVersion();
324     }
325
326     @Override
327     public int getPatchVersion() {
328         return this.getParentConceptKey().getPatchVersion();
329     }
330
331
332     @Override
333     public boolean isNewerThan(@NonNull final PfKey otherKey) {
334         Assertions.instanceOf(otherKey, PfReferenceKey.class);
335
336         final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
337
338         return this.getParentConceptKey().isNewerThan(otherReferenceKey.getParentConceptKey());
339     }
340
341     @Override
342     public PfValidationResult validate(final PfValidationResult result) {
343         final String parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME,
344                         parentKeyName, NAME_REGEXP);
345         if (parentNameValidationErrorMessage != null) {
346             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
347                             "parentKeyName invalid-" + parentNameValidationErrorMessage));
348         }
349
350         final String parentKeyVersionValidationErrorMessage = Assertions
351                         .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
352         if (parentKeyVersionValidationErrorMessage != null) {
353             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
354                             "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage));
355         }
356
357         final String parentLocalNameValidationErrorMessage = Assertions
358                         .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
359         if (parentLocalNameValidationErrorMessage != null) {
360             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
361                             "parentLocalName invalid-" + parentLocalNameValidationErrorMessage));
362         }
363
364         final String localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME,
365                         localName, LOCAL_NAME_REGEXP);
366         if (localNameValidationErrorMessage != null) {
367             result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
368                             "localName invalid-" + localNameValidationErrorMessage));
369         }
370
371         return result;
372     }
373
374     @Override
375     public void clean() {
376         parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
377         parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
378         parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
379         localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
380     }
381
382     @Override
383     public int compareTo(final PfConcept otherObj) {
384         Assertions.argumentNotNull(otherObj, "comparison object may not be null");
385
386         if (this == otherObj) {
387             return 0;
388         }
389         if (getClass() != otherObj.getClass()) {
390             return getClass().getName().compareTo(otherObj.getClass().getName());
391         }
392
393         final PfReferenceKey other = (PfReferenceKey) otherObj;
394         if (!parentKeyName.equals(other.parentKeyName)) {
395             return parentKeyName.compareTo(other.parentKeyName);
396         }
397         if (!parentKeyVersion.equals(other.parentKeyVersion)) {
398             return parentKeyVersion.compareTo(other.parentKeyVersion);
399         }
400         if (!parentLocalName.equals(other.parentLocalName)) {
401             return parentLocalName.compareTo(other.parentLocalName);
402         }
403         return localName.compareTo(other.localName);
404     }
405 }