summaryrefslogtreecommitdiffstats
path: root/models-base/src/main/java/org/onap
diff options
context:
space:
mode:
authorPamela Dragosh <pdragosh@research.att.com>2019-02-28 17:30:41 +0000
committerGerrit Code Review <gerrit@onap.org>2019-02-28 17:30:41 +0000
commita8d633825a90a9199b7646e67fad559ada63b55a (patch)
tree98f16f96a2ef8ced0895ae1aaa09c021a96f15f0 /models-base/src/main/java/org/onap
parentf8a80a4b32b55f7c41a075af6141097745ba8859 (diff)
parentf240fda5e8f7e940d6033b204c2dac48a9dc7c4e (diff)
Merge "Add basic model object concepts"
Diffstat (limited to 'models-base/src/main/java/org/onap')
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfConcept.java139
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java317
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfKey.java105
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfModelException.java109
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java92
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java103
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java151
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/package-info.java25
8 files changed, 1041 insertions, 0 deletions
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java b/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
new file mode 100644
index 000000000..99eee8d7f
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConcept.java
@@ -0,0 +1,139 @@
+/*-
+ * ============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.io.Serializable;
+import java.util.List;
+
+import javax.xml.bind.annotation.XmlType;
+
+import org.onap.policy.common.utils.validation.Assertions;
+
+/**
+ * This class is the base class for all model concept classes. It enforces implementation of
+ * abstract methods and interfaces on all concepts that are sub-classes of this class.
+ */
+
+@XmlType(name = "PfConcept", namespace = "http://www.onap.org/policy/models")
+
+public abstract class PfConcept implements Serializable, Comparable<PfConcept> {
+ private static final long serialVersionUID = -7434939557282697490L;
+
+ /**
+ * Default constructor.
+ */
+ public PfConcept() {}
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public PfConcept(final PfConcept copyConcept) {
+ Assertions.argumentNotNull(copyConcept, "copy concept may not be null");
+ copyConcept.copyTo(this);
+ }
+
+ /**
+ * Gets the key of this concept.
+ *
+ * @return the concept key
+ */
+ public abstract PfKey getKey();
+
+ /**
+ * Gets a list of all keys for this concept and all concepts that are defined or referenced by
+ * this concept and its sub-concepts.
+ *
+ * @return the keys used by this concept and it's contained concepts
+ */
+ public abstract List<PfKey> getKeys();
+
+ /**
+ * Validate that this concept is structurally correct.
+ *
+ * @param result the parameter in which the result of the validation will be returned
+ * @return the validation result that was passed in in the @{link result} field with the result
+ * of this validation added
+ */
+ public abstract PfValidationResult validate(PfValidationResult result);
+
+ /**
+ * Clean this concept, tidy up any superfluous information such as leading and trailing white
+ * space.
+ */
+ public abstract void clean();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public abstract boolean equals(Object otherObject);
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public abstract String toString();
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#hashCode()
+ */
+ @Override
+ public abstract int hashCode();
+
+ /**
+ * Copy this concept to another object. The target object must have the same class as the source
+ * object.
+ *
+ * @param target the target object to which this object is copied
+ * @return the copied object
+ */
+ public abstract PfConcept copyTo(PfConcept target);
+
+ /**
+ * Gets the ID string of this concept.
+ *
+ * @return the ID string of this concept
+ */
+ public String getId() {
+ return getKey().getId();
+ }
+
+ /**
+ * Checks if this key matches the given key ID.
+ *
+ * @param id the key ID to match against
+ * @return true, if this key matches the ID
+ */
+ public final boolean matchesId(final String id) {
+ Assertions.argumentNotNull(id, "id may not be null");
+
+ // Check the ID
+ return getId().equals(id);
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java
new file mode 100644
index 000000000..6ebb8886a
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptKey.java
@@ -0,0 +1,317 @@
+/*-
+ * ============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 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.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * An artifact key uniquely identifies every first order entity in the system. Every first order
+ * concept in the system must have an {@link PfConceptKey} to identify it. Concepts that are wholly
+ * contained in another concept are identified using a {@link AxReferenceKey} key.
+ *
+ * <p>Key validation checks that the name and version fields match the NAME_REGEXP and VERSION_REGEXP
+ * regular expressions respectively.
+ */
+@Embeddable
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlRootElement(name = "pfConceptKey", namespace = "http://www.onap.org/policy/models")
+
+@XmlType(name = "PfConceptKey", namespace = "http://www.onap.org/policy/models", propOrder = {"name", "version"})
+
+public class PfConceptKey extends PfKey {
+ private static final long serialVersionUID = 8932717618579392561L;
+
+ private static final String NAME_TOKEN = "name";
+ private static final String VERSION_TOKEN = "version";
+
+ @Column(name = NAME_TOKEN)
+ @XmlElement(required = true)
+ private String name;
+
+ @Column(name = VERSION_TOKEN)
+ @XmlElement(required = true)
+ private String version;
+
+ /**
+ * The default constructor creates a null artifact key.
+ */
+ public PfConceptKey() {
+ this(NULL_KEY_NAME, NULL_KEY_VERSION);
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public PfConceptKey(final PfConceptKey copyConcept) {
+ super(copyConcept);
+ }
+
+ /**
+ * Constructor to create a key with the specified name and version.
+ *
+ * @param name the key name
+ * @param version the key version
+ */
+ public PfConceptKey(final String name, final String version) {
+ super();
+ this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ /**
+ * Constructor to create a key using the key and version from the specified key ID.
+ *
+ * @param id the key ID in a format that respects the KEY_ID_REGEXP
+ */
+ public PfConceptKey(final String id) {
+ Assertions.argumentNotNull(id, "id may not be null");
+
+ // Check the incoming ID is valid
+ Assertions.validateStringParameter("id", id, KEY_ID_REGEXP);
+
+ // Split on colon, if the id passes the regular expression test above
+ // it'll have just one colon separating the name and version
+ // No need for range checks or size checks on the array
+ final String[] nameVersionArray = id.split(":");
+
+ // Return the new key
+ name = Assertions.validateStringParameter(NAME_TOKEN, nameVersionArray[0], NAME_REGEXP);
+ version = Assertions.validateStringParameter(VERSION_TOKEN, nameVersionArray[1], VERSION_REGEXP);
+ }
+
+ /**
+ * Get a null artifact key.
+ *
+ * @return a null artifact key
+ */
+ public static final PfConceptKey getNullKey() {
+ return new PfConceptKey(PfKey.NULL_KEY_NAME, PfKey.NULL_KEY_VERSION);
+ }
+
+ @Override
+ public PfConceptKey getKey() {
+ return this;
+ }
+
+ @Override
+ public List<PfKey> getKeys() {
+ final List<PfKey> keyList = new ArrayList<>();
+ keyList.add(getKey());
+ return keyList;
+ }
+
+ @Override
+ public String getId() {
+ return name + ':' + version;
+ }
+
+ /**
+ * Gets the key name.
+ *
+ * @return the key name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Sets the key name.
+ *
+ * @param name the key name
+ */
+ public void setName(final String name) {
+ this.name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ }
+
+ /**
+ * Gets the key version.
+ *
+ * @return the key version
+ */
+ public String getVersion() {
+ return version;
+ }
+
+ /**
+ * Sets the key version.
+ *
+ * @param version the key version
+ */
+ public void setVersion(final String version) {
+ this.version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ @Override
+ public PfKey.Compatibility getCompatibility(final PfKey otherKey) {
+ if (!(otherKey instanceof PfConceptKey)) {
+ return Compatibility.DIFFERENT;
+ }
+ final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+
+ if (this.equals(otherArtifactKey)) {
+ return Compatibility.IDENTICAL;
+ }
+ if (!this.getName().equals(otherArtifactKey.getName())) {
+ return Compatibility.DIFFERENT;
+ }
+
+ final String[] thisVersionArray = getVersion().split("\\.");
+ final String[] otherVersionArray = otherArtifactKey.getVersion().split("\\.");
+
+ // There must always be at least one element in each version
+ if (!thisVersionArray[0].equals(otherVersionArray[0])) {
+ return Compatibility.MAJOR;
+ }
+
+ if (thisVersionArray.length >= 2 && otherVersionArray.length >= 2
+ && !thisVersionArray[1].equals(otherVersionArray[1])) {
+ return Compatibility.MINOR;
+ }
+
+ return Compatibility.PATCH;
+ }
+
+ @Override
+ public boolean isCompatible(final PfKey otherKey) {
+ if (!(otherKey instanceof PfConceptKey)) {
+ return false;
+ }
+ final PfConceptKey otherArtifactKey = (PfConceptKey) otherKey;
+
+ final Compatibility compatibility = this.getCompatibility(otherArtifactKey);
+
+ return !(compatibility == Compatibility.DIFFERENT || compatibility == Compatibility.MAJOR);
+ }
+
+ @Override
+ public PfValidationResult validate(final PfValidationResult result) {
+ final String nameValidationErrorMessage =
+ Assertions.getStringParameterValidationMessage(NAME_TOKEN, name, NAME_REGEXP);
+ if (nameValidationErrorMessage != null) {
+ result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "name invalid-" + nameValidationErrorMessage));
+ }
+
+ final String versionValidationErrorMessage =
+ Assertions.getStringParameterValidationMessage(VERSION_TOKEN, version, VERSION_REGEXP);
+ if (versionValidationErrorMessage != null) {
+ result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
+ "version invalid-" + versionValidationErrorMessage));
+ }
+
+ return result;
+ }
+
+ @Override
+ public void clean() {
+ name = Assertions.validateStringParameter(NAME_TOKEN, name, NAME_REGEXP);
+ version = Assertions.validateStringParameter(VERSION_TOKEN, version, VERSION_REGEXP);
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(this.getClass().getSimpleName());
+ builder.append(":(");
+ builder.append("name=");
+ builder.append(name);
+ builder.append(",version=");
+ builder.append(version);
+ builder.append(")");
+ return builder.toString();
+ }
+
+ @Override
+ public PfConcept copyTo(final PfConcept target) {
+ Assertions.argumentNotNull(target, "target may not be null");
+
+ final PfConcept copyObject = target;
+ Assertions.instanceOf(copyObject, PfConceptKey.class);
+
+ final PfConceptKey copy = ((PfConceptKey) copyObject);
+ copy.setName(name);
+ copy.setVersion(version);
+
+ return copyObject;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + name.hashCode();
+ result = prime * result + version.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final PfConceptKey other = (PfConceptKey) obj;
+
+ if (!name.equals(other.name)) {
+ return false;
+ }
+ return version.equals(other.version);
+ }
+
+ @Override
+ public int compareTo(final PfConcept otherObj) {
+ Assertions.argumentNotNull(otherObj, "comparison object may not be null");
+
+ if (this == otherObj) {
+ return 0;
+ }
+ if (getClass() != otherObj.getClass()) {
+ return this.hashCode() - otherObj.hashCode();
+ }
+
+ final PfConceptKey other = (PfConceptKey) otherObj;
+
+ if (!name.equals(other.name)) {
+ return name.compareTo(other.name);
+ }
+ return version.compareTo(other.version);
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
new file mode 100644
index 000000000..16e70a2c0
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfKey.java
@@ -0,0 +1,105 @@
+/*-
+ * ============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;
+
+/**
+ * The key uniquely identifies every entity in the system. This class is an abstract class to give a
+ * common parent for all key types in the system.
+ */
+public abstract class PfKey extends PfConcept {
+ private static final long serialVersionUID = 6281159885962014041L;
+
+ /** Regular expression to specify the structure of key names. */
+ public static final String NAME_REGEXP = "[A-Za-z0-9\\-_\\.]+";
+
+ /** Regular expression to specify the structure of key versions. */
+ public static final String VERSION_REGEXP = "[A-Za-z0-9.]+";
+
+ /** Regular expression to specify the structure of key IDs. */
+ public static final String KEY_ID_REGEXP = "[A-Za-z0-9\\-_\\.]+:[0-9].[0-9].[0-9]";
+
+ /** Specifies the value for names in NULL keys. */
+ public static final String NULL_KEY_NAME = "NULL";
+
+ /** Specifies the value for versions in NULL keys. */
+ public static final String NULL_KEY_VERSION = "0.0.0";
+
+ /**
+ * This enumeration is returned on key compatibility checks.
+ */
+ public enum Compatibility {
+ /** The keys have different names. */
+ DIFFERENT,
+ /**
+ * The name of the key matches but the Major version number of the keys is different (x in
+ * x.y.z do not match).
+ */
+ MAJOR,
+ /**
+ * The name of the key matches but the Minor version number of the keys is different (y in
+ * x.y.z do not match).
+ */
+ MINOR,
+ /**
+ * The name of the key matches but the Patch version number of the keys is different (z in
+ * x.y.z do not match).
+ */
+ PATCH,
+ /** The keys match completely. */
+ IDENTICAL
+ }
+
+ /**
+ * Default constructor.
+ */
+ public PfKey() {
+ super();
+ }
+
+ /**
+ * Copy constructor.
+ *
+ * @param copyConcept the concept to copy from
+ */
+ public PfKey(final PfKey copyConcept) {
+ super(copyConcept);
+ }
+
+ @Override
+ public abstract String getId();
+
+ /**
+ * Return the result of a compatibility check of two keys.
+ *
+ * @param otherKey the key to check compatibility against
+ * @return the compatibility result of the check
+ */
+ public abstract Compatibility getCompatibility(PfKey otherKey);
+
+ /**
+ * Check if two keys are compatible, that is the keys are IDENTICAL or have only MINOR, PATCH
+ * differences.
+ *
+ * @param otherKey the key to check compatibility against
+ * @return true, if the keys are compatible
+ */
+ public abstract boolean isCompatible(PfKey otherKey);
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java
new file mode 100644
index 000000000..3d1bb1794
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelException.java
@@ -0,0 +1,109 @@
+/*-
+ * ============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;
+
+/**
+ * This class is a base exception from which all model exceptions are sub classes.
+ */
+public class PfModelException extends Exception {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ // The object on which the exception was thrown
+ private final transient Object object;
+
+ /**
+ * Instantiates a new model exception.
+ *
+ * @param message the message on the exception
+ */
+ public PfModelException(final String message) {
+ this(message, null);
+ }
+
+ /**
+ * Instantiates a new model exception.
+ *
+ * @param message the message on the exception
+ * @param object the object that the exception was thrown on
+ */
+ public PfModelException(final String message, final Object object) {
+ super(message);
+ this.object = object;
+ }
+
+ /**
+ * Instantiates a new model exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this exception
+ */
+ public PfModelException(final String message, final Exception exception) {
+ this(message, exception, null);
+ }
+
+ /**
+ * Instantiates a new exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this exception
+ * @param object the object that the exception was thrown on
+ */
+ public PfModelException(final String message, final Exception exception, final Object object) {
+ super(message, exception);
+ this.object = object;
+ }
+
+ /**
+ * Get the message from this exception and its causes.
+ *
+ * @return the cascaded messages from this exception and the exceptions that caused it
+ */
+ public String getCascadedMessage() {
+ return buildCascadedMessage(this);
+ }
+
+ /**
+ * Build a cascaded message from an exception and all its nested exceptions.
+ *
+ * @param throwable the top level exception
+ * @return cascaded message string
+ */
+ public static String buildCascadedMessage(Throwable throwable) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append(throwable.getMessage());
+
+ for (Throwable t = throwable; t != null; t = t.getCause()) {
+ builder.append("\ncaused by: ");
+ builder.append(t.getMessage());
+ }
+
+ return builder.toString();
+ }
+
+ /**
+ * Get the object on which the exception was thrown.
+ *
+ * @return The object on which the exception was thrown
+ */
+ public Object getObject() {
+ return object;
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java b/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java
new file mode 100644
index 000000000..0780a9e20
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfModelRuntimeException.java
@@ -0,0 +1,92 @@
+/*-
+ * ============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;
+
+/**
+ * This class is a base model run time exception from which all model run time exceptions are sub
+ * classes.
+ */
+public class PfModelRuntimeException extends RuntimeException {
+ private static final long serialVersionUID = -8507246953751956974L;
+
+ // The object on which the exception was thrown
+ private final transient Object object;
+
+ /**
+ * Instantiates a new model runtime exception.
+ *
+ * @param message the message on the exception
+ */
+ public PfModelRuntimeException(final String message) {
+ this(message, null);
+ }
+
+ /**
+ * Instantiates a new model runtime exception.
+ *
+ * @param message the message on the exception
+ * @param object the object that the exception was thrown on
+ */
+ public PfModelRuntimeException(final String message, final Object object) {
+ super(message);
+ this.object = object;
+ }
+
+ /**
+ * Instantiates a new model runtime exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this model exception
+ */
+ public PfModelRuntimeException(final String message, final Exception exception) {
+ this(message, exception, null);
+ }
+
+ /**
+ * Instantiates a new model runtime exception.
+ *
+ * @param message the message on the exception
+ * @param exception the exception that caused this model exception
+ * @param object the object that the exception was thrown on
+ */
+ public PfModelRuntimeException(final String message, final Exception exception, final Object object) {
+ super(message, exception);
+ this.object = object;
+ }
+
+ /**
+ * Get the message from this exception and its causes.
+ *
+ * @return the message of this exception and all the exceptions that caused this exception
+ */
+ public String getCascadedMessage() {
+ return PfModelException.buildCascadedMessage(this);
+ }
+
+ /**
+ * Get the object on which the exception was thrown.
+ *
+ * @return The object
+ */
+ public Object getObject() {
+ return object;
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java b/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java
new file mode 100644
index 000000000..708bfddfb
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java
@@ -0,0 +1,103 @@
+/*-
+ * ============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 org.onap.policy.common.utils.validation.Assertions;
+import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+
+/**
+ * A validation message is created for each validation observation observed during validation of a
+ * concept. The message holds the key and the class of the concept on which the observation was made
+ * as well as the type of observation and a message describing the observation.
+ */
+public class PfValidationMessage {
+ private final PfKey observedKey;
+ private ValidationResult validationResult = ValidationResult.VALID;
+ private final String observedClass;
+ private final String message;
+
+ /**
+ * Create an validation observation with the given fields.
+ *
+ * @param observedKey the key of the class on which the validation observation was made
+ * @param observedClass the class on which the validation observation was made
+ * @param validationResult the type of observation made
+ * @param message a message describing the observation
+ */
+ public PfValidationMessage(final PfKey observedKey, final Class<?> observedClass,
+ final ValidationResult validationResult, final String message) {
+ Assertions.argumentNotNull(observedKey, "observedKey may not be null");
+ Assertions.argumentNotNull(observedClass, "observedClass may not be null");
+ Assertions.argumentNotNull(validationResult, "validationResult may not be null");
+ Assertions.argumentNotNull(message, "message may not be null");
+
+ this.observedKey = observedKey;
+ this.observedClass = observedClass.getCanonicalName();
+ this.validationResult = validationResult;
+ this.message = message;
+ }
+
+ /**
+ * Gets the key of the observation.
+ *
+ * @return the key of the observation
+ */
+ public PfKey getObservedKey() {
+ return observedKey;
+ }
+
+ /**
+ * Gets the observed class.
+ *
+ * @return the observed class
+ */
+ public String getObservedClass() {
+ return observedClass;
+ }
+
+ /**
+ * Gets the type of observation made.
+ *
+ * @return the type of observation made
+ */
+ public ValidationResult getValidationResult() {
+ return validationResult;
+ }
+
+ /**
+ * Get a description of the observation.
+ *
+ * @return the observation description
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ return observedKey.toString() + ':' + observedClass + ':' + validationResult.name() + ':' + message;
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java b/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java
new file mode 100644
index 000000000..284c11ac2
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java
@@ -0,0 +1,151 @@
+/*-
+ * ============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.LinkedList;
+import java.util.List;
+
+/**
+ * This class records the result of a validation and holds all validatino observation messages.
+ */
+public class PfValidationResult {
+ /**
+ * The ValidationResult enumeration describes the severity of a validation result.
+ */
+ public enum ValidationResult {
+ /** No problems or observations were detected during validation. */
+ VALID,
+ /**
+ * Observations were made on a concept (such as blank descriptions) of a nature that will not
+ * affect the use of the concept.
+ */
+ OBSERVATION,
+ /**
+ * Warnings were made on a concept (such as defined but unused concepts) of a nature that may
+ * affect the use of the concept.
+ */
+ WARNING,
+ /**
+ * Errors were detected on a concept (such as referenced but undefined concepts) of a nature
+ * that will affect the use of the concept.
+ */
+ INVALID
+ }
+
+ // The actual verification result
+ private ValidationResult validationResult = ValidationResult.VALID;
+
+ // Messages collected during the verification process
+ private final List<PfValidationMessage> messageList = new LinkedList<>();
+
+ /**
+ * Check if a validation reported a valid concept, returns true if the model is usable (that is,
+ * even if the model has warnings or observations).
+ *
+ * @return true, if the concept is reported as valid and can be used
+ */
+ public boolean isValid() {
+ return validationResult != ValidationResult.INVALID;
+ }
+
+ /**
+ * Check if a validation reported a concept with no errors or warnings, returns true if the
+ * model is OK to use.
+ *
+ * @return true, if the concept has no warnings or errors
+ */
+ public boolean isOk() {
+ return validationResult == ValidationResult.VALID || validationResult == ValidationResult.OBSERVATION;
+ }
+
+ /**
+ * Gets the validation result.
+ *
+ * @return the validation result on a concept
+ */
+ public ValidationResult getValidationResult() {
+ return validationResult;
+ }
+
+ /**
+ * Gets the list of validation results on the concept.
+ *
+ * @return the list of validaiton results
+ */
+ public List<PfValidationMessage> getMessageList() {
+ return messageList;
+ }
+
+ /**
+ * Adds a validation message to the validation result, used by validate() implementations on
+ * {@link PfConcept} subclasses to report validaiton observations.
+ *
+ * @param validationMessage the validation message
+ */
+ public void addValidationMessage(final PfValidationMessage validationMessage) {
+ messageList.add(validationMessage);
+
+ // Check if the incoming message has a more sever status than the
+ // current one on the overall validation result,
+ // if so, the overall result goes to that level
+ if (validationMessage.getValidationResult().ordinal() > validationResult.ordinal()) {
+ validationResult = validationMessage.getValidationResult();
+ }
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see java.lang.Object#toString()
+ */
+ @Override
+ public String toString() {
+ final StringBuilder builder = new StringBuilder();
+
+ switch (validationResult) {
+ case VALID:
+
+ builder.append("***validation of model successful***");
+ return builder.toString();
+ case OBSERVATION:
+
+ builder.append("\n***observations noted during validation of model***\n");
+ break;
+ case WARNING:
+
+ builder.append("\n***warnings issued during validation of model***\n");
+ break;
+ case INVALID:
+ builder.append("\n***validation of model failed***\n");
+ break;
+ default:
+ break;
+ }
+
+ for (final PfValidationMessage message : messageList) {
+ builder.append(message);
+ builder.append("\n");
+ }
+
+ builder.append("********************************");
+ return builder.toString();
+ }
+}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/package-info.java b/models-base/src/main/java/org/onap/policy/models/base/package-info.java
new file mode 100644
index 000000000..a71dce6ff
--- /dev/null
+++ b/models-base/src/main/java/org/onap/policy/models/base/package-info.java
@@ -0,0 +1,25 @@
+/*-
+ * ============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=========================================================
+ */
+
+/**
+ * Defines and implements the basic concepts for all models in the Policy Framework.
+ */
+
+package org.onap.policy.models.base;