summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/BeanValidator.java61
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/FieldValidator.java65
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/Item2Validator.java71
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Max.java5
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java5
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java5
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java5
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Pattern.java5
-rw-r--r--common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Valid.java5
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java29
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java101
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/TestItem2Validator.java121
-rw-r--r--common-parameters/src/test/java/org/onap/policy/common/parameters/ValidatorUtil.java11
13 files changed, 471 insertions, 18 deletions
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/BeanValidator.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/BeanValidator.java
index 51b11402..6791c616 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/BeanValidator.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/BeanValidator.java
@@ -288,6 +288,9 @@ public class BeanValidator {
}
ItemValidator itemValidator = makeItemValidator(annot);
+ if (itemValidator.isEmpty()) {
+ return true;
+ }
return verCollection(result, fieldName, itemValidator, value);
}
@@ -304,7 +307,7 @@ public class BeanValidator {
public boolean verCollection(BeanValidationResult result, String fieldName, ValueValidator itemValidator,
Object value) {
- if (!(value instanceof Collection) || itemValidator.isEmpty()) {
+ if (!(value instanceof Collection)) {
return true;
}
@@ -376,6 +379,62 @@ public class BeanValidator {
}
/**
+ * Validates the items in a Map.
+ *
+ * @param result where to add the validation result
+ * @param fieldName name of the field containing the map
+ * @param keyValidator validator for an individual key within the Map entry
+ * @param valueValidator validator for an individual value within the Map entry
+ * @param value value to be verified
+ * @return {@code true} if the next check should be performed, {@code false} otherwise
+ */
+ public boolean verMap(BeanValidationResult result, String fieldName, ValueValidator keyValidator,
+ ValueValidator valueValidator, Object value) {
+
+ if (!(value instanceof Map)) {
+ return true;
+ }
+
+ Map<?, ?> map = (Map<?, ?>) value;
+
+ BeanValidationResult result2 = new BeanValidationResult(fieldName, value);
+
+ for (Entry<?, ?> entry : map.entrySet()) {
+ String name = getEntryName(entry);
+
+ BeanValidationResult result3 = new BeanValidationResult(name, entry);
+ keyValidator.validateValue(result3, "key", entry.getKey());
+ valueValidator.validateValue(result3, "value", entry.getValue());
+
+ if (!result3.isClean()) {
+ result2.addResult(result3);
+ }
+ }
+
+ if (result2.isClean()) {
+ return true;
+ }
+
+ result.addResult(result2);
+ return false;
+ }
+
+ /**
+ * Gets a name for an entry.
+ *
+ * @param entry entry whose name is to be determined
+ * @return a name for the entry
+ */
+ protected <K, V> String getEntryName(Map.Entry<K, V> entry) {
+ K key = entry.getKey();
+ if (key == null) {
+ return "";
+ }
+
+ return key.toString();
+ }
+
+ /**
* Makes a field validator.
*
* @param clazz class containing the field
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/FieldValidator.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/FieldValidator.java
index 249185c7..58f3e833 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/FieldValidator.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/FieldValidator.java
@@ -21,10 +21,14 @@
package org.onap.policy.common.parameters;
import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Map;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
@@ -76,6 +80,8 @@ public class FieldValidator extends ValueValidator {
}
validator.addValidators(this);
+ addListValidator(validator);
+ addMapValidator(validator);
if (checkers.isEmpty()) {
// has no annotations - nothing to check
@@ -105,6 +111,65 @@ public class FieldValidator extends ValueValidator {
}
/**
+ * Adds validators for the individual items within a collection, if the field is a
+ * collection.
+ *
+ * @param validator provider of validation methods
+ */
+ private void addListValidator(BeanValidator validator) {
+ if (!Collection.class.isAssignableFrom(field.getType())) {
+ return;
+ }
+
+ AnnotatedType tannot = field.getAnnotatedType();
+ if (!(tannot instanceof AnnotatedParameterizedType)) {
+ return;
+ }
+
+ AnnotatedType[] targs = ((AnnotatedParameterizedType) tannot).getAnnotatedActualTypeArguments();
+ if (targs.length != 1) {
+ return;
+ }
+
+ Item2Validator itemValidator = new Item2Validator(validator, targs[0]);
+ if (itemValidator.isEmpty()) {
+ return;
+ }
+
+ checkers.add((result, fieldName, value) -> validator.verCollection(result, fieldName, itemValidator, value));
+ }
+
+ /**
+ * Adds validators for the individual entries within a map, if the field is a map.
+ *
+ * @param validator provider of validation methods
+ */
+ private void addMapValidator(BeanValidator validator) {
+ if (!Map.class.isAssignableFrom(field.getType())) {
+ return;
+ }
+
+ AnnotatedType tannot = field.getAnnotatedType();
+ if (!(tannot instanceof AnnotatedParameterizedType)) {
+ return;
+ }
+
+ AnnotatedType[] targs = ((AnnotatedParameterizedType) tannot).getAnnotatedActualTypeArguments();
+ if (targs.length != 2) {
+ return;
+ }
+
+ Item2Validator keyValidator = new Item2Validator(validator, targs[0]);
+ Item2Validator valueValidator = new Item2Validator(validator, targs[1]);
+ if (keyValidator.isEmpty() && valueValidator.isEmpty()) {
+ return;
+ }
+
+ checkers.add((result, fieldName, value) -> validator.verMap(result, fieldName, keyValidator, valueValidator,
+ value));
+ }
+
+ /**
* Performs validation of a single field.
*
* @param result validation results are added here
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/Item2Validator.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/Item2Validator.java
new file mode 100644
index 00000000..c82244d6
--- /dev/null
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/Item2Validator.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.parameters;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedType;
+
+/**
+ * Validator of an "item", which is typically found in a collection, or the key or value
+ * components of an entry in a Map.
+ */
+public class Item2Validator extends ValueValidator {
+ private final AnnotatedType annotatedType;
+
+ /**
+ * Constructs the object.
+ *
+ * @param validator provider of validation methods
+ * @param annotatedType a type having validation annotations to be
+ * applied to the item
+ */
+ public Item2Validator(BeanValidator validator, AnnotatedType annotatedType) {
+ this(validator, annotatedType, true);
+ }
+
+ /**
+ * Constructs the object.
+ *
+ * @param validator provider of validation methods
+ * @param annotatedType a type having validation annotations to be
+ * applied to the item
+ * @param addValidators {@code true} if to add validators
+ */
+ public Item2Validator(BeanValidator validator, AnnotatedType annotatedType, boolean addValidators) {
+ this.annotatedType = annotatedType;
+
+ if (addValidators) {
+ validator.addValidators(this);
+ }
+ }
+
+ /**
+ * Gets an annotation from the field or the class.
+ *
+ * @param annotClass annotation class of interest
+ * @return the annotation, or {@code null} if the {@link #annotatedType} does
+ * not contain the desired annotation
+ */
+ @Override
+ public <T extends Annotation> T getAnnotation(Class<T> annotClass) {
+ return annotatedType.getAnnotation(annotClass);
+ }
+}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Max.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Max.java
index 1d8fd90f..f28fd2cf 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Max.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Max.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 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.
@@ -21,13 +21,14 @@
package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
-@Target(FIELD)
+@Target({FIELD, TYPE_USE})
public @interface Max {
/**
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java
index 9ad6d7e0..305d9810 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Min.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 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.
@@ -21,13 +21,14 @@
package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
-@Target(FIELD)
+@Target({FIELD, TYPE_USE})
public @interface Min {
/**
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java
index 169fa593..0744beb5 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotBlank.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 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.
@@ -22,6 +22,7 @@ package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
@@ -31,7 +32,7 @@ import java.lang.annotation.Target;
* Indicates that a field (i.e., String) may not be empty.
*/
@Retention(RUNTIME)
-@Target({TYPE, FIELD})
+@Target({TYPE, FIELD, TYPE_USE})
public @interface NotBlank {
}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java
index 3c7bc8b7..81356005 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/NotNull.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2019, 2021 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.
@@ -22,6 +22,7 @@ package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
@@ -31,7 +32,7 @@ import java.lang.annotation.Target;
* Indicates that a field may not be null.
*/
@Retention(RUNTIME)
-@Target({TYPE, FIELD})
+@Target({TYPE, FIELD, TYPE_USE})
public @interface NotNull {
}
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Pattern.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Pattern.java
index a30d814c..91a74d70 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Pattern.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Pattern.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 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.
@@ -21,13 +21,14 @@
package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
-@Target(FIELD)
+@Target({FIELD, TYPE_USE})
public @interface Pattern {
/**
diff --git a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Valid.java b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Valid.java
index a3a1d59f..227a726f 100644
--- a/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Valid.java
+++ b/common-parameters/src/main/java/org/onap/policy/common/parameters/annotations/Valid.java
@@ -2,7 +2,7 @@
* ============LICENSE_START=======================================================
* ONAP
* ================================================================================
- * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
+ * Copyright (C) 2020-2021 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.
@@ -22,13 +22,14 @@ package org.onap.policy.common.parameters.annotations;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
-@Target({TYPE, FIELD})
+@Target({TYPE, FIELD, TYPE_USE})
public @interface Valid {
}
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java
index 5d539260..00ed972c 100644
--- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestBeanValidator.java
@@ -23,6 +23,7 @@ package org.onap.policy.common.parameters;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertTrue;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
@@ -30,7 +31,6 @@ import java.util.function.Consumer;
import lombok.Getter;
import org.junit.Before;
import org.junit.Test;
-import org.onap.policy.common.parameters.annotations.Entries;
import org.onap.policy.common.parameters.annotations.Items;
import org.onap.policy.common.parameters.annotations.Max;
import org.onap.policy.common.parameters.annotations.Min;
@@ -489,11 +489,10 @@ public class TestBeanValidator {
public void testVerMap() {
@Getter
class Container {
- @Entries(key = @Items(), value = @Items(min = {@Min(5)}))
- Map<String, Integer> items;
+ Map<String, @Min(5) Integer> items;
- // not a map - should not be checked
- @Entries(key = @Items(), value = @Items(min = {@Min(5)}))
+ // not a map
+ @NotBlank
String strValue;
String noAnnotations;
@@ -521,6 +520,26 @@ public class TestBeanValidator {
assertTrue(validator.validateTop(TOP, cont).isValid());
}
+ @Test
+ public void testGetEntryName() {
+ assertThat(validator.getEntryName(makeEntry(null, 0))).isEmpty();
+ assertThat(validator.getEntryName(makeEntry("", 0))).isEmpty();
+ assertThat(validator.getEntryName(makeEntry(STRING_VALUE, 0))).isEqualTo(STRING_VALUE);
+ }
+
+ /**
+ * Makes a Map entry with the given key and value.
+ *
+ * @param key desired key
+ * @param value desired value
+ * @return a new Map entry
+ */
+ private Map.Entry<String, Integer> makeEntry(String key, int value) {
+ HashMap<String, Integer> map = new HashMap<>();
+ map.put(key, value);
+ return map.entrySet().iterator().next();
+ }
+
private <T> void assertNumeric(String testName, T object, Consumer<Integer> setter, String fieldName,
String expectedText, int inside, int edge, int outside) {
setter.accept(inside);
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java
index e4432c8d..29b4b0e3 100644
--- a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestFieldValidator.java
@@ -25,13 +25,18 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Map;
import lombok.Getter;
import org.junit.Before;
import org.junit.Test;
import org.onap.policy.common.parameters.annotations.Min;
+import org.onap.policy.common.parameters.annotations.NotBlank;
import org.onap.policy.common.parameters.annotations.NotNull;
public class TestFieldValidator extends ValidatorUtil {
+ private static final String INT_LIST_FIELD = "intList";
+ private static final String INT_MAP_FIELD = "intMap";
private static final String UNANNOTATED_FIELD = "unannotated";
private static final String INT_FIELD = "intValue";
private static final int VALID_INT = 10;
@@ -44,6 +49,24 @@ public class TestFieldValidator extends ValidatorUtil {
@Getter
private int intValue;
+ @Getter
+ private List<@Min(1) Integer> intList;
+
+ @Getter
+ private Map<@NotBlank String, @Min(1) Integer> intMap;
+
+ @Getter
+ private Map<@NotBlank String, Integer> annotatedKeyMap;
+
+ @Getter
+ private Map<String, @Min(1) Integer> annotatedValueMap;
+
+ @Getter
+ private List<Integer> unannotatedList;
+
+ @Getter
+ private Map<String, Integer> unannotatedMap;
+
@NotNull
@Getter
private boolean boolValue;
@@ -153,6 +176,52 @@ public class TestFieldValidator extends ValidatorUtil {
}
@Test
+ public void testAddListValidator() {
+
+ // unannotated
+ assertThat(new FieldValidator(bean, TestFieldValidator.class, getField("unannotatedList")).isEmpty()).isTrue();
+
+ // annotated
+ assertThat(new FieldValidator(bean, TestFieldValidator.class, getField(INT_LIST_FIELD)).isEmpty()).isFalse();
+ }
+
+ @Test
+ public void testAddMapValidator() {
+
+ // unannotated
+ assertThat(new FieldValidator(bean, TestFieldValidator.class, getField("unannotatedMap")).isEmpty()).isTrue();
+
+ // annotated
+ assertThat(new FieldValidator(bean, TestFieldValidator.class, getField(INT_MAP_FIELD)).isEmpty()).isFalse();
+
+ // only the key is annotated
+ FieldValidator validator = new FieldValidator(bean, TestFieldValidator.class, getField("annotatedKeyMap"));
+ assertThat(validator.isEmpty()).isFalse();
+
+ BeanValidationResult result = new BeanValidationResult(MY_NAME, this);
+ annotatedKeyMap = Map.of("abc", -10);
+ validator.validateField(result, this);
+ assertThat(result.getResult()).isNull();
+
+ annotatedKeyMap = Map.of(" ", -10);
+ validator.validateField(result, this);
+ assertThat(result.getResult()).contains("blank").doesNotContain("-10");
+
+ // only the value is annotated
+ validator = new FieldValidator(bean, TestFieldValidator.class, getField("annotatedValueMap"));
+ assertThat(validator.isEmpty()).isFalse();
+
+ result = new BeanValidationResult(MY_NAME, this);
+ annotatedValueMap = Map.of(" ", 10);
+ validator.validateField(result, this);
+ assertThat(result.getResult()).isNull();
+
+ annotatedValueMap = Map.of(" ", -10);
+ validator.validateField(result, this);
+ assertThat(result.getResult()).doesNotContain("blank").contains("\" \"", "-10");
+ }
+
+ @Test
public void testValidateField_testGetValue() {
// unannotated
BeanValidationResult result = new BeanValidationResult(MY_NAME, this);
@@ -180,6 +249,38 @@ public class TestFieldValidator extends ValidatorUtil {
}
@Test
+ public void testValidateField_testGetValue_ListField() {
+ // valid
+ BeanValidationResult result = new BeanValidationResult(MY_NAME, this);
+ intList = List.of(10, 20, 30, 40);
+ new FieldValidator(bean, getClass(), getField(INT_LIST_FIELD)).validateField(result, this);
+ assertThat(result.getResult()).isNull();
+
+ // invalid
+ result = new BeanValidationResult(MY_NAME, this);
+ intList = List.of(9, -8, 7, -6);
+ new FieldValidator(bean, getClass(), getField(INT_LIST_FIELD)).validateField(result, this);
+ assertThat(result.getResult()).doesNotContain("0", "9").contains("1", "-8").doesNotContain("2", "7")
+ .contains("3", "-6");
+ }
+
+ @Test
+ public void testValidateField_testGetValue_MapField() {
+ // valid
+ BeanValidationResult result = new BeanValidationResult(MY_NAME, this);
+ intMap = Map.of("ten", 10, "twenty", 20, "thirty", 30, "forty", 40);
+ new FieldValidator(bean, getClass(), getField(INT_MAP_FIELD)).validateField(result, this);
+ assertThat(result.getResult()).isNull();
+
+ // invalid
+ result = new BeanValidationResult(MY_NAME, this);
+ intMap = Map.of("ten", 9, "twenty", -8, "thirty", 7, "forty", -6);
+ new FieldValidator(bean, getClass(), getField(INT_MAP_FIELD)).validateField(result, this);
+ assertThat(result.getResult()).doesNotContain("ten", "9").contains("twenty", "-8").doesNotContain("thirty", "7")
+ .contains("forty", "-6");
+ }
+
+ @Test
public void testClassOnly() {
// class-level annotation has no bearing on a static field
assertThat(new FieldValidator(bean, ClassAnnot.class, getField(ClassAnnot.class, "staticValue")).isEmpty())
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/TestItem2Validator.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestItem2Validator.java
new file mode 100644
index 00000000..f8d38642
--- /dev/null
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/TestItem2Validator.java
@@ -0,0 +1,121 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP
+ * ================================================================================
+ * Copyright (C) 2021 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.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.common.parameters;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.common.parameters.annotations.Min;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+
+public class TestItem2Validator extends ValidatorUtil {
+
+ // annotated fields - each field must have exactly one annotation
+
+ /**
+ * This annotation does not contain a method returning an array.
+ */
+ @Min(value = 0)
+ private int notArray;
+
+ /**
+ * This annotation doesn't contain any annotations that the {@link BeanValidator}
+ * recognizes.
+ */
+ @Simple
+ private int mismatch;
+
+ /**
+ * No annotations.
+ */
+ @SuppressWarnings("unused")
+ private int noAnnotations;
+
+ /**
+ * One matching annotation.
+ */
+ @NotNull
+ private int match;
+
+ /**
+ * Multiple matching annotations.
+ */
+ @NotNull
+ @NotBlank
+ private String multiMatch;
+
+
+ @Before
+ public void setUp() {
+ bean = new BeanValidator();
+ }
+
+ @Test
+ public void testGetAnnotation() {
+ // no matches
+ assertThat(new Item2Validator(bean, getAnnotType("noAnnotations"), true).isEmpty()).isTrue();
+
+ // had a match
+ assertThat(new Item2Validator(bean, getAnnotType("match"), true).checkers).hasSize(1);
+
+ // multiple matches
+ Item2Validator validator = new Item2Validator(bean, getAnnotType("multiMatch"), true);
+ assertThat(validator.checkers).hasSize(2);
+
+ BeanValidationResult result = new BeanValidationResult(MY_NAME, this);
+ validator.validateValue(result, MY_FIELD, HELLO);
+ assertThat(result.getResult()).isNull();
+
+ result = new BeanValidationResult(MY_NAME, this);
+ validator.validateValue(result, MY_FIELD, null);
+ assertThat(result.getResult()).isNotNull();
+
+ result = new BeanValidationResult(MY_NAME, this);
+ validator.validateValue(result, MY_FIELD, "");
+ assertThat(result.getResult()).isNotNull();
+ }
+
+ @Test
+ public void testItem2ValidatorBeanValidatorAnnotation() {
+ assertThat(new Item2Validator(bean, getAnnotType("match")).isEmpty()).isFalse();
+ }
+
+ @Test
+ public void testItem2ValidatorBeanValidatorAnnotationBoolean() {
+ assertThat(new Item2Validator(bean, getAnnotType("match"), true).isEmpty()).isFalse();
+
+ assertThat(new Item2Validator(bean, getAnnotType("match"), false).isEmpty()).isTrue();
+ }
+
+ // these annotations are not recognized by the BeanValidator
+
+ @Retention(RUNTIME)
+ @Target(FIELD)
+ public @interface Simple {
+
+ }
+}
diff --git a/common-parameters/src/test/java/org/onap/policy/common/parameters/ValidatorUtil.java b/common-parameters/src/test/java/org/onap/policy/common/parameters/ValidatorUtil.java
index 4df014f7..e39b5b86 100644
--- a/common-parameters/src/test/java/org/onap/policy/common/parameters/ValidatorUtil.java
+++ b/common-parameters/src/test/java/org/onap/policy/common/parameters/ValidatorUtil.java
@@ -21,6 +21,7 @@
package org.onap.policy.common.parameters;
import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Field;
/**
@@ -44,6 +45,16 @@ public class ValidatorUtil {
}
/**
+ * Gets the annotated type for a given field.
+ *
+ * @param fieldName name of the field of interest
+ * @return the given field's annotated type
+ */
+ protected AnnotatedType getAnnotType(String fieldName) {
+ return getField(fieldName).getAnnotatedType();
+ }
+
+ /**
* Gets a field from this object.
*
* @param fieldName name of the field of interest