32fb76c992cb3ce0f513814ac0c4cf1fded15f49
[policy/apex-pdp.git] / model / basic-model / src / main / java / org / onap / policy / apex / model / basicmodel / concepts / AxReferenceKey.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
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.apex.model.basicmodel.concepts;
23
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import javax.persistence.Column;
28 import javax.persistence.Embeddable;
29 import javax.xml.bind.annotation.XmlAccessType;
30 import javax.xml.bind.annotation.XmlAccessorType;
31 import javax.xml.bind.annotation.XmlElement;
32 import javax.xml.bind.annotation.XmlRootElement;
33 import javax.xml.bind.annotation.XmlType;
34
35 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
36 import org.onap.policy.common.utils.validation.Assertions;
37
38 /**
39  * A reference key identifies entities in the system that are contained in other entities. Every contained concept in
40  * the system must have an {@link AxReferenceKey} to identify it. Non-contained first order concepts are identified
41  * using an {@link AxArtifactKey} key.
42  *
43  * <p>An {@link AxReferenceKey} contains an {@link AxArtifactKey} key reference to the first order entity that contains
44  * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained
45  * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key
46  * of all its children must be unique.
47  *
48  * <p>If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference
49  * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL.
50  *
51  * <p>Key validation checks that the parent name and parent version fields match the NAME_REGEXP and
52  * VERSION_REGEXP regular expressions respectively and that the local name fields match the
53  * LOCAL_NAME_REGEXP regular expression.
54  */
55 @Embeddable
56 @XmlAccessorType(XmlAccessType.FIELD)
57 @XmlRootElement(name = "apexReferenceKey", namespace = "http://www.onap.org/policy/apex-pdp")
58 @XmlType(name = "AxReferenceKey", namespace = "http://www.onap.org/policy/apex-pdp", propOrder = { "parentKeyName",
59                 "parentKeyVersion", "parentLocalName", "localName" })
60
61 public class AxReferenceKey extends AxKey {
62     private static final String PARENT_KEY_NAME = "parentKeyName";
63     private static final String PARENT_KEY_VERSION = "parentKeyVersion";
64     private static final String PARENT_LOCAL_NAME = "parentLocalName";
65     private static final String LOCAL_NAME = "localName";
66
67     private static final long serialVersionUID = 8932717618579392561L;
68
69     /** Regular expression to specify the structure of local names in reference keys. */
70     public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$";
71
72     /** Regular expression to specify the structure of IDs in reference keys. */
73     public static final String REFERENCE_KEY_ID_REGEXP =
74                     "[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+";
75
76     private static final int PARENT_NAME_FIELD = 0;
77     private static final int PARENT_VERSION_FIELD = 1;
78     private static final int PARENT_LOCAL_NAME_FIELD = 2;
79     private static final int LOCAL_NAME_FIELD = 3;
80
81     @Column(name = PARENT_KEY_NAME)
82     @XmlElement(required = true)
83     private String parentKeyName;
84
85     @Column(name = PARENT_KEY_VERSION)
86     @XmlElement(required = true)
87     private String parentKeyVersion;
88
89     @Column(name = PARENT_LOCAL_NAME)
90     @XmlElement(required = true)
91     private String parentLocalName;
92
93     @Column(name = LOCAL_NAME)
94     @XmlElement(required = true)
95     private String localName;
96
97     /**
98      * The default constructor creates a null reference key.
99      */
100     public AxReferenceKey() {
101         this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
102     }
103
104     /**
105      * The Copy Constructor creates a key by copying another key.
106      *
107      * @param referenceKey
108      *        the reference key to copy from
109      */
110     public AxReferenceKey(final AxReferenceKey referenceKey) {
111         this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
112                         referenceKey.getLocalName());
113     }
114
115     /**
116      * Constructor to create a null reference key for the specified parent artifact key.
117      *
118      * @param axArtifactKey
119      *        the parent artifact key of this reference key
120      */
121     public AxReferenceKey(final AxArtifactKey axArtifactKey) {
122         this(axArtifactKey.getName(), axArtifactKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
123     }
124
125     /**
126      * Constructor to create a reference key for the given parent artifact key with the given local name.
127      *
128      * @param axArtifactKey
129      *        the parent artifact key of this reference key
130      * @param localName
131      *        the local name of this reference key
132      */
133     public AxReferenceKey(final AxArtifactKey axArtifactKey, final String localName) {
134         this(axArtifactKey, NULL_KEY_NAME, localName);
135     }
136
137     /**
138      * Constructor to create a reference key for the given parent reference key with the given local name.
139      *
140      * @param parentReferenceKey
141      *        the parent reference key of this reference key
142      * @param localName
143      *        the local name of this reference key
144      */
145     public AxReferenceKey(final AxReferenceKey parentReferenceKey, final String localName) {
146         this(parentReferenceKey.getParentArtifactKey(), parentReferenceKey.getLocalName(), localName);
147     }
148
149     /**
150      * Constructor to create a reference key for the given parent reference key (specified by the parent reference key's
151      * artifact key and local name) with the given local name.
152      *
153      * @param axArtifactKey
154      *        the artifact key of the parent reference key of this reference key
155      * @param parentLocalName
156      *        the local name of the parent reference key of this reference key
157      * @param localName
158      *        the local name of this reference key
159      */
160     public AxReferenceKey(final AxArtifactKey axArtifactKey, final String parentLocalName, final String localName) {
161         this(axArtifactKey.getName(), axArtifactKey.getVersion(), parentLocalName, localName);
162     }
163
164     /**
165      * Constructor to create a reference key for the given parent artifact key (specified by the parent artifact key's
166      * name and version) with the given local name.
167      *
168      * @param parentKeyName
169      *        the name of the parent artifact key of this reference key
170      * @param parentKeyVersion
171      *        the version of the parent artifact key of this reference key
172      * @param localName
173      *        the local name of this reference key
174      */
175     public AxReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
176         this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
177     }
178
179     /**
180      * Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad
181      * local name) with the given local name.
182      *
183      * @param parentKeyName
184      *        the parent key name of this reference key
185      * @param parentKeyVersion
186      *        the parent key version of this reference key
187      * @param parentLocalName
188      *        the parent local name of this reference key
189      * @param localName
190      *        the local name of this reference key
191      */
192     public AxReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
193                     final String localName) {
194         super();
195         this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
196         this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
197                         VERSION_REGEXP);
198         this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
199                         LOCAL_NAME_REGEXP);
200         this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
201     }
202
203     /**
204      * Constructor to create a key from the specified key ID.
205      *
206      * @param id
207      *        the key ID in a format that respects the KEY_ID_REGEXP
208      */
209     public AxReferenceKey(final String id) {
210         final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
211
212         // Split on colon, if the id passes the regular expression test above
213         // it'll have just three colons separating the parent name,
214         // parent version, parent local name, and and local name
215         // No need for range checks or size checks on the array
216         final String[] nameVersionNameArray = conditionedId.split(":");
217
218         // Initiate the new key
219         parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
220                         NAME_REGEXP);
221         parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION,
222                         nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP);
223         parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME,
224                         nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP);
225         localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD],
226                         LOCAL_NAME_REGEXP);
227     }
228
229     /**
230      * Get a null reference key.
231      *
232      * @return a null reference key
233      */
234     public static AxReferenceKey getNullKey() {
235         return new AxReferenceKey(AxKey.NULL_KEY_NAME, AxKey.NULL_KEY_VERSION, AxKey.NULL_KEY_NAME,
236                         AxKey.NULL_KEY_NAME);
237     }
238
239     /**
240      * {@inheritDoc}.
241      */
242     @Override
243     public AxReferenceKey getKey() {
244         return this;
245     }
246
247     /**
248      * {@inheritDoc}.
249      */
250     @Override
251     public List<AxKey> getKeys() {
252         final List<AxKey> keyList = new ArrayList<>();
253         keyList.add(getKey());
254         return keyList;
255     }
256
257     /**
258      * {@inheritDoc}.
259      */
260     @Override
261     public String getId() {
262         return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName;
263     }
264
265     /**
266      * Gets the parent artifact key of this reference key.
267      *
268      * @return the parent artifact key of this reference key
269      */
270     public AxArtifactKey getParentArtifactKey() {
271         return new AxArtifactKey(parentKeyName, parentKeyVersion);
272     }
273
274     /**
275      * Gets the parent reference key of this reference key.
276      *
277      * @return the parent reference key of this reference key
278      */
279     public AxReferenceKey getParentReferenceKey() {
280         return new AxReferenceKey(parentKeyName, parentKeyVersion, parentLocalName);
281     }
282
283     /**
284      * Sets the parent artifact key of this reference key.
285      *
286      * @param parentKey
287      *        the parent artifact key of this reference key
288      */
289     public void setParentArtifactKey(final AxArtifactKey parentKey) {
290         Assertions.argumentNotNull(parentKey, "parentKey may not be null");
291
292         parentKeyName = parentKey.getName();
293         parentKeyVersion = parentKey.getVersion();
294         parentLocalName = NULL_KEY_NAME;
295     }
296
297     /**
298      * Sets the parent reference key of this reference key.
299      *
300      * @param parentKey
301      *        the parent reference key of this reference key
302      */
303     public void setParentReferenceKey(final AxReferenceKey parentKey) {
304         Assertions.argumentNotNull(parentKey, "parentKey may not be null");
305
306         parentKeyName = parentKey.getParentKeyName();
307         parentKeyVersion = parentKey.getParentKeyVersion();
308         parentLocalName = parentKey.getLocalName();
309     }
310
311     /**
312      * Gets the parent key name of this reference key.
313      *
314      * @return the parent key name of this reference key
315      */
316     public String getParentKeyName() {
317         return parentKeyName;
318     }
319
320     /**
321      * Sets the parent key name of this reference key.
322      *
323      * @param parentKeyName
324      *        the parent key name of this reference key
325      */
326     public void setParentKeyName(final String parentKeyName) {
327         this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
328     }
329
330     /**
331      * Gets the parent key version of this reference key.
332      *
333      * @return the parent key version of this reference key
334      */
335     public String getParentKeyVersion() {
336         return parentKeyVersion;
337     }
338
339     /**
340      * Sets the parent key version of this reference key.
341      *
342      * @param parentKeyVersion
343      *        the parent key version of this reference key
344      */
345     public void setParentKeyVersion(final String parentKeyVersion) {
346         this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
347                         VERSION_REGEXP);
348     }
349
350     /**
351      * Gets the parent local name of this reference key.
352      *
353      * @return the parent local name of this reference key
354      */
355     public String getParentLocalName() {
356         return parentLocalName;
357     }
358
359     /**
360      * Sets the parent local name of this reference key.
361      *
362      * @param parentLocalName
363      *        the parent local name of this reference key
364      */
365     public void setParentLocalName(final String parentLocalName) {
366         this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
367                         LOCAL_NAME_REGEXP);
368     }
369
370     /**
371      * Gets the local name of this reference key.
372      *
373      * @return the local name of this reference key
374      */
375     public String getLocalName() {
376         return localName;
377     }
378
379     /**
380      * Sets the local name of this reference key.
381      *
382      * @param localName
383      *        the local name of this reference key
384      */
385     public void setLocalName(final String localName) {
386         this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
387     }
388
389     /**
390      * {@inheritDoc}.
391      */
392     @Override
393     public AxKey.Compatibility getCompatibility(final AxKey otherKey) {
394         if (!(otherKey instanceof AxReferenceKey)) {
395             return Compatibility.DIFFERENT;
396         }
397         final AxReferenceKey otherReferenceKey = (AxReferenceKey) otherKey;
398
399         return this.getParentArtifactKey().getCompatibility(otherReferenceKey.getParentArtifactKey());
400     }
401
402     /**
403      * {@inheritDoc}.
404      */
405     @Override
406     public boolean isCompatible(final AxKey otherKey) {
407         if (!(otherKey instanceof AxReferenceKey)) {
408             return false;
409         }
410         final AxReferenceKey otherReferenceKey = (AxReferenceKey) otherKey;
411
412         return this.getParentArtifactKey().isCompatible(otherReferenceKey.getParentArtifactKey());
413     }
414
415     /**
416      * {@inheritDoc}.
417      */
418     @Override
419     public AxValidationResult validate(final AxValidationResult result) {
420         final String parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME,
421                         parentKeyName, NAME_REGEXP);
422         if (parentNameValidationErrorMessage != null) {
423             result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
424                             "parentKeyName invalid-" + parentNameValidationErrorMessage));
425         }
426
427         final String parentKeyVersionValidationErrorMessage = Assertions
428                         .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
429         if (parentKeyVersionValidationErrorMessage != null) {
430             result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
431                             "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage));
432         }
433
434         final String parentLocalNameValidationErrorMessage = Assertions
435                         .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
436         if (parentLocalNameValidationErrorMessage != null) {
437             result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
438                             "parentLocalName invalid-" + parentLocalNameValidationErrorMessage));
439         }
440
441         final String localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME,
442                         localName, LOCAL_NAME_REGEXP);
443         if (localNameValidationErrorMessage != null) {
444             result.addValidationMessage(new AxValidationMessage(this, this.getClass(), ValidationResult.INVALID,
445                             "localName invalid-" + localNameValidationErrorMessage));
446         }
447
448         return result;
449     }
450
451     /**
452      * {@inheritDoc}.
453      */
454     @Override
455     public void clean() {
456         parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
457         parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
458         parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
459         localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
460     }
461
462     /**
463      * {@inheritDoc}.
464      */
465     @Override
466     public String toString() {
467         final StringBuilder builder = new StringBuilder();
468         builder.append(this.getClass().getSimpleName());
469         builder.append(":(");
470         builder.append("parentKeyName=");
471         builder.append(parentKeyName);
472         builder.append(",parentKeyVersion=");
473         builder.append(parentKeyVersion);
474         builder.append(",parentLocalName=");
475         builder.append(parentLocalName);
476         builder.append(",localName=");
477         builder.append(localName);
478         builder.append(")");
479         return builder.toString();
480     }
481
482     /**
483      * {@inheritDoc}.
484      */
485     @Override
486     public AxConcept copyTo(final AxConcept target) {
487         Assertions.argumentNotNull(target, "target may not be null");
488
489         final Object copyObject = target;
490         Assertions.instanceOf(copyObject, AxReferenceKey.class);
491
492         final AxReferenceKey copy = ((AxReferenceKey) copyObject);
493         copy.setParentKeyName(parentKeyName);
494         copy.setParentKeyVersion(parentKeyVersion);
495         copy.setLocalName(localName);
496         copy.setParentLocalName(parentLocalName);
497
498         return copy;
499     }
500
501     /**
502      * {@inheritDoc}.
503      */
504     @Override
505     public int hashCode() {
506         final int prime = 31;
507         int result = 1;
508         result = prime * result + parentKeyName.hashCode();
509         result = prime * result + parentKeyVersion.hashCode();
510         result = prime * result + parentLocalName.hashCode();
511         result = prime * result + localName.hashCode();
512         return result;
513     }
514
515     /**
516      * {@inheritDoc}.
517      */
518     @Override
519     public boolean equals(final Object obj) {
520         if (obj == null) {
521             throw new IllegalArgumentException("comparison object may not be null");
522         }
523
524         if (this == obj) {
525             return true;
526         }
527
528         if (getClass() != obj.getClass()) {
529             return false;
530         }
531
532         final AxReferenceKey other = (AxReferenceKey) obj;
533
534         if (!parentKeyName.equals(other.parentKeyName)) {
535             return false;
536         }
537         if (!parentKeyVersion.equals(other.parentKeyVersion)) {
538             return false;
539         }
540         if (!parentLocalName.equals(other.parentLocalName)) {
541             return false;
542         }
543         return localName.equals(other.localName);
544     }
545
546     /**
547      * {@inheritDoc}.
548      */
549     @Override
550     public int compareTo(final AxConcept otherObj) {
551         Assertions.argumentNotNull(otherObj, "comparison object may not be null");
552
553         if (this == otherObj) {
554             return 0;
555         }
556         if (getClass() != otherObj.getClass()) {
557             return this.hashCode() - otherObj.hashCode();
558         }
559
560         final AxReferenceKey other = (AxReferenceKey) otherObj;
561         if (!parentKeyName.equals(other.parentKeyName)) {
562             return parentKeyName.compareTo(other.parentKeyName);
563         }
564         if (!parentKeyVersion.equals(other.parentKeyVersion)) {
565             return parentKeyVersion.compareTo(other.parentKeyVersion);
566         }
567         if (!parentLocalName.equals(other.parentLocalName)) {
568             return parentLocalName.compareTo(other.parentLocalName);
569         }
570         return localName.compareTo(other.localName);
571     }
572 }