Java 17 Upgrade
[policy/models.git] / models-base / src / main / java / org / onap / policy / models / base / PfModel.java
index 3dc233b..1caa632 100644 (file)
@@ -1,6 +1,8 @@
 /*-
  * ============LICENSE_START=======================================================
- *  Copyright (C) 2019 Nordix Foundation.
+ *  Copyright (C) 2019, 2023 Nordix Foundation.
+ *  Modifications Copyright (C) 2019-2021 AT&T Intellectual Property. All rights reserved.
+ *  Modifications Copyright (C) 2022 Bell Canada. 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.
 
 package org.onap.policy.models.base;
 
+import jakarta.persistence.EmbeddedId;
+import jakarta.persistence.MappedSuperclass;
+import java.io.Serial;
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
-
-import javax.persistence.EmbeddedId;
-import javax.persistence.Entity;
-import javax.persistence.Inheritance;
-import javax.persistence.InheritanceType;
-import javax.persistence.Table;
-
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.NonNull;
-
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
+import org.onap.policy.common.parameters.annotations.NotNull;
 import org.onap.policy.common.utils.validation.Assertions;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+import org.onap.policy.models.base.validation.annotations.VerifyKey;
 
 /**
  * This class is the base class for all models in the Policy Framework. 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 PfKeyInfo}
+ * each key for uniqueness in the model. A check is carried out to ensure that an {@link PfKey}
  * instance exists for every {@link PfConceptKey} key. For each {@link PfReferenceKey} instance, a
- * check is made that its parent and local name are nut null and that a {@link PfKeyInfo} entry
+ * check is made that its parent and local name are not null and that a {@link PfKey} entry
  * exists for its parent. Then a check is made that each used {@link PfConceptKey} and
  * {@link PfReferenceKey} usage references a key that exists. Finally, a check is made to ensure
- * that an {@link PfConceptKey} instance exists for every {@link PfKeyInfo} instance.
+ * that an {@link PfConceptKey} instance exists for every {@link PfKey} instance.
  *
  * @param <C> the type of concept on which the interface is applied.
  */
 
-@Entity
-@Table(name = "PfModel")
-@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
+@MappedSuperclass
 @Data
 @EqualsAndHashCode(callSuper = false)
 public abstract class PfModel extends PfConcept {
-    private static final String IS_A_NULL_KEY = " is a null key";
+    private static final String KEYS_TOKEN = "keys";
 
+    @Serial
     private static final long serialVersionUID = -771659065637205430L;
 
     @EmbeddedId
+    @VerifyKey
+    @NotNull
     private PfConceptKey key;
 
     /**
      * The Default Constructor creates this concept with a NULL artifact key.
      */
-    public PfModel() {
+    protected PfModel() {
         this(new PfConceptKey());
     }
 
@@ -77,7 +78,7 @@ public abstract class PfModel extends PfConcept {
      *
      * @param key the key of this concept
      */
-    public PfModel(@NonNull final PfConceptKey key) {
+    protected PfModel(@NonNull final PfConceptKey key) {
         super();
         Assertions.argumentNotNull(key, "key may not be null");
 
@@ -89,8 +90,9 @@ public abstract class PfModel extends PfConcept {
      *
      * @param copyConcept the concept to copy from
      */
-    public PfModel(@NonNull final PfModel copyConcept) {
+    protected PfModel(@NonNull final PfModel copyConcept) {
         super(copyConcept);
+        this.key = new PfConceptKey(copyConcept.key);
     }
 
     /**
@@ -111,15 +113,8 @@ public abstract class PfModel extends PfConcept {
     }
 
     @Override
-    public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
-        PfValidationResult result = resultIn;
-
-        if (key.isNullKey()) {
-            result.addValidationMessage(
-                    new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
-        }
-
-        result = key.validate(result);
+    public BeanValidationResult validate(@NonNull String fieldName) {
+        BeanValidationResult result = new PfValidator().validateTop(fieldName, this);
 
         // Key consistency check
         final Set<PfConceptKey> artifactKeySet = new TreeSet<>();
@@ -129,12 +124,11 @@ public abstract class PfModel extends PfConcept {
         for (final PfKey pfKey : this.getKeys()) {
             // Check for the two type of keys we have
             if (pfKey instanceof PfConceptKey) {
-                result = validateArtifactKeyInModel((PfConceptKey) pfKey, artifactKeySet, result);
+                validateArtifactKeyInModel((PfConceptKey) pfKey, artifactKeySet, result);
             } else if (pfKey instanceof PfReferenceKey) {
-                result = validateReferenceKeyInModel((PfReferenceKey) pfKey, referenceKeySet, result);
-            }
-            // It must be a PfKeyUse, nothing else is legal
-            else {
+                validateReferenceKeyInModel((PfReferenceKey) pfKey, referenceKeySet, result);
+            } else {
+                // It must be a PfKeyUse, nothing else is legal
                 usedKeySet.add((PfKeyUse) pfKey);
             }
         }
@@ -142,12 +136,11 @@ public abstract class PfModel extends PfConcept {
         // Check all reference keys have correct parent keys
         for (final PfReferenceKey referenceKey : referenceKeySet) {
             if (!artifactKeySet.contains(referenceKey.getParentConceptKey())) {
-                result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                        "parent artifact key not found for reference key " + referenceKey));
+                addResult(result, "reference key", referenceKey, "parent artifact key not found");
             }
         }
 
-        result = validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result);
+        validateKeyUses(usedKeySet, artifactKeySet, referenceKeySet, result);
 
         return result;
     }
@@ -155,114 +148,101 @@ public abstract class PfModel extends PfConcept {
     /**
      * Check for consistent usage of an artifact key in the model.
      *
-     * @param artifactKey The artifact key to check
+     * @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
+     *                       the set
+     * @param result         where to add the results
      */
-    private PfValidationResult validateArtifactKeyInModel(final PfConceptKey artifactKey,
-            final Set<PfConceptKey> artifactKeySet, final PfValidationResult result) {
-        // Null key check
-        if (artifactKey.isNullKey()) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "key " + artifactKey + IS_A_NULL_KEY));
-        }
+    private void validateArtifactKeyInModel(final PfConceptKey artifactKey,
+                                            final Set<PfConceptKey> artifactKeySet, final BeanValidationResult result) {
+
+        validateKeyNotNull(result, KEYS_TOKEN, artifactKey);
+
+        var result2 = new BeanValidationResult(KEYS_TOKEN, artifactKey);
 
         // Null key name start check
         if (artifactKey.getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "key " + artifactKey + " name starts with keyword " + PfKey.NULL_KEY_NAME));
+            addResult(result2, "name of " + artifactKey.getId(), artifactKey.getName(),
+                "starts with keyword " + PfKey.NULL_KEY_NAME);
         }
 
         // Unique key check
         if (artifactKeySet.contains(artifactKey)) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "duplicate key " + artifactKey + " found"));
+            addResult(result, KEYS_TOKEN, artifactKey, "duplicate key");
         } else {
             artifactKeySet.add(artifactKey);
         }
-
-        return result;
     }
 
     /**
      * Check for consistent usage of a reference key in the model.
      *
-     * @param artifactKey The reference key to check
+     * @param referenceKey    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
+     *                        the set
+     * @param result          where to add the results
      */
-    private PfValidationResult validateReferenceKeyInModel(final PfReferenceKey referenceKey,
-            final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) {
+    private void validateReferenceKeyInModel(final PfReferenceKey referenceKey,
+                                             final Set<PfReferenceKey> referenceKeySet,
+                                             final BeanValidationResult result) {
         // Null key check
         if (referenceKey.isNullKey()) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "key " + referenceKey + IS_A_NULL_KEY));
+            addResult(result, KEYS_TOKEN, referenceKey, IS_A_NULL_KEY);
         }
 
+        var result2 = new BeanValidationResult(KEYS_TOKEN, referenceKey);
+
         // Null parent key check
         if (referenceKey.getParentConceptKey().isNullKey()) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "parent artifact key of key " + referenceKey + IS_A_NULL_KEY));
+            addResult(result2, "parent key of " + referenceKey.getId(), referenceKey.getParentConceptKey().getId(),
+                IS_A_NULL_KEY);
         }
 
         // Null local name check
         if (referenceKey.getLocalName().equals(PfKey.NULL_KEY_NAME)) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "key " + referenceKey + " has a null local name"));
+            addResult(result2, "local name of " + referenceKey.getId(), referenceKey.getLocalName(), IS_NULL);
         }
 
         // Null key name start check
         if (referenceKey.getParentConceptKey().getName().toUpperCase().startsWith(PfKey.NULL_KEY_NAME)) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "key " + referenceKey + " parent name starts with keyword " + PfKey.NULL_KEY_NAME));
+            addResult(result2, "parent name of " + referenceKey.getId(), referenceKey.getParentConceptKey().getName(),
+                "starts with keyword " + PfKey.NULL_KEY_NAME);
         }
 
         // Unique key check
         if (referenceKeySet.contains(referenceKey)) {
-            result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
-                    "duplicate key " + referenceKey + " found"));
+            addResult(result, KEYS_TOKEN, referenceKey, "duplicate key");
         } else {
             referenceKeySet.add(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 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
+     *                        the set
+     * @param result          where to add the results
      */
-    private PfValidationResult validateKeyUses(final Set<PfKeyUse> usedKeySet, final Set<PfConceptKey> artifactKeySet,
-            final Set<PfReferenceKey> referenceKeySet, final PfValidationResult result) {
+    private void validateKeyUses(final Set<PfKeyUse> usedKeySet, final Set<PfConceptKey> artifactKeySet,
+                                 final Set<PfReferenceKey> referenceKeySet, final BeanValidationResult result) {
         // Check all key uses
         for (final PfKeyUse usedKey : usedKeySet) {
             if (usedKey.getKey() instanceof PfConceptKey) {
                 // PfConceptKey usage, check the key exists
                 if (!artifactKeySet.contains(usedKey.getKey())) {
-                    result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(),
-                            ValidationResult.INVALID, "an artifact key used in the model is not defined"));
+                    result.addResult("artifact key", usedKey.getId(), ValidationStatus.INVALID, NOT_DEFINED);
                 }
             } else {
                 // PfReferenceKey usage, check the key exists
                 if (!referenceKeySet.contains(usedKey.getKey())) {
-                    result.addValidationMessage(new PfValidationMessage(usedKey.getKey(), this.getClass(),
-                            ValidationResult.INVALID, "a reference key used in the model is not defined"));
+                    result.addResult("reference key", usedKey.getId(), ValidationStatus.INVALID, NOT_DEFINED);
                 }
             }
         }
-
-        return result;
     }
 
     @Override
@@ -274,21 +254,11 @@ public abstract class PfModel extends PfConcept {
             return 0;
         }
         if (getClass() != otherObj.getClass()) {
-            return this.hashCode() - otherObj.hashCode();
+            return getClass().getName().compareTo(otherObj.getClass().getName());
         }
 
         final PfModel other = (PfModel) otherObj;
 
         return key.compareTo(other.key);
     }
-
-    @Override
-    public PfConcept copyTo(@NonNull final PfConcept target) {
-        Assertions.instanceOf(target, PfModel.class);
-
-        final PfModel copy = ((PfModel) target);
-        copy.setKey(new PfConceptKey(key));
-
-        return copy;
-    }
 }