/*- * ============LICENSE_START======================================================= * Copyright (C) 2019 Nordix Foundation. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * SPDX-License-Identifier: Apache-2.0 * ============LICENSE_END========================================================= */ package org.onap.policy.models.base; import java.util.ArrayList; import java.util.List; import javax.persistence.Column; import javax.persistence.Embeddable; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.NonNull; import org.onap.policy.common.utils.validation.Assertions; import org.onap.policy.models.base.PfValidationResult.ValidationResult; /** * A reference key identifies entities in the system that are contained in other entities. Every contained concept in * the system must have an {@link PfReferenceKey} to identify it. Non-contained first order concepts are identified * using an {@link PfConceptKey} key. * *
An {@link PfReferenceKey} contains an {@link PfConceptKey} key reference to the first order entity that contains * it. The local name of the reference key must uniquely identify the referenced concept among those concepts contained * in the reference key's parent. In other words, if a parent concept has more than one child, the local name in the key * of all its children must be unique. * *
If a reference key's parent is itself a reference key, then the parent's local name must be set in the reference * key. If the parent is a first order concept, then the parent's local name in the key will be set to NULL. * *
Key validation checks that the parent name and parent version fields match the NAME_REGEXP and
* VERSION_REGEXP regular expressions respectively and that the local name fields match the
* LOCAL_NAME_REGEXP regular expression.
*/
@Embeddable
@Data
@EqualsAndHashCode(callSuper = false)
public class PfReferenceKey extends PfKey {
private static final String PARENT_KEY_NAME = "parentKeyName";
private static final String PARENT_KEY_VERSION = "parentKeyVersion";
private static final String PARENT_LOCAL_NAME = "parentLocalName";
private static final String LOCAL_NAME = "localName";
private static final long serialVersionUID = 8932717618579392561L;
/** Regular expression to specify the structure of local names in reference keys. */
public static final String LOCAL_NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+|^$";
/** Regular expression to specify the structure of IDs in reference keys. */
public static final String REFERENCE_KEY_ID_REGEXP =
"[A-Za-z0-9\\-_]+:[0-9].[0-9].[0-9]:[A-Za-z0-9\\-_]+:[A-Za-z0-9\\-_]+";
private static final int PARENT_NAME_FIELD = 0;
private static final int PARENT_VERSION_FIELD = 1;
private static final int PARENT_LOCAL_NAME_FIELD = 2;
private static final int LOCAL_NAME_FIELD = 3;
@Column(name = PARENT_KEY_NAME, length = 120)
private String parentKeyName;
@Column(name = PARENT_KEY_VERSION, length = 15)
private String parentKeyVersion;
@Column(name = PARENT_LOCAL_NAME, length = 120)
private String parentLocalName;
@Column(name = LOCAL_NAME, length = 120)
private String localName;
/**
* The default constructor creates a null reference key.
*/
public PfReferenceKey() {
this(NULL_KEY_NAME, NULL_KEY_VERSION, NULL_KEY_NAME, NULL_KEY_NAME);
}
/**
* The Copy Constructor creates a key by copying another key.
*
* @param referenceKey
* the reference key to copy from
*/
public PfReferenceKey(final PfReferenceKey referenceKey) {
this(referenceKey.getParentKeyName(), referenceKey.getParentKeyVersion(), referenceKey.getParentLocalName(),
referenceKey.getLocalName());
}
/**
* Constructor to create a null reference key for the specified parent concept key.
*
* @param pfConceptKey
* the parent concept key of this reference key
*/
public PfReferenceKey(final PfConceptKey pfConceptKey) {
this(pfConceptKey.getName(), pfConceptKey.getVersion(), NULL_KEY_NAME, NULL_KEY_NAME);
}
/**
* Constructor to create a reference key for the given parent concept key with the given local name.
*
* @param pfConceptKey
* the parent concept key of this reference key
* @param localName
* the local name of this reference key
*/
public PfReferenceKey(final PfConceptKey pfConceptKey, final String localName) {
this(pfConceptKey, NULL_KEY_NAME, localName);
}
/**
* Constructor to create a reference key for the given parent reference key with the given local name.
*
* @param parentReferenceKey
* the parent reference key of this reference key
* @param localName
* the local name of this reference key
*/
public PfReferenceKey(final PfReferenceKey parentReferenceKey, final String localName) {
this(parentReferenceKey.getParentConceptKey(), parentReferenceKey.getLocalName(), localName);
}
/**
* Constructor to create a reference key for the given parent reference key (specified by the parent reference key's
* concept key and local name) with the given local name.
*
* @param pfConceptKey
* the concept key of the parent reference key of this reference key
* @param parentLocalName
* the local name of the parent reference key of this reference key
* @param localName
* the local name of this reference key
*/
public PfReferenceKey(final PfConceptKey pfConceptKey, final String parentLocalName, final String localName) {
this(pfConceptKey.getName(), pfConceptKey.getVersion(), parentLocalName, localName);
}
/**
* Constructor to create a reference key for the given parent concept key (specified by the parent concept key's
* name and version) with the given local name.
*
* @param parentKeyName
* the name of the parent concept key of this reference key
* @param parentKeyVersion
* the version of the parent concept key of this reference key
* @param localName
* the local name of this reference key
*/
public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String localName) {
this(parentKeyName, parentKeyVersion, NULL_KEY_NAME, localName);
}
/**
* Constructor to create a reference key for the given parent key (specified by the parent key's name, version nad
* local name) with the given local name.
*
* @param parentKeyName
* the parent key name of this reference key
* @param parentKeyVersion
* the parent key version of this reference key
* @param parentLocalName
* the parent local name of this reference key
* @param localName
* the local name of this reference key
*/
public PfReferenceKey(final String parentKeyName, final String parentKeyVersion, final String parentLocalName,
final String localName) {
super();
this.parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP);
this.parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION, parentKeyVersion,
VERSION_REGEXP);
this.parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME, parentLocalName,
LOCAL_NAME_REGEXP);
this.localName = Assertions.validateStringParameter(LOCAL_NAME, localName, LOCAL_NAME_REGEXP);
}
/**
* Constructor to create a key from the specified key ID.
*
* @param id
* the key ID in a format that respects the KEY_ID_REGEXP
*/
public PfReferenceKey(final String id) {
final String conditionedId = Assertions.validateStringParameter("id", id, REFERENCE_KEY_ID_REGEXP);
// Split on colon, if the id passes the regular expression test above
// it'll have just three colons separating the parent name,
// parent version, parent local name, and and local name
// No need for range checks or size checks on the array
final String[] nameVersionNameArray = conditionedId.split(":");
// Initiate the new key
parentKeyName = Assertions.validateStringParameter(PARENT_KEY_NAME, nameVersionNameArray[PARENT_NAME_FIELD],
NAME_REGEXP);
parentKeyVersion = Assertions.validateStringParameter(PARENT_KEY_VERSION,
nameVersionNameArray[PARENT_VERSION_FIELD], VERSION_REGEXP);
parentLocalName = Assertions.validateStringParameter(PARENT_LOCAL_NAME,
nameVersionNameArray[PARENT_LOCAL_NAME_FIELD], LOCAL_NAME_REGEXP);
localName = Assertions.validateStringParameter(LOCAL_NAME, nameVersionNameArray[LOCAL_NAME_FIELD],
LOCAL_NAME_REGEXP);
}
/**
* Get a null reference key.
*
* @return a null reference key
*/
public static PfReferenceKey getNullKey() {
return new PfReferenceKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION, PfKey.NULL_KEY_NAME,
PfKey.NULL_KEY_NAME);
}
@Override
public PfReferenceKey getKey() {
return this;
}
@Override
public List