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