2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019-2020 AT&T Intellectual Property. All rights reserved.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.models.base;
23 import com.google.re2j.Pattern;
24 import java.util.Collection;
26 import java.util.Map.Entry;
27 import java.util.function.BiFunction;
28 import java.util.function.Function;
29 import lombok.NonNull;
30 import org.apache.commons.lang3.StringUtils;
31 import org.onap.policy.common.parameters.BeanValidationResult;
32 import org.onap.policy.common.parameters.ObjectValidationResult;
33 import org.onap.policy.common.parameters.ValidationResult;
34 import org.onap.policy.common.parameters.ValidationStatus;
37 * Classes that can be validated. This can be used as a super class or as a stand-alone
40 public class Validated {
41 public static final String IS_BLANK = "is blank";
42 public static final String IS_A_NULL_KEY = "is a null key";
43 public static final String IS_NULL = "is null";
44 public static final String NOT_DEFINED = "not defined";
45 public static final String NOT_FOUND = "not found";
47 public static final String KEY_TOKEN = "key";
48 public static final String VALUE_TOKEN = "value";
51 * Validates the fields of the object. The default method uses a {@link PfValidator}
52 * to validate the object.
54 * @param fieldName name of the field containing this
55 * @return the result, or {@code null}
57 public BeanValidationResult validate(@NonNull String fieldName) {
58 return new PfValidator().validateTop(fieldName, this);
62 * Adds a result indicating that a value is invalid.
64 * @param result where to put the result
65 * @param fieldName name of the field containing the value
66 * @param value the field's value
67 * @param errorMessage the error message
69 public static void addResult(@NonNull BeanValidationResult result, @NonNull String fieldName, Object value,
70 @NonNull String errorMessage) {
72 new ObjectValidationResult(fieldName, getKeyId(value), ValidationStatus.INVALID, errorMessage));
76 * Makes a result that indicates a value is invalid, because it is null.
78 * @param fieldName name of the field containing the value
79 * @param value the field's value
80 * @return a result indicating the value is invalid
82 public static ValidationResult makeNullResult(@NonNull String fieldName, Object value) {
83 return new ObjectValidationResult(fieldName, getKeyId(value), ValidationStatus.INVALID, IS_NULL);
87 * Validates a value, if is not {@code null}, by invoking it's validate() method.
89 * @param result where to put the result
90 * @param fieldName name of the field containing the value
91 * @param value the field's value
93 public static void validateOptional(@NonNull BeanValidationResult result, @NonNull String fieldName,
96 result.addResult(value.validate(fieldName));
101 * Validates that a value is not {@code null}. If the value is a subclass of this
102 * class, then it's {@link #validate(String)} method is invoked, too.
104 * @param fieldName name of the field containing the value
105 * @param value the field's value
106 * @return a result, or {@code null}
108 public static ValidationResult validateNotNull(@NonNull String fieldName, Object value) {
110 return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID, IS_NULL);
113 if (value instanceof Validated) {
114 return ((Validated) value).validate(fieldName);
121 * Validates that a value is not "blank" (i.e., empty). value.
123 * @param fieldName name of the field containing the value
124 * @param value the field's value
125 * @param checkNull {@code true} if to validate that the value is not {@code null}
126 * @return a result, or {@code null}
128 public static ValidationResult validateNotBlank(@NonNull String fieldName, String value, boolean checkNull) {
129 if (value == null && !checkNull) {
133 if (StringUtils.isBlank(value)) {
134 return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID, IS_BLANK);
141 * Validates that a value matches regular expression.
143 * @param fieldName name of the field containing the value
144 * @param value the field's value
145 * @param pattern regular expression to be matched
146 * @return a result, or {@code null}
148 public static ValidationResult validateRegex(@NonNull String fieldName, String value, @NonNull String pattern) {
150 return makeNullResult(fieldName, value);
153 if (!Pattern.matches(pattern, value)) {
154 return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID,
155 "does not match regular expression " + pattern);
162 * Validates a key, ensuring that it isn't null and that it's structurally sound.
164 * @param fieldName name of the field containing the key
165 * @param key the field's value
166 * @return a result, or {@code null}
168 public static ValidationResult validateKeyNotNull(@NonNull String fieldName, PfKey key) {
170 return new ObjectValidationResult(fieldName, key, ValidationStatus.INVALID, IS_A_NULL_KEY);
173 if (key.isNullKey()) {
174 return new ObjectValidationResult(fieldName, key.getId(), ValidationStatus.INVALID, IS_A_NULL_KEY);
177 return key.validate(fieldName);
181 * Validates a key's version, ensuring that it isn't null.
183 * @param fieldName name of the field containing the key
184 * @param key the field's value
185 * @return a result, or {@code null}
187 public static BeanValidationResult validateKeyVersionNotNull(@NonNull String fieldName, PfConceptKey key) {
188 if (key != null && key.isNullVersion()) {
189 BeanValidationResult result = new BeanValidationResult(fieldName, key);
190 result.addResult(makeNullResult(PfKeyImpl.VERSION_TOKEN, key.getVersion()));
198 * Generates a function to validate that a value is not below a minimum.
200 * @param min minimum value allowed
201 * @param allowedValue {@code null} or an allowed value outside the range
202 * @param checkRef {@code true} to generate an error if the value is {@code null}
203 * @return a function to validate that a value is not below a minimum
205 public static BiFunction<String, Integer, ValidationResult> validateMin(int min, Integer allowedValue,
207 return (name, value) -> validateMin(name, value, min, allowedValue, checkRef);
211 * Validates that a value is not below a minimum.
213 * @param fieldName name of the field containing the key
214 * @param value the field's value
215 * @param min minimum value allowed
216 * @param allowedValue {@code null} or an allowed value outside the range
217 * @param checkRef {@code true} to generate an error if the value is {@code null}
218 * @return a result, or {@code null}
220 public static ValidationResult validateMin(@NonNull String fieldName, Integer value, int min, Integer allowedValue,
224 return makeNullResult(fieldName, value);
230 if (value < min && !value.equals(allowedValue)) {
231 return new ObjectValidationResult(fieldName, value, ValidationStatus.INVALID,
232 "is below the minimum value: " + min);
239 * Validates the items in a list.
241 * @param result where to add the results
242 * @param fieldName name of the field containing the list
243 * @param list the field's list (may be {@code null})
244 * @param checker function to validate in individual item in the list
246 public static <T> void validateList(@NonNull BeanValidationResult result, @NonNull String fieldName,
247 Collection<T> list, @NonNull BiFunction<String, T, ValidationResult> checker) {
252 BeanValidationResult result2 = new BeanValidationResult(fieldName, list);
255 for (T value : list) {
256 result2.addResult(checker.apply(String.valueOf(count++), value));
259 if (!result2.isClean()) {
260 result.addResult(result2);
265 * Validates the items in a map.
267 * @param result where to add the results
268 * @param fieldName name of the field containing the list
269 * @param map the field's map (may be {@code null})
270 * @param checker function to validate in individual item in the list
272 public static <T> void validateMap(@NonNull BeanValidationResult result, @NonNull String fieldName,
273 Map<String, T> map, @NonNull Function<Map.Entry<String, T>, ValidationResult> checker) {
278 BeanValidationResult result2 = new BeanValidationResult(fieldName, map);
280 for (Entry<String, T> entry : map.entrySet()) {
281 result2.addResult(checker.apply(entry));
284 if (!result2.isClean()) {
285 result.addResult(result2);
290 * Validates a Map entry, ensuring that neither the key nor the value are "blank"
291 * (i.e., empty or {@code null}).
293 * @param entry entry to be validated
294 * @return a result, or {@code null}
296 public static BeanValidationResult validateEntryNotBlankNotBlank(Map.Entry<String, String> entry) {
297 BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
299 if (StringUtils.isBlank(entry.getKey())) {
300 Validated.addResult(result, KEY_TOKEN, entry.getKey(), IS_BLANK);
303 if (StringUtils.isBlank(entry.getValue())) {
304 Validated.addResult(result, VALUE_TOKEN, entry.getValue(), IS_BLANK);
307 return (result.isClean() ? null : result);
311 * Validates a Map entry, ensuring that the key is not "blank" (i.e., empty or
312 * {@code null}) and the value is not {@code null}.
314 * @param entry entry to be validated
315 * @return a result, or {@code null}
317 public static BeanValidationResult validateEntryNotBlankNotNull(Map.Entry<String, String> entry) {
318 BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
320 if (StringUtils.isBlank(entry.getKey())) {
321 Validated.addResult(result, KEY_TOKEN, entry.getKey(), IS_BLANK);
324 if (entry.getValue() == null) {
325 result.addResult(makeNullResult(VALUE_TOKEN, entry.getValue()));
328 return (result.isClean() ? null : result);
332 * Validates a Map entry, ensuring that neither the key nor the value are
333 * {@code null}. If the value is a subclass of this class, then it's
334 * {@link #validate(String)} method is invoked.
336 * @param entry entry to be validated
337 * @return a result, or {@code null}
339 public static <V> BeanValidationResult validateEntryValueNotNull(Map.Entry<String, V> entry) {
340 BeanValidationResult result = new BeanValidationResult("" + entry.getKey(), entry.getKey());
342 if (entry.getKey() == null) {
343 result.addResult(makeNullResult(KEY_TOKEN, entry.getKey()));
346 V value = entry.getValue();
348 result.addResult(makeNullResult(VALUE_TOKEN, value));
349 } else if (value instanceof Validated) {
350 result.addResult(((Validated) value).validate(VALUE_TOKEN));
353 return (result.isClean() ? null : result);
357 * Gets a key's ID, if the value is a {@link PfKey}.
359 * @param value value from which to get the ID
360 * @return the value's ID, if it's a key, the original value otherwise
362 private static Object getKeyId(Object value) {
363 return (value instanceof PfKey ? ((PfKey) value).getId() : value);