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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
22 package org.onap.policy.models.base;
24 import java.util.ArrayList;
25 import java.util.List;
27 import javax.persistence.Column;
28 import javax.persistence.Embeddable;
31 import lombok.EqualsAndHashCode;
32 import lombok.NonNull;
34 import org.onap.policy.common.utils.validation.Assertions;
35 import org.onap.policy.models.base.PfValidationResult.ValidationResult;
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.
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.
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.
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.
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";
63 private static final long serialVersionUID = 8932717618579392561L;
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\\-_\\.]+|^$";
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\\-_]+";
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;
77 @Column(name = PARENT_KEY_NAME, length = 120)
78 private String parentKeyName;
80 @Column(name = PARENT_KEY_VERSION, length = 15)
81 private String parentKeyVersion;
83 @Column(name = PARENT_LOCAL_NAME, length = 120)
84 private String parentLocalName;
86 @Column(name = LOCAL_NAME, length = 120)
87 private String localName;
90 * The default constructor creates a null reference key.
92 public PfReferenceKey() {
93 this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
97 * The Copy Constructor creates a key by copying another key.
100 * the reference key to copy from
102 public PfReferenceKey(final PfReferenceKey referenceKey) {
103 this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
104 referenceKey.getLocalName());
108 * Constructor to create a null reference key for the specified parent concept key.
110 * @param pfConceptKey
111 * the parent concept key of this reference key
113 public PfReferenceKey(final PfConceptKey pfConceptKey) {
114 this(pfConceptKey.getName(), pfConceptKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
118 * Constructor to create a reference key for the given parent concept key with the given local name.
120 * @param pfConceptKey
121 * the parent concept key of this reference key
123 * the local name of this reference key
125 public PfReferenceKey(final PfConceptKey pfConceptKey, final String localName) {
126 this(pfConceptKey, NULL_KEY_NAME, localName);
130 * Constructor to create a reference key for the given parent reference key with the given local name.
132 * @param parentReferenceKey
133 * the parent reference key of this reference key
135 * the local name of this reference key
137 public PfReferenceKey(final PfReferenceKey parentReferenceKey, final String localName) {
138 this(parentReferenceKey.getParentConceptKey(), parentReferenceKey.getLocalName(), localName);
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.
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
150 * the local name of this reference key
152 public PfReferenceKey(final PfConceptKey pfConceptKey, final String parentLocalName, final String localName) {
153 this(pfConceptKey.getName(), pfConceptKey.getVersion(), parentLocalName, localName);
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.
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
165 * the local name of this reference key
167 public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
168 this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
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.
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
182 * the local name of this reference key
184 public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
185 final String localName) {
187 this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
188 this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
190 this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
192 this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
196 * Constructor to create a key from the specified key ID.
199 * the key ID in a format that respects the KEY_ID_REGEXP
201 public PfReferenceKey(final String id) {
202 final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
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(":");
210 // Initiate the new key
211 parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
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],
222 * Get a null reference key.
224 * @return a null reference key
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);
232 public PfReferenceKey getKey() {
237 public List<PfKey> getKeys() {
238 final List<PfKey> keyList = new ArrayList<>();
239 keyList.add(getKey());
244 public String getId() {
245 return parentKeyName + ':' + parentKeyVersion + ':' + parentLocalName + ':' + localName;
249 public boolean isNullKey() {
250 return this.equals(PfReferenceKey.getNullKey());
254 * Gets the parent concept key of this reference key.
256 * @return the parent concept key of this reference key
258 public PfConceptKey getParentConceptKey() {
259 return new PfConceptKey(parentKeyName, parentKeyVersion);
263 * Gets the parent reference key of this reference key.
265 * @return the parent reference key of this reference key
267 public PfReferenceKey getParentReferenceKey() {
268 return new PfReferenceKey(parentKeyName, parentKeyVersion, parentLocalName);
272 * Sets the parent concept key of this reference key.
275 * the parent concept key of this reference key
277 public void setParentConceptKey(final PfConceptKey parentKey) {
278 Assertions.argumentNotNull(parentKey, "parentKey may not be null");
280 parentKeyName = parentKey.getName();
281 parentKeyVersion = parentKey.getVersion();
282 parentLocalName = NULL_KEY_NAME;
286 * Sets the parent reference key of this reference key.
289 * the parent reference key of this reference key
291 public void setParentReferenceKey(final PfReferenceKey parentKey) {
292 Assertions.argumentNotNull(parentKey, "parentKey may not be null");
294 parentKeyName = parentKey.getParentKeyName();
295 parentKeyVersion = parentKey.getParentKeyVersion();
296 parentLocalName = parentKey.getLocalName();
300 public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
301 if (!(otherKey instanceof PfReferenceKey)) {
302 return Compatibility.DIFFERENT;
304 final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
306 return this.getParentConceptKey().getCompatibility(otherReferenceKey.getParentConceptKey());
310 public boolean isCompatible(@NonNull final PfKey otherKey) {
311 if (!(otherKey instanceof PfReferenceKey)) {
314 final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
316 return this.getParentConceptKey().isCompatible(otherReferenceKey.getParentConceptKey());
320 public int getMajorVersion() {
321 return this.getParentConceptKey().getMajorVersion();
325 public int getMinorVersion() {
326 return this.getParentConceptKey().getMinorVersion();
330 public int getPatchVersion() {
331 return this.getParentConceptKey().getPatchVersion();
336 public boolean isNewerThan(@NonNull final PfKey otherKey) {
337 Assertions.instanceOf(otherKey, PfReferenceKey.class);
339 final PfReferenceKey otherReferenceKey = (PfReferenceKey) otherKey;
341 return this.getParentConceptKey().isNewerThan(otherReferenceKey.getParentConceptKey());
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));
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));
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));
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));
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);
386 public int compareTo(final PfConcept otherObj) {
387 Assertions.argumentNotNull(otherObj, "comparison object may not be null");
389 if (this == otherObj) {
392 if (getClass() != otherObj.getClass()) {
393 return getClass().getName().compareTo(otherObj.getClass().getName());
396 final PfReferenceKey other = (PfReferenceKey) otherObj;
397 if (!parentKeyName.equals(other.parentKeyName)) {
398 return parentKeyName.compareTo(other.parentKeyName);
400 if (!parentKeyVersion.equals(other.parentKeyVersion)) {
401 return parentKeyVersion.compareTo(other.parentKeyVersion);
403 if (!parentLocalName.equals(other.parentLocalName)) {
404 return parentLocalName.compareTo(other.parentLocalName);
406 return localName.compareTo(other.localName);