aboutsummaryrefslogtreecommitdiffstats
path: root/model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java
diff options
context:
space:
mode:
Diffstat (limited to 'model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java')
-rw-r--r--model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java471
1 files changed, 471 insertions, 0 deletions
diff --git a/model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java b/model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java
new file mode 100644
index 000000000..f0489c734
--- /dev/null
+++ b/model/basic-model/src/main/java/org/onap/apex/model/basicmodel/concepts/AxModel.java
@@ -0,0 +1,471 @@
+/*
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ * ================================================================================
+ * 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.apex.model.basicmodel.concepts;
+
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.persistence.CascadeType;
+import javax.persistence.EmbeddedId;
+import javax.persistence.Entity;
+import javax.persistence.Inheritance;
+import javax.persistence.InheritanceType;
+import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.apex.model.basicmodel.concepts.AxValidationResult.ValidationResult;
+import org.onap.apex.model.basicmodel.service.ModelService;
+import org.onap.policy.apex.model.utilities.Assertions;
+
+/**
+ * This class is the base class for all models in Apex. All model classes inherit from this model so all models must have a key and have key information.
+ * <p>
+ * Validation checks that the model key is valid. It goes on to check for null keys and checks each key for uniqueness in the model. A check is carried out to
+ * ensure that an {@link AxKeyInfo} instance exists for every {@link AxArtifactKey} key. For each {@link AxReferenceKey} instance, a check is made that its
+ * parent and local name are nut null and that a {@link AxKeyInfo} entry exists for its parent. Then a check is made that each used {@link AxArtifactKey} and
+ * {@link AxReferenceKey} usage references a key that exists. Finally, a check is made to ensure that an {@link AxArtifactKey} instance exists for every
+ * {@link AxKeyInfo} instance.
+ */
+
+@Entity
+@Table(name = "AxModel")
+@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+
+@XmlRootElement(name = "apexModel", namespace = "http://www.ericsson.com/apex")
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "AxModel", namespace = "http://www.ericsson.com/apex", propOrder = { "key", "keyInformation" })
+
+public class AxModel extends AxConcept {
+ private static final String IS_A_NULL_KEY = " is a null key";
+
+ private static final long serialVersionUID = -771659065637205430L;
+
+ @EmbeddedId
+ @XmlElement(name = "key", required = true)
+ private AxArtifactKey key;
+
+ // @formatter:off
+ @OneToOne(cascade = CascadeType.ALL)
+ @JoinColumns({
+ @JoinColumn(name = "keyInformationName", referencedColumnName = "name"),
+ @JoinColumn(name = "keyInformationVersion", referencedColumnName = "version")
+ })
+ @XmlElement(name = "keyInformation", required = true)
+ private AxKeyInformation keyInformation;
+ // @formatter:on
+
+ /**
+ * The Default Constructor creates this concept with a NULL artifact key.
+ */
+ public AxModel() {
+ this(new AxArtifactKey());
+ }
+
+ /**
+ * Copy constructor
+ * @param copyConcept the concept to copy from
+ */
+ public AxModel(final AxModel copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create this concept with the specified key.
+ *
+ * @param key the key of this concept
+ */
+ public AxModel(final AxArtifactKey key) {
+ this(key, new AxKeyInformation(new AxArtifactKey(key.getName() + "_KeyInfo", key.getVersion())));
+ }
+
+ /**
+ * Constructor to create this concept and set all its fields.
+ *
+ * @param key the key of this concept
+ * @param keyInformation the key information of this concept
+ */
+ public AxModel(final AxArtifactKey key, final AxKeyInformation keyInformation) {
+ super();
+ Assertions.argumentNotNull(key, "key may not be null");
+ Assertions.argumentNotNull(keyInformation, "keyInformation may not be null");
+
+ this.key = key;
+ this.keyInformation = keyInformation;
+ }
+
+ /**
+ * Registers this model with the {@link ModelService}. All models are registered with the model service so that models can be references from anywhere in
+ * the Apex system without being passed as references through deep call chains.
+ */
+ public void register() {
+ ModelService.registerModel(AxKeyInformation.class, getKeyInformation());
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKey()
+ */
+ @Override
+ public AxArtifactKey getKey() {
+ return key;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#getKeys()
+ */
+ @Override
+ public List<AxKey> getKeys() {
+ final List<AxKey> keyList = key.getKeys();
+
+ // We just add the key for the KeyInformation itself. We don't add the
+ // keys from key information because
+ // that is a list of key information for existing keys
+ keyList.add(keyInformation.getKey());
+
+ return keyList;
+ }
+
+ /**
+ * Sets the key of this concept.
+ *
+ * @param key the key of this concept
+ */
+ public void setKey(final AxArtifactKey key) {
+ Assertions.argumentNotNull(key, "key may not be null");
+ this.key = key;
+ }
+
+ /**
+ * Gets the key information of this concept.
+ *
+ * @return the key information of this concept
+ */
+ public AxKeyInformation getKeyInformation() {
+ return keyInformation;
+ }
+
+ /**
+ * Sets the key information of this concept.
+ *
+ * @param keyInformation the key information of this concept
+ */
+ public void setKeyInformation(final AxKeyInformation keyInformation) {
+ Assertions.argumentNotNull(keyInformation, "keyInformation may not be null");
+ this.keyInformation = keyInformation;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#validate(com. ericsson.apex.model.basicmodel.concepts.AxValidationResult)
+ */
+ @Override
+ public AxValidationResult validate(final AxValidationResult resultIn) {
+ AxValidationResult result = resultIn;
+
+ if (key.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
+ }
+
+ result = key.validate(result);
+ result = keyInformation.validate(result);
+
+ // Key consistency check
+ final Set<AxArtifactKey> artifactKeySet = new TreeSet<>();
+ final Set<AxReferenceKey> referenceKeySet = new TreeSet<>();
+ final Set<AxKeyUse> usedKeySet = new TreeSet<>();
+
+ for (final AxKey axKey : this.getKeys()) {
+ // Check for the two type of keys we have
+ if (axKey instanceof AxArtifactKey) {
+ result = validateArtifactKeyInModel((AxArtifactKey) axKey, artifactKeySet, result);
+ }
+ else if (axKey instanceof AxReferenceKey) {
+ result = validateReferenceKeyInModel((AxReferenceKey) axKey, referenceKeySet, result);
+ }
+ // It must be an AxKeyUse, nothing else is legal
+ else {
+ usedKeySet.add((AxKeyUse) axKey);
+ }
+ }
+
+ // Check all reference keys have correct parent keys
+ for (final AxReferenceKey referenceKey : referenceKeySet) {
+ if (!artifactKeySet.contains(referenceKey.getParentArtifactKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent artifact key not found for reference key " + referenceKey));
+ }
+ }
+
+ result = validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result);
+
+ // Check key information for unused key information
+ for (final AxArtifactKey keyInfoKey : keyInformation.getKeyInfoMap().keySet()) {
+ if (!artifactKeySet.contains(keyInfoKey)) {
+ result.addValidationMessage(
+ new AxValidationMessage(keyInfoKey, this.getClass(), ValidationResult.WARNING, "key not found for key information entry"));
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of an artifact key in the model
+ * @param artifactKey The artifact key to check
+ * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateArtifactKeyInModel(final AxArtifactKey artifactKey, Set<AxArtifactKey> artifactKeySet, AxValidationResult result) {
+ // Null key check
+ if (artifactKey.equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key " + artifactKey + IS_A_NULL_KEY));
+ }
+
+ // Null key name start check
+ if (artifactKey.getName().toUpperCase().startsWith(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + artifactKey + " name starts with keyword " + AxKey.NULL_KEY_NAME));
+ }
+
+ // Unique key check
+ if (artifactKeySet.contains(artifactKey)) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "duplicate key " + artifactKey + " found"));
+ }
+ else {
+ artifactKeySet.add(artifactKey);
+ }
+
+ // Key information check
+ if (!keyInformation.getKeyInfoMap().containsKey(artifactKey)) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key information not found for key " + artifactKey));
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of a reference key in the model
+ * @param artifactKey The reference key to check
+ * @param referenceKeySet The set of reference keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateReferenceKeyInModel(final AxReferenceKey referenceKey, Set<AxReferenceKey> referenceKeySet, AxValidationResult result) {
+ // Null key check
+ if (referenceKey.equals(AxReferenceKey.getNullKey())) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key " + referenceKey + IS_A_NULL_KEY));
+ }
+
+ // Null parent key check
+ if (referenceKey.getParentArtifactKey().equals(AxArtifactKey.getNullKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "parent artifact key of key " + referenceKey + IS_A_NULL_KEY));
+ }
+
+ // Null local name check
+ if (referenceKey.getLocalName().equals(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key " + referenceKey + " has a null local name"));
+ }
+
+ // Null key name start check
+ if (referenceKey.getParentArtifactKey().getName().toUpperCase().startsWith(AxKey.NULL_KEY_NAME)) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key " + referenceKey + " parent name starts with keyword " + AxKey.NULL_KEY_NAME));
+ }
+
+ // Unique key check
+ if (referenceKeySet.contains(referenceKey)) {
+ result.addValidationMessage(
+ new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID, "duplicate key " + referenceKey + " found"));
+ }
+ else {
+ referenceKeySet.add(referenceKey);
+ }
+
+ // Key information check
+ if (!keyInformation.getKeyInfoMap().containsKey(referenceKey.getParentArtifactKey())) {
+ result.addValidationMessage(new AxValidationMessage(key, this.getClass(), ValidationResult.INVALID,
+ "key information not found for parent key of key " + referenceKey));
+ }
+
+ return result;
+ }
+
+ /**
+ * Check for consistent usage of cross-key references in the model
+ * @param usedKeySet The set of all keys used in the model
+ * @param artifactKeySet The set of artifact keys encountered so far, this key is appended to the set
+ * @param referenceKeySet The set of reference keys encountered so far, this key is appended to the set
+ * @param result The validation result to append to
+ * @return the result of the validation
+ */
+ private AxValidationResult validateKeyUses(final Set<AxKeyUse> usedKeySet, final Set<AxArtifactKey> artifactKeySet,
+ final Set<AxReferenceKey> referenceKeySet, AxValidationResult result) {
+ // Check all key uses
+ for (final AxKeyUse usedKey : usedKeySet) {
+ if (usedKey.getKey() instanceof AxArtifactKey) {
+ // AxArtifact key usage, check the key exists
+ if (!artifactKeySet.contains(usedKey.getKey())) {
+ result.addValidationMessage(new AxValidationMessage(usedKey.getKey(), this.getClass(), ValidationResult.INVALID,
+ "an artifact key used in the model is not defined"));
+ }
+ }
+ else {
+ // AxReference key usage, check the key exists
+ if (!referenceKeySet.contains(usedKey.getKey())) {
+ result.addValidationMessage(new AxValidationMessage(usedKey.getKey(), this.getClass(), ValidationResult.INVALID,
+ "a reference key used in the model is not defined"));
+ }
+ }
+ }
+
+ return result;
+ }
+
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#clean()
+ */
+ @Override
+ public void clean() {
+ key.clean();
+ keyInformation.clean();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("key=");
+ builder.append(key);
+ builder.append(",keyInformation=");
+ builder.append(keyInformation);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#copyTo(com.ericsson.apex.model.basicmodel.concepts.AxConcept)
+ */
+ @Override
+ public AxConcept copyTo(final AxConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final Object copyObject = target;
+ Assertions.instanceOf(copyObject, AxModel.class);
+
+ final AxModel copy = ((AxModel) copyObject);
+ copy.setKey(new AxArtifactKey(key));
+ copy.setKeyInformation(new AxKeyInformation(keyInformation));
+
+ return copy;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + key.hashCode();
+ result = prime * result + keyInformation.hashCode();
+ return result;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see com.ericsson.apex.model.basicmodel.concepts.AxConcept#equals(java.lang. Object)
+ */
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final AxModel other = (AxModel) obj;
+ if (!key.equals(other.key)) {
+ return false;
+ }
+ return keyInformation.equals(other.keyInformation);
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Comparable#compareTo(java.lang.Object)
+ */
+ @Override
+ public int compareTo(final AxConcept otherObj) {
+ if (otherObj == null) {
+ return -1;
+ }
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final AxModel other = (AxModel) otherObj;
+ if (!key.equals(other.key)) {
+ return key.compareTo(other.key);
+ }
+ return keyInformation.compareTo(other.keyInformation);
+ }
+}