summaryrefslogtreecommitdiffstats
path: root/models-base/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'models-base/src/main/java/org')
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfConcept.java13
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java49
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java22
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java15
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfModel.java100
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java38
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java104
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java146
-rw-r--r--models-base/src/main/java/org/onap/policy/models/base/Validated.java377
9 files changed, 332 insertions, 532 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
index 5273bd39e..394eb89f2 100644
--- 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
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. 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.
@@ -30,7 +30,7 @@ import lombok.NonNull;
* and interfaces on all concepts that are sub-classes of this class.
*/
-public abstract class PfConcept implements Serializable, Comparable<PfConcept> {
+public abstract class PfConcept extends Validated implements Serializable, Comparable<PfConcept> {
private static final long serialVersionUID = -7434939557282697490L;
/**
@@ -65,15 +65,6 @@ public abstract class PfConcept implements Serializable, Comparable<PfConcept> {
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(@NonNull final PfValidationResult result);
-
- /**
* Clean this concept, tidy up any superfluous information such as leading and trailing white space.
*/
public abstract void clean();
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java
index 863a3ef02..484632f7c 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfConceptContainer.java
@@ -45,7 +45,8 @@ import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import org.apache.commons.lang3.StringUtils;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
// @formatter:off
/**
@@ -241,19 +242,11 @@ public class PfConceptContainer<C extends PfConcept, A extends PfNameVersion> ex
}
@Override
- public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
- PfValidationResult result = resultIn;
+ public BeanValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, this);
- if (key.equals(PfConceptKey.getNullKey())) {
- result.addValidationMessage(
- new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
- }
-
- result = key.validate(result);
-
- if (!conceptMap.isEmpty()) {
- result = validateConceptMap(result);
- }
+ result.addResult(validateKeyNotNull("key", key));
+ result.addResult(validateConceptMap());
return result;
}
@@ -261,29 +254,31 @@ public class PfConceptContainer<C extends PfConcept, A extends PfNameVersion> ex
/**
* Validate the concept map of the container.
*
- * @param resultIn the incoming validation results so far
- * @return the validation results with the results of this validation added
+ * @return the validation result
*/
- private PfValidationResult validateConceptMap(final PfValidationResult resultIn) {
- PfValidationResult result = resultIn;
+ private ValidationResult validateConceptMap() {
+ BeanValidationResult result = new BeanValidationResult("conceptMap", conceptMap);
for (final Entry<PfConceptKey, C> conceptEntry : conceptMap.entrySet()) {
+ BeanValidationResult result2 = null;
+
if (conceptEntry.getKey().equals(PfConceptKey.getNullKey())) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "key on concept entry " + conceptEntry.getKey() + " may not be the null key"));
+ addResult(result, "key on concept entry", conceptEntry.getKey(), IS_A_NULL_KEY);
} else if (conceptEntry.getValue() == null) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "value on concept entry " + conceptEntry.getKey() + " may not be null"));
+ result2 = new BeanValidationResult(conceptEntry.getKey().getId(), conceptEntry.getKey());
+ addResult(result2, "value", conceptEntry.getValue(), IS_NULL);
} else if (!conceptEntry.getKey().equals(conceptEntry.getValue().getKey())) {
- result.addValidationMessage(new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID,
- "key on concept entry key " + conceptEntry.getKey() + " does not equal concept value key "
- + conceptEntry.getValue().getKey()));
- result = conceptEntry.getValue().validate(result);
+ result2 = new BeanValidationResult(conceptEntry.getKey().getId(), conceptEntry.getKey());
+ addResult(result2, "value", conceptEntry.getValue(), "does not equal concept key");
+ result2.addResult(conceptEntry.getValue().validate("value"));
} else {
- result = conceptEntry.getValue().validate(result);
+ result2 = new BeanValidationResult(conceptEntry.getKey().getId(), conceptEntry.getKey());
+ result2.addResult(conceptEntry.getValue().validate("value"));
}
+
+ result.addResult(result2);
}
- return result;
+ return (result.isClean() ? null : result);
}
@Override
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java b/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java
index 81066c37c..3cbef75f9 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyImpl.java
@@ -1,7 +1,7 @@
/*
* ============LICENSE_START=======================================================
* Copyright (C) 2019-2020 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. 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.
@@ -26,8 +26,9 @@ import java.util.List;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.common.utils.validation.Assertions;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
/**
* A key, upon which other key subclasses can be built, providing implementations of the methods.
@@ -241,20 +242,11 @@ public abstract class PfKeyImpl extends PfKey {
}
@Override
- public PfValidationResult validate(final PfValidationResult result) {
- final String nameValidationErrorMessage =
- Assertions.getStringParameterValidationMessage(NAME_TOKEN, getName(), getNameRegEx());
- if (nameValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "name invalid-" + nameValidationErrorMessage));
- }
+ public ValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, this);
- final String versionValidationErrorMessage =
- Assertions.getStringParameterValidationMessage(VERSION_TOKEN, getVersion(), getVersionRegEx());
- if (versionValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "version invalid-" + versionValidationErrorMessage));
- }
+ result.addResult(validateRegex(NAME_TOKEN, getName(), getNameRegEx()));
+ result.addResult(validateRegex(VERSION_TOKEN, getVersion(), getVersionRegEx()));
return result;
}
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java
index 03873236c..616284daf 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfKeyUse.java
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. 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.
@@ -25,8 +25,9 @@ import java.util.List;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
import lombok.ToString;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
import org.onap.policy.common.utils.validation.Assertions;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
/**
* This class records a usage of a key in the system. When the list of keys being used by a concept
@@ -134,12 +135,10 @@ public class PfKeyUse extends PfKey {
}
@Override
- public PfValidationResult validate(@NonNull final PfValidationResult result) {
- if (usedKey.isNullKey()) {
- result.addValidationMessage(new PfValidationMessage(usedKey, this.getClass(), ValidationResult.INVALID,
- "usedKey is a null key"));
- }
- return usedKey.validate(result);
+ public ValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, this);
+ result.addResult(validateKeyNotNull("usedKey", usedKey));
+ return result;
}
@Override
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfModel.java b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java
index 340f4e3b2..c87874774 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfModel.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfModel.java
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. 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.
@@ -32,8 +32,10 @@ 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.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
import org.onap.policy.common.utils.validation.Assertions;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
/**
* This class is the base class for all models in the Policy Framework. All model classes inherit
@@ -56,7 +58,7 @@ import org.onap.policy.models.base.PfValidationResult.ValidationResult;
@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";
private static final long serialVersionUID = -771659065637205430L;
@@ -110,15 +112,10 @@ public abstract class PfModel extends PfConcept {
}
@Override
- public PfValidationResult validate(@NonNull final PfValidationResult resultIn) {
- PfValidationResult result = resultIn;
+ public BeanValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, this);
- if (key.isNullKey()) {
- result.addValidationMessage(
- new PfValidationMessage(key, this.getClass(), ValidationResult.INVALID, "key is a null key"));
- }
-
- result = key.validate(result);
+ result.addResult(validateKeyNotNull("key", key));
// Key consistency check
final Set<PfConceptKey> artifactKeySet = new TreeSet<>();
@@ -128,9 +125,9 @@ 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);
+ validateReferenceKeyInModel((PfReferenceKey) pfKey, referenceKeySet, result);
} else {
// It must be a PfKeyUse, nothing else is legal
usedKeySet.add((PfKeyUse) pfKey);
@@ -140,12 +137,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;
}
@@ -156,78 +152,69 @@ public abstract class PfModel extends PfConcept {
* @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
+ * @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) {
+
+ result.addResult(validateKeyNotNull(KEYS_TOKEN, artifactKey));
+
+ BeanValidationResult 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
+ * @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);
}
+ BeanValidationResult 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;
}
/**
@@ -238,29 +225,26 @@ public abstract class PfModel extends PfConcept {
* 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
+ * @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(new ObjectValidationResult("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(new ObjectValidationResult("reference key", usedKey.getId(),
+ ValidationStatus.INVALID, NOT_DEFINED));
}
}
}
-
- return result;
}
@Override
diff --git a/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java
index 7984e4297..83403ac43 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/PfReferenceKey.java
@@ -1,7 +1,7 @@
/*-
* ============LICENSE_START=======================================================
* Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Modifications Copyright (C) 2019-2020 AT&T Intellectual Property. 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.
@@ -28,8 +28,9 @@ import javax.persistence.Embeddable;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NonNull;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
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
@@ -339,34 +340,13 @@ public class PfReferenceKey extends PfKey {
}
@Override
- public PfValidationResult validate(final PfValidationResult result) {
- final String parentNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(PARENT_KEY_NAME,
- parentKeyName, NAME_REGEXP);
- if (parentNameValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "parentKeyName invalid-" + parentNameValidationErrorMessage));
- }
-
- final String parentKeyVersionValidationErrorMessage = Assertions
- .getStringParameterValidationMessage(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP);
- if (parentKeyVersionValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "parentKeyVersion invalid-" + parentKeyVersionValidationErrorMessage));
- }
+ public ValidationResult validate(@NonNull String fieldName) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, this);
- final String parentLocalNameValidationErrorMessage = Assertions
- .getStringParameterValidationMessage(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP);
- if (parentLocalNameValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "parentLocalName invalid-" + parentLocalNameValidationErrorMessage));
- }
-
- final String localNameValidationErrorMessage = Assertions.getStringParameterValidationMessage(LOCAL_NAME,
- localName, LOCAL_NAME_REGEXP);
- if (localNameValidationErrorMessage != null) {
- result.addValidationMessage(new PfValidationMessage(this, this.getClass(), ValidationResult.INVALID,
- "localName invalid-" + localNameValidationErrorMessage));
- }
+ result.addResult(validateRegex(PARENT_KEY_NAME, parentKeyName, NAME_REGEXP));
+ result.addResult(validateRegex(PARENT_KEY_VERSION, parentKeyVersion, VERSION_REGEXP));
+ result.addResult(validateRegex(PARENT_LOCAL_NAME, parentLocalName, LOCAL_NAME_REGEXP));
+ result.addResult(validateRegex(LOCAL_NAME, localName, LOCAL_NAME_REGEXP));
return result;
}
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
deleted file mode 100644
index cd8b08bfa..000000000
--- a/models-base/src/main/java/org/onap/policy/models/base/PfValidationMessage.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2019 Nordix Foundation.
- * Modifications Copyright (C) 2019 AT&T Intellectual Property. 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.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.getName();
- 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
deleted file mode 100644
index bbac3b7e5..000000000
--- a/models-base/src/main/java/org/onap/policy/models/base/PfValidationResult.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * Copyright (C) 2019-2020 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;
-import lombok.Getter;
-
-/**
- * This class records the result of a validation and holds all validation observation messages.
- */
-@Getter
-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;
- }
-
-
- /**
- * Append a validation result to another validation result.
- *
- * @param result2Append the result to append to the current validation result
- */
- public void append(final PfValidationResult result2Append) {
- for (PfValidationMessage message : result2Append.getMessageList()) {
- addValidationMessage(message);
- }
- }
-
- /**
- * 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/Validated.java b/models-base/src/main/java/org/onap/policy/models/base/Validated.java
index d79d58f13..b962d46ab 100644
--- a/models-base/src/main/java/org/onap/policy/models/base/Validated.java
+++ b/models-base/src/main/java/org/onap/policy/models/base/Validated.java
@@ -20,234 +20,343 @@
package org.onap.policy.models.base;
+import com.google.re2j.Pattern;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.function.BiFunction;
+import java.util.function.Function;
import lombok.NonNull;
-import org.onap.policy.common.utils.validation.Assertions;
-import org.onap.policy.models.base.PfValidationResult.ValidationResult;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
/**
* Classes that can be validated. This can be used as a super class or as a stand-alone
* utility class.
*/
-public class Validated {
+public abstract class Validated {
+ public static final String IS_BLANK = "is blank";
+ public static final String IS_A_NULL_KEY = "is a null key";
+ public static final String IS_NULL = "is null";
+ public static final String NOT_DEFINED = "not defined";
+ public static final String NOT_FOUND = "not found";
+
+ public static final String KEY_TOKEN = "key";
+ public static final String VALUE_TOKEN = "value";
+
+ /**
+ * Validates the fields of the object.
+ *
+ * @param fieldName name of the field containing this
+ * @return the result, or {@code null}
+ */
+ public abstract ValidationResult validate(String fieldName);
/**
- * Validates the fields of the object. The default method simply returns the result.
+ * Adds a result indicating that a value is invalid.
*
- * @param result where to place the result
- * @return the result
+ * @param result where to put the result
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ * @param errorMessage the error message
*/
- public PfValidationResult validate(@NonNull PfValidationResult result) {
- return result;
+ public static void addResult(@NonNull BeanValidationResult result, @NonNull String fieldName, Object value,
+ @NonNull String errorMessage) {
+ result.addResult(
+ new ObjectValidationResult(fieldName, getKeyId(value), ValidationStatus.INVALID, errorMessage));
}
/**
- * Validates that a field value is not null.
+ * Makes a result that indicates a value is invalid, because it is null.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param value value to be validated
- * @param result where to place the result
- * @return the result
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ * @return a result indicating the value is invalid
*/
- public PfValidationResult validateNotNull(@NonNull Object container, @NonNull String fieldName, Object value,
- @NonNull PfValidationResult result) {
+ public static ValidationResult makeNullResult(@NonNull String fieldName, Object value) {
+ return new ObjectValidationResult(fieldName, getKeyId(value), ValidationStatus.INVALID, IS_NULL);
+ }
+ /**
+ * Validates a value, if is not {@code null}, by invoking it's validate() method.
+ *
+ * @param result where to put the result
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ */
+ public static void validateOptional(@NonNull BeanValidationResult result, @NonNull String fieldName,
+ Validated value) {
+ if (value != null) {
+ result.addResult(value.validate(fieldName));
+ }
+ }
+
+ /**
+ * Validates that a value is not {@code null}. If the value is a subclass of this
+ * class, then it's {@link #validate(String)} method is invoked, too.
+ *
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ * @return a result, or {@code null}
+ */
+ public static ValidationResult validateNotNull(@NonNull String fieldName, Object value) {
if (value == null) {
- addError(container, fieldName, result, "null");
+ return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID, IS_NULL);
+ }
+
+ if (value instanceof Validated) {
+ return ((Validated) value).validate(fieldName);
}
- return result;
+ return null;
}
/**
- * Validates that the name and version of a concept key do not have the null default
- * values.
+ * Validates that a value is not "blank" (i.e., empty). value.
*
- * @param value value to be validated
- * @param result where to place the result
- * @return the result
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ * @param checkNull {@code true} if to validate that the value is not {@code null}
+ * @return a result, or {@code null}
*/
- public PfValidationResult validateNotNull(@NonNull PfConceptKey value, @NonNull PfValidationResult result) {
-
- if (PfKey.NULL_KEY_NAME.equals(value.getName())) {
- addError(value, "name", result, "null");
+ public static ValidationResult validateNotBlank(@NonNull String fieldName, String value, boolean checkNull) {
+ if (value == null && !checkNull) {
+ return null;
}
- if (PfKey.NULL_KEY_VERSION.equals(value.getVersion())) {
- addError(value, "version", result, "null");
+ if (StringUtils.isBlank(value)) {
+ return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID, IS_BLANK);
}
- return result;
+ return null;
}
/**
- * Validates the contents of a field, verifying that it matches a pattern, if it is
- * non-null.
+ * Validates that a value matches regular expression.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param value value to be validated
- * @param pattern pattern used to validate the value
- * @param result where to place the result
- * @return the result
+ * @param fieldName name of the field containing the value
+ * @param value the field's value
+ * @param pattern regular expression to be matched
+ * @return a result, or {@code null}
*/
- public PfValidationResult validateText(@NonNull Object container, @NonNull String fieldName, String value,
- @NonNull String pattern, @NonNull PfValidationResult result) {
+ public static ValidationResult validateRegex(@NonNull String fieldName, String value, @NonNull String pattern) {
+ if (value == null) {
+ return makeNullResult(fieldName, value);
+ }
- if (value != null) {
- addError(container, fieldName, result,
- Assertions.getStringParameterValidationMessage(fieldName, value, pattern));
+ if (!Pattern.matches(pattern, value)) {
+ return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID,
+ "does not match regular expression " + pattern);
}
- return result;
+ return null;
}
/**
- * Validates the contents of a property field, verifying that the keys ands values are
- * non-null.
+ * Validates a key, ensuring that it isn't null and that it's structurally sound.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param properties properties to be validated
- * @param resultIn where to place the result
- * @return the result
+ * @param fieldName name of the field containing the key
+ * @param key the field's value
+ * @return a result, or {@code null}
*/
- public <T> PfValidationResult validatePropertiesNotNull(@NonNull Object container, @NonNull String fieldName,
- Map<String, T> properties, @NonNull PfValidationResult resultIn) {
+ public static ValidationResult validateKeyNotNull(@NonNull String fieldName, PfKey key) {
+ if (key == null) {
+ return new ObjectValidationResult(fieldName, key, ValidationStatus.INVALID, IS_A_NULL_KEY);
+ }
+
+ if (key.isNullKey()) {
+ return new ObjectValidationResult(fieldName, key.getId(), ValidationStatus.INVALID, IS_A_NULL_KEY);
+ }
- PfValidationResult result = resultIn;
+ return key.validate(fieldName);
+ }
- if (properties == null) {
+ /**
+ * Validates a key's version, ensuring that it isn't null.
+ *
+ * @param fieldName name of the field containing the key
+ * @param key the field's value
+ * @return a result, or {@code null}
+ */
+ public static BeanValidationResult validateKeyVersionNotNull(@NonNull String fieldName, PfConceptKey key) {
+ if (key != null && key.isNullVersion()) {
+ BeanValidationResult result = new BeanValidationResult(fieldName, key);
+ result.addResult(makeNullResult(PfKeyImpl.VERSION_TOKEN, key.getVersion()));
return result;
}
- for (Entry<String, T> ent : properties.entrySet()) {
- String key = ent.getKey();
- String keyName = fieldName + "." + key;
- result = validateNotNull(container, keyName, key, result);
+ return null;
+ }
+
+ /**
+ * Generates a function to validate that a value is not below a minimum.
+ *
+ * @param min minimum value allowed
+ * @param allowedValue {@code null} or an allowed value outside the range
+ * @param checkRef {@code true} to generate an error if the value is {@code null}
+ * @return a function to validate that a value is not below a minimum
+ */
+ public static BiFunction<String, Integer, ValidationResult> validateMin(int min, Integer allowedValue,
+ boolean checkRef) {
+ return (name, value) -> validateMin(name, value, min, allowedValue, checkRef);
+ }
+
+ /**
+ * Validates that a value is not below a minimum.
+ *
+ * @param fieldName name of the field containing the key
+ * @param value the field's value
+ * @param min minimum value allowed
+ * @param allowedValue {@code null} or an allowed value outside the range
+ * @param checkRef {@code true} to generate an error if the value is {@code null}
+ * @return a result, or {@code null}
+ */
+ public static ValidationResult validateMin(@NonNull String fieldName, Integer value, int min, Integer allowedValue,
+ boolean checkRef) {
+ if (value == null) {
+ if (checkRef) {
+ return makeNullResult(fieldName, value);
+ }
+
+ return null;
+ }
- result = validateNotNull(container, keyName, ent.getValue(), result);
+ if (value < min && !value.equals(allowedValue)) {
+ return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID,
+ "is below the minimum value: " + min);
}
- return result;
+ return null;
}
/**
- * Validates the items in a collection field are non-null.
+ * Validates the items in a list.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param collection collection whose items are to be validated
- * @param resultIn where to place the result
- * @return the result
+ * @param result where to add the results
+ * @param fieldName name of the field containing the list
+ * @param list the field's list (may be {@code null})
+ * @param checker function to validate in individual item in the list
*/
- public <T> PfValidationResult validateCollectionNotNull(@NonNull Object container, @NonNull String fieldName,
- Collection<T> collection, @NonNull PfValidationResult resultIn) {
+ public static <T> void validateList(@NonNull BeanValidationResult result, @NonNull String fieldName,
+ Collection<T> list, @NonNull BiFunction<String, T, ValidationResult> checker) {
+ if (list == null) {
+ return;
+ }
- PfValidationResult result = resultIn;
+ BeanValidationResult result2 = new BeanValidationResult(fieldName, list);
- if (collection == null) {
- return result;
+ int count = 0;
+ for (T value : list) {
+ result2.addResult(checker.apply(String.valueOf(count++), value));
}
- String prefix = fieldName + ".";
- int count = 0;
+ if (!result2.isClean()) {
+ result.addResult(result2);
+ }
+ }
+
+ /**
+ * Validates the items in a map.
+ *
+ * @param result where to add the results
+ * @param fieldName name of the field containing the list
+ * @param map the field's map (may be {@code null})
+ * @param checker function to validate in individual item in the list
+ */
+ public static <T> void validateMap(@NonNull BeanValidationResult result, @NonNull String fieldName,
+ Map<String, T> map, @NonNull Function<Map.Entry<String, T>, ValidationResult> checker) {
+ if (map == null) {
+ return;
+ }
- for (T item : collection) {
- result = validateNotNull(container, prefix + count, item, result);
- ++count;
+ BeanValidationResult result2 = new BeanValidationResult(fieldName, map);
+
+ for (Entry<String, T> entry : map.entrySet()) {
+ result2.addResult(checker.apply(entry));
}
- return result;
+ if (!result2.isClean()) {
+ result.addResult(result2);
+ }
}
/**
- * Invokes the "validate()" method on each item in a collection field, if the item is
- * non-null.
+ * Validates a Map entry, ensuring that neither the key nor the value are "blank"
+ * (i.e., empty or {@code null}).
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param collection collection whose items are to be validated
- * @param result where to place the result
- * @return the result
+ * @param entry entry to be validated
+ * @return a result, or {@code null}
*/
- public <T extends Validated> PfValidationResult validateCollection(@NonNull Object container,
- @NonNull String fieldName, Collection<T> collection, @NonNull PfValidationResult result) {
+ public static BeanValidationResult validateEntryNotBlankNotBlank(Map.Entry<String, String> entry) {
+ BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
- if (collection == null) {
- return result;
+ if (StringUtils.isBlank(entry.getKey())) {
+ Validated.addResult(result, KEY_TOKEN, entry.getKey(), IS_BLANK);
}
- for (T item : collection) {
- if (item != null) {
- result = item.validate(result);
- }
+ if (StringUtils.isBlank(entry.getValue())) {
+ Validated.addResult(result, VALUE_TOKEN, entry.getValue(), IS_BLANK);
}
- return result;
+ return (result.isClean() ? null : result);
}
/**
- * Invokes the "validate()" method on each item in a concept collection field, if the
- * item is non-null.
+ * Validates a Map entry, ensuring that the key is not "blank" (i.e., empty or
+ * {@code null}) and the value is not {@code null}.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param collection collection whose items are to be validated
- * @param result where to place the result
- * @return the result
+ * @param entry entry to be validated
+ * @return a result, or {@code null}
*/
- public <T extends PfConcept> PfValidationResult validateConceptCollection(@NonNull Object container,
- @NonNull String fieldName, Collection<T> collection, @NonNull PfValidationResult result) {
+ public static BeanValidationResult validateEntryNotBlankNotNull(Map.Entry<String, String> entry) {
+ BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
- if (collection == null) {
- return result;
+ if (StringUtils.isBlank(entry.getKey())) {
+ Validated.addResult(result, KEY_TOKEN, entry.getKey(), IS_BLANK);
}
- for (T item : collection) {
- if (item != null) {
- result = item.validate(result);
- }
+ if (entry.getValue() == null) {
+ result.addResult(makeNullResult(VALUE_TOKEN, entry.getValue()));
}
- return result;
+ return (result.isClean() ? null : result);
}
/**
- * Adds an error message to the validation result.
+ * Validates a Map entry, ensuring that neither the key nor the value are
+ * {@code null}. If the value is a subclass of this class, then it's
+ * {@link #validate(String)} method is invoked.
*
- * @param container the object that contains the field
- * @param fieldName name of the field to be validated
- * @param result where to place the result
- * @param errmsg the error message to be added, or {@code null} if nothing to add
+ * @param entry entry to be validated
+ * @return a result, or {@code null}
*/
- public void addError(@NonNull Object container, @NonNull String fieldName, @NonNull PfValidationResult result,
- String errmsg) {
- if (errmsg != null) {
- result.addValidationMessage(new PfValidationMessage(makeKey(container), container.getClass(),
- ValidationResult.INVALID, fieldName + " invalid-" + errmsg));
+ public static <V> BeanValidationResult validateEntryValueNotNull(Map.Entry<String, V> entry) {
+ BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
+
+ if (entry.getKey() == null) {
+ result.addResult(makeNullResult(KEY_TOKEN, entry.getKey()));
+ }
+
+ V value = entry.getValue();
+ if (value == null) {
+ result.addResult(makeNullResult(VALUE_TOKEN, value));
+ } else if (value instanceof Validated) {
+ result.addResult(((Validated) value).validate(VALUE_TOKEN));
}
+
+ return (result.isClean() ? null : result);
}
/**
- * Makes a PfKey suitable for insertion into a validation message. Note: the
- * "toString()" method of the key simply invokes container.toString();
+ * Gets a key's ID, if the value is a {@link PfKey}.
*
- * @param container the container object for which the key should be made
- * @return a key for the container
+ * @param value value from which to get the ID
+ * @return the value's ID, if it's a key, the original value otherwise
*/
- public PfKey makeKey(@NonNull Object container) {
-
- return new PfConceptKey() {
- private static final long serialVersionUID = 1L;
-
- @Override
- public String toString() {
- return container.toString();
- }
- };
+ private static Object getKeyId(Object value) {
+ return (value instanceof PfKey ? ((PfKey) value).getId() : value);
}
}