You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/02/21 21:02:06 UTC
[16/17] bval git commit: code updates
code updates
Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/f87be824
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/f87be824
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/f87be824
Branch: refs/heads/bv2
Commit: f87be824d77a26424e6856183391c8d3340b5241
Parents: b808381
Author: Matt Benson <mb...@apache.org>
Authored: Wed Feb 21 14:58:35 2018 -0600
Committer: Matt Benson <mb...@apache.org>
Committed: Wed Feb 21 14:59:59 2018 -0600
----------------------------------------------------------------------
.../bval/routines/EMailValidationUtils.java | 7 +-
.../main/java/org/apache/bval/el/ELFacade.java | 16 +--
.../bval/jsr/AnnotationConstraintBuilder.java | 38 ++---
.../apache/bval/jsr/AnnotationProcessor.java | 24 ++--
.../jsr/ConstraintAnnotationAttributes.java | 46 +++---
.../org/apache/bval/jsr/ConstraintCached.java | 143 +++++++++++++++++--
.../org/apache/bval/jsr/ConstraintDefaults.java | 103 +++++--------
.../bval/jsr/ConstraintDescriptorImpl.java | 13 ++
.../apache/bval/jsr/ConstraintValidation.java | 33 ++++-
.../jsr/ConstraintValidatorContextImpl.java | 20 ++-
.../bval/jsr/ConstraintValidatorIdentity.java | 9 +-
.../bval/jsr/ConstraintViolationImpl.java | 94 +++++-------
.../jsr/DefaultConstraintValidatorFactory.java | 12 +-
.../bval/jsr/DefaultMessageInterpolator.java | 35 ++---
.../jsr/DefaultValidationProviderResolver.java | 50 +++----
.../org/apache/bval/jsr/GraphBeanIdentity.java | 28 +---
.../bval/jsr/ParameterDescriptorImpl.java | 7 +
.../apache/bval/jsr/PropertyDescriptorImpl.java | 9 ++
.../bval/jsr/ReturnValueDescriptorImpl.java | 8 ++
.../java/org/apache/bval/jsr/groups/Group.java | 13 +-
.../groups/GroupConversionDescriptorImpl.java | 3 +-
.../java/org/apache/bval/jsr/groups/Groups.java | 67 +++++----
.../apache/bval/jsr/groups/GroupsComputer.java | 111 +++++++-------
.../parameter/DefaultParameterNameProvider.java | 25 ++--
.../resolver/CachingTraversableResolver.java | 26 ++--
25 files changed, 506 insertions(+), 434 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-core/src/main/java/org/apache/bval/routines/EMailValidationUtils.java
----------------------------------------------------------------------
diff --git a/bval-core/src/main/java/org/apache/bval/routines/EMailValidationUtils.java b/bval-core/src/main/java/org/apache/bval/routines/EMailValidationUtils.java
index 1158c7f..0835bae 100644
--- a/bval-core/src/main/java/org/apache/bval/routines/EMailValidationUtils.java
+++ b/bval-core/src/main/java/org/apache/bval/routines/EMailValidationUtils.java
@@ -29,12 +29,11 @@ public class EMailValidationUtils {
private static String ATOM = "[^\\x00-\\x1F\\(\\)\\<\\>\\@\\,\\;\\:\\\\\\\"\\.\\[\\]\\s]";
private static String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)*";
private static String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";
- public static final java.util.regex.Pattern DEFAULT_EMAIL_PATTERN;
+ public static final Pattern DEFAULT_EMAIL_PATTERN;
static {
- DEFAULT_EMAIL_PATTERN =
- java.util.regex.Pattern.compile("^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$",
- java.util.regex.Pattern.CASE_INSENSITIVE);
+ DEFAULT_EMAIL_PATTERN = Pattern.compile("^" + ATOM + "+(\\." + ATOM + "+)*@" + DOMAIN + "|" + IP_DOMAIN + ")$",
+ Pattern.CASE_INSENSITIVE);
}
/**
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java b/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
index 49f236b..9798455 100644
--- a/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
+++ b/bval-jsr/src/main/java/org/apache/bval/el/ELFacade.java
@@ -54,10 +54,9 @@ public final class ELFacade implements MessageEvaluator {
if (EXPRESSION_FACTORY != null) {
final BValELContext context = new BValELContext();
final VariableMapper variables = context.getVariableMapper();
- for (final Map.Entry<String, Object> var : annotationParameters.entrySet()) {
- variables.setVariable(var.getKey(),
- EXPRESSION_FACTORY.createValueExpression(var.getValue(), Object.class));
- }
+ annotationParameters.forEach(
+ (k, v) -> variables.setVariable(k, EXPRESSION_FACTORY.createValueExpression(v, Object.class)));
+
variables.setVariable("validatedValue",
EXPRESSION_FACTORY.createValueExpression(validatedValue, Object.class));
@@ -83,13 +82,8 @@ public final class ELFacade implements MessageEvaluator {
}
private static class BValELContext extends ELContext {
- private final FunctionMapper functions;
- private final VariableMapper variables;
-
- public BValELContext() {
- this.variables = new BValVariableMapper();
- this.functions = new BValFunctionMapper();
- }
+ private final FunctionMapper functions = new BValFunctionMapper();
+ private final VariableMapper variables = new BValVariableMapper();
@Override
public ELResolver getELResolver() {
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationConstraintBuilder.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationConstraintBuilder.java b/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationConstraintBuilder.java
index 017cabb..4b15ba7 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationConstraintBuilder.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationConstraintBuilder.java
@@ -72,7 +72,7 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
final boolean reportFromComposite =
annotation != null && annotation.annotationType().isAnnotationPresent(ReportAsSingleViolation.class);
constraintValidation =
- new ConstraintValidation<A>(validatorClasses, annotation, owner, access, reportFromComposite, target);
+ new ConstraintValidation<>(validatorClasses, annotation, owner, access, reportFromComposite, target);
buildFromAnnotation();
}
@@ -139,7 +139,7 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
if (!foundGroups) {
throw new ConstraintDefinitionException("Annotation " + annotationType.getName() + " has no groups method");
}
- if (validationAppliesTo != null && !ConstraintTarget.IMPLICIT.equals(validationAppliesTo.getDefaultValue())) {
+ if (validationAppliesTo != null && ConstraintTarget.IMPLICIT != validationAppliesTo.getDefaultValue()) {
throw new ConstraintDefinitionException("validationAppliesTo default value should be IMPLICIT");
}
@@ -257,9 +257,9 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
final Set<Class<? extends Payload>> payloadSet;
if (payload_raw == null) {
- payloadSet = Collections.<Class<? extends Payload>> emptySet();
+ payloadSet = Collections.emptySet();
} else {
- payloadSet = new HashSet<Class<? extends Payload>>(payload_raw.length);
+ payloadSet = new HashSet<>(payload_raw.length);
Collections.addAll(payloadSet, payload_raw);
}
constraintValidation.setPayload(payloadSet);
@@ -323,18 +323,13 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
* @return An integer index always >= 0
*/
private int computeIndex(ConstraintValidation<?> composite) {
- int idx = 0;
- for (ConstraintValidation<?> each : constraintValidation.getComposingValidations()) {
- if (each.getAnnotation().annotationType() == composite.getAnnotation().annotationType()) {
- idx++;
- }
- }
- return idx;
+ return (int) constraintValidation.getComposingValidations().stream()
+ .filter(v -> v.getAnnotation().annotationType().equals(composite.getAnnotation().annotationType())).count();
}
/** read overridesAttributes from constraintValidation.annotation */
private void buildOverridesAttributes() {
- overrides = new LinkedList<ConstraintOverrides>();
+ overrides = new LinkedList<>();
for (Method method : constraintValidation.getAnnotation().annotationType().getDeclaredMethods()) {
final OverridesAttribute.List overridesAttributeList = method.getAnnotation(OverridesAttribute.List.class);
if (overridesAttributeList != null) {
@@ -359,12 +354,9 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
}
private ConstraintOverrides findOverride(Class<? extends Annotation> constraint, int constraintIndex) {
- for (ConstraintOverrides each : overrides) {
- if (each.constraintType == constraint && each.constraintIndex == constraintIndex) {
- return each;
- }
- }
- return null;
+ return overrides.stream()
+ .filter(ov -> ov.constraintType.equals(constraint) && ov.constraintIndex == constraintIndex).findFirst()
+ .orElse(null);
}
/**
@@ -381,7 +373,7 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
private ConstraintOverrides(Class<? extends Annotation> constraintType, int constraintIndex) {
this.constraintType = constraintType;
this.constraintIndex = constraintIndex;
- values = new HashMap<String, Object>();
+ values = new HashMap<>();
}
@SuppressWarnings("unchecked")
@@ -392,11 +384,9 @@ final class AnnotationConstraintBuilder<A extends Annotation> {
// And the annotation
final Annotation originalAnnot = composite.getAnnotation();
final AnnotationProxyBuilder<Annotation> apb = new AnnotationProxyBuilder<Annotation>(originalAnnot);
- for (String key : values.keySet()) {
- apb.putValue(key, values.get(key));
- }
- final Annotation newAnnot = apb.createAnnotation();
- ((ConstraintValidation<Annotation>) composite).setAnnotation(newAnnot);
+ values.forEach(apb::putValue);
+
+ ((ConstraintValidation<Annotation>) composite).setAnnotation(apb.createAnnotation());
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationProcessor.java b/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationProcessor.java
index 4bdb331..3c4b046 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationProcessor.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/AnnotationProcessor.java
@@ -38,7 +38,9 @@ import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.List;
import java.util.Set;
/**
@@ -121,7 +123,7 @@ public final class AnnotationProcessor {
if (!reflection) {
Collection<Annotation> annotations = prop.getFeature(JsrFeatures.Property.ANNOTATIONS_TO_PROCESS);
if (annotations == null) {
- annotations = new ArrayList<Annotation>();
+ annotations = new ArrayList<>();
prop.putFeature(JsrFeatures.Property.ANNOTATIONS_TO_PROCESS, annotations);
}
annotations.add(annotation);
@@ -129,18 +131,19 @@ public final class AnnotationProcessor {
return true;
}
- /**
+ /*
* An annotation is considered a constraint definition if its retention
* policy contains RUNTIME and if the annotation itself is annotated
* with javax.validation.Constraint.
*/
final Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
if (vcAnno != null) {
- Class<? extends ConstraintValidator<A, ?>>[] validatorClasses;
- validatorClasses = findConstraintValidatorClasses(annotation, vcAnno);
+ Class<? extends ConstraintValidator<A, ?>>[] validatorClasses =
+ findConstraintValidatorClasses(annotation, vcAnno);
return applyConstraint(annotation, validatorClasses, prop, owner, access, appender);
}
- /**
+
+ /*
* Multi-valued constraints: To support this requirement, the bean
* validation provider treats regular annotations (annotations not
* annotated by @Constraint) whose value element has a return type of an
@@ -202,15 +205,14 @@ public final class AnnotationProcessor {
vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
}
final Class<A> annotationType = (Class<A>) annotation.annotationType();
- Class<? extends ConstraintValidator<A, ?>>[] validatorClasses =
- factory.getConstraintsCache().getConstraintValidators(annotationType);
+ List<Class<? extends ConstraintValidator<A, ?>>> validatorClasses =
+ factory.getConstraintsCache().getConstraintValidatorClasses(annotationType);
if (validatorClasses == null) {
- validatorClasses = (Class<? extends ConstraintValidator<A, ?>>[]) vcAnno.validatedBy();
- if (validatorClasses.length == 0) {
- validatorClasses = factory.getDefaultConstraints().getValidatorClasses(annotationType);
+ validatorClasses = Arrays.asList((Class<? extends ConstraintValidator<A, ?>>[]) vcAnno.validatedBy());
+ if (validatorClasses.isEmpty()) {
}
}
- return validatorClasses;
+ return validatorClasses.toArray(new Class[validatorClasses.size()]);
}
/**
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
index 24b38ea..df99bf9 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintAnnotationAttributes.java
@@ -16,6 +16,7 @@
*/
package org.apache.bval.jsr;
+import org.apache.bval.util.Exceptions;
import org.apache.bval.util.reflection.Reflection;
import org.apache.bval.util.reflection.TypeUtils;
import org.apache.commons.weaver.privilizer.Privilizing;
@@ -125,29 +126,24 @@ public enum ConstraintAnnotationAttributes {
public <V> V get(Map<? super String, ? super V> map) {
@SuppressWarnings("unchecked")
final V result = (V) map.get(getAttributeName());
- if (TypeUtils.isInstance(result, getType())) {
- return result;
- }
- throw new IllegalStateException(String.format("Invalid '%s' value: %s", getAttributeName(), result));
+ Exceptions.raiseUnless(TypeUtils.isInstance(result, getType()), IllegalStateException::new,
+ "Invalid '%s' value: %s", getAttributeName(), result);
+ return result;
}
public <C extends Annotation> Worker<C> analyze(final Class<C> clazz) {
if (clazz.getName().startsWith("javax.validation.constraint.")) { // cache only APIs classes to avoid memory leaks
@SuppressWarnings("unchecked")
- Worker<C> w = Worker.class.cast(WORKER_CACHE.get(clazz));
- if (w == null) {
- w = new Worker<C>(clazz);
- WORKER_CACHE.putIfAbsent(clazz, w);
- return w;
- }
+ final Worker<C> w = (Worker<C>) WORKER_CACHE.computeIfAbsent(clazz, Worker::new);
+ return w;
}
return new Worker<C>(clazz);
}
// this is static but related to Worker
- private static final ConcurrentMap<Class<?>, Worker<?>> WORKER_CACHE = new ConcurrentHashMap<Class<?>, Worker<?>>();
+ private static final ConcurrentMap<Class<?>, Worker<?>> WORKER_CACHE = new ConcurrentHashMap<>();
private static final ConcurrentMap<Class<?>, ConcurrentMap<String, Method>> METHOD_BY_NAME_AND_CLASS =
- new ConcurrentHashMap<Class<?>, ConcurrentMap<String, Method>>();
+ new ConcurrentHashMap<>();
private static final Method NULL_METHOD;
static {
try {
@@ -171,14 +167,8 @@ public enum ConstraintAnnotationAttributes {
}
private Method findMethod(final Class<C> constraintType, final String attributeName) {
- ConcurrentMap<String, Method> cache = METHOD_BY_NAME_AND_CLASS.get(constraintType);
- if (cache == null) {
- cache = new ConcurrentHashMap<String, Method>();
- final ConcurrentMap<String, Method> old = METHOD_BY_NAME_AND_CLASS.putIfAbsent(constraintType, cache);
- if (old != null) {
- cache = old;
- }
- }
+ ConcurrentMap<String, Method> cache =
+ METHOD_BY_NAME_AND_CLASS.computeIfAbsent(constraintType, t -> new ConcurrentHashMap<>());
final Method found = cache.get(attributeName);
if (found != null) {
@@ -189,15 +179,19 @@ public enum ConstraintAnnotationAttributes {
cache.putIfAbsent(attributeName, NULL_METHOD);
return null;
}
- final Method oldMtd = cache.putIfAbsent(attributeName, m);
- if (oldMtd != null) {
- return oldMtd;
- }
- return m;
+ return cache.computeIfAbsent(attributeName, s -> m);
}
public boolean isValid() {
- return method != null && method != NULL_METHOD;
+ return method != null && method != NULL_METHOD && TypeUtils.isAssignable(method.getReturnType(), type);
+ }
+
+ /**
+ * @since 2.0
+ * @return {@link Type}
+ */
+ public Type getSpecificType() {
+ return isValid() ? method.getGenericReturnType() : type;
}
public <T> T read(final Annotation constraint) {
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
index 1bb012f..a1f3924 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
@@ -18,18 +18,92 @@
*/
package org.apache.bval.jsr;
-import javax.validation.ConstraintValidator;
import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.ConstraintValidator;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
+
+import org.apache.bval.jsr.metadata.AnnotationDeclaredValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.CompositeValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.DualValidationMappingProvider;
+import org.apache.bval.jsr.metadata.ValidatorMappingProvider;
+import org.apache.bval.jsr.util.ToUnmodifiable;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.ObjectUtils;
+import org.apache.bval.util.Validate;
/**
- * Description: hold the relationship annotation->validatedBy[] ConstraintValidator classes that are already parsed in a
- * cache.<br/>
+ * Description: hold the relationship annotation->validatedBy[]
+ * ConstraintValidator classes that are already parsed in a cache.<br/>
*/
public class ConstraintCached {
- private final Map<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]> classes =
- new HashMap<Class<? extends Annotation>, Class<? extends ConstraintValidator<?, ?>>[]>();
+
+ /**
+ * Describes a {@link ConstraintValidator} implementation type.
+ *
+ * @since 2.0
+ */
+ public static final class ConstraintValidatorInfo<T extends Annotation> {
+ private static final Set<ValidationTarget> DEFAULT_VALIDATION_TARGETS =
+ Collections.singleton(ValidationTarget.ANNOTATED_ELEMENT);
+
+ private final Class<? extends ConstraintValidator<T, ?>> type;
+ private Set<ValidationTarget> supportedTargets;
+
+ ConstraintValidatorInfo(Class<? extends ConstraintValidator<T, ?>> type) {
+ super();
+ this.type = Validate.notNull(type);
+ final SupportedValidationTarget svt = type.getAnnotation(SupportedValidationTarget.class);
+
+ supportedTargets = svt == null ? DEFAULT_VALIDATION_TARGETS
+ : Collections.unmodifiableSet(EnumSet.copyOf(Arrays.asList(svt.value())));
+ }
+
+ public Class<? extends ConstraintValidator<T, ?>> getType() {
+ return type;
+ }
+
+ public Set<ValidationTarget> getSupportedTargets() {
+ return supportedTargets;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj == this
+ || obj instanceof ConstraintValidatorInfo<?> && ((ConstraintValidatorInfo<?>) obj).type.equals(type);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(type);
+ }
+ }
+
+ private final Map<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
+ new HashMap<>();
+
+ private final List<ValidatorMappingProvider> customValidatorMappingProviders = new ArrayList<>();
+ private final Lazy<ValidatorMappingProvider> validatorMappingProvider =
+ new Lazy<>(this::createValidatorMappingProvider);
+
+ public void add(ValidatorMappingProvider validatorMappingProvider) {
+ if (customValidatorMappingProviders.add(validatorMappingProvider)) {
+ this.validatorMappingProvider.reset(this::createValidatorMappingProvider);
+ }
+ }
/**
* Record the set of validator classes for a given constraint annotation.
@@ -37,33 +111,80 @@ public class ConstraintCached {
* @param annotationClass
* @param definitionClasses
*/
+ @Deprecated
public <A extends Annotation> void putConstraintValidator(Class<A> annotationClass,
Class<? extends ConstraintValidator<A, ?>>[] definitionClasses) {
- classes.put(annotationClass, definitionClasses);
+ if (ObjectUtils.isEmpty(definitionClasses)) {
+ return;
+ }
+ Validate.notNull(annotationClass, "annotationClass");
+ Stream.of(definitionClasses).map(t -> new ConstraintValidatorInfo<>(t))
+ .forEach(constraintValidatorInfo.computeIfAbsent(annotationClass, k -> new HashSet<>())::add);
}
/**
- * Learn whether we have cached the validator classes for the requested constraint annotation.
+ * Learn whether we have cached the validator classes for the requested
+ * constraint annotation.
*
* @param annotationClass
* to look up
* @return boolean
*/
+ @Deprecated
public boolean containsConstraintValidator(Class<? extends Annotation> annotationClass) {
- return classes.containsKey(annotationClass);
+ return constraintValidatorInfo.containsKey(annotationClass);
}
/**
* Get the cached validator classes for the requested constraint annotation.
*
- * @param annotationClass
+ * @param constraintType
* to look up
* @return array of {@link ConstraintValidator} implementation types
*/
@SuppressWarnings("unchecked")
+ @Deprecated
public <A extends Annotation> Class<? extends ConstraintValidator<A, ?>>[] getConstraintValidators(
- Class<A> annotationClass) {
- return (Class<? extends ConstraintValidator<A, ?>>[]) classes.get(annotationClass);
+ Class<A> constraintType) {
+ final Set<ConstraintValidatorInfo<A>> infos = infos(constraintType);
+ return infos == null ? new Class[0]
+ : infos.stream().map(ConstraintValidatorInfo::getType).toArray(Class[]::new);
}
+ public <A extends Annotation> List<Class<? extends ConstraintValidator<A, ?>>> getConstraintValidatorClasses(
+ Class<A> constraintType) {
+ final Set<ConstraintValidatorInfo<A>> infos = infos(constraintType);
+ return infos == null ? Collections.emptyList()
+ : infos.stream().map(ConstraintValidatorInfo::getType).collect(ToUnmodifiable.list());
+ }
+
+ public <A extends Annotation> Set<ConstraintValidatorInfo<A>> getConstraintValidatorInfo(Class<A> constraintType) {
+ return Collections.unmodifiableSet(infos(constraintType));
+ }
+
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ private <A extends Annotation> Set<ConstraintValidatorInfo<A>> infos(Class<A> constraintType) {
+ return (Set) constraintValidatorInfo.computeIfAbsent(constraintType,
+ c -> validatorMappingProvider.get().getValidatorMapping(c).getValidatorTypes().stream()
+ .map(ConstraintValidatorInfo::new).collect(Collectors.toSet()));
+ }
+
+ private ValidatorMappingProvider createValidatorMappingProvider() {
+ final ValidatorMappingProvider configured;
+ if (customValidatorMappingProviders.isEmpty()) {
+ configured = AnnotationDeclaredValidatorMappingProvider.INSTANCE;
+ } else {
+ final ValidatorMappingProvider custom;
+ if (customValidatorMappingProviders.size() == 1) {
+ custom = customValidatorMappingProviders.get(0);
+ } else {
+ custom = new CompositeValidatorMappingProvider(customValidatorMappingProviders);
+ }
+ configured = new DualValidationMappingProvider(AnnotationDeclaredValidatorMappingProvider.INSTANCE, custom);
+ }
+ // interpret spec as saying that default constraint validators are
+ // always present even when annotation-based validators
+ // have been excluded by custom (i.e. XML) config:
+ return new DualValidationMappingProvider(configured, ConstraintDefaults.INSTANCE);
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
index 3e3771e..9ea93e7 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDefaults.java
@@ -21,101 +21,70 @@ package org.apache.bval.jsr;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import javax.validation.ConstraintValidator;
+import org.apache.bval.jsr.metadata.ClassLoadingValidatorMappingProvider;
+import org.apache.bval.jsr.metadata.ValidatorMapping;
import org.apache.bval.util.StringUtils;
import org.apache.bval.util.reflection.Reflection;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
/**
- * Description: Provides access to the default constraints/validator implementation classes built into the framework.
- * These are configured in DefaultConstraints.properties.<br/>
+ * Description: Provides access to the default constraints/validator
+ * implementation classes built into the framework. These are configured in
+ * DefaultConstraints.properties.<br/>
*/
@Privilizing(@CallTo(Reflection.class))
-public class ConstraintDefaults {
+public class ConstraintDefaults extends ClassLoadingValidatorMappingProvider {
+ public static final ConstraintDefaults INSTANCE = new ConstraintDefaults();
+
private static final Logger log = Logger.getLogger(ConstraintDefaults.class.getName());
private static final String DEFAULT_CONSTRAINTS = "org/apache/bval/jsr/DefaultConstraints.properties";
- /**
- * The default constraint data stored herein.
- */
- private Map<String, Class<? extends ConstraintValidator<?, ?>>[]> defaultConstraints;
+ private final Properties properties;
/**
* Create a new ConstraintDefaults instance.
*/
- public ConstraintDefaults() {
- defaultConstraints = loadDefaultConstraints(DEFAULT_CONSTRAINTS);
- }
-
- /**
- * Get the default constraint data.
- * @return String-keyed map
- */
- public Map<String, Class<? extends ConstraintValidator<?, ?>>[]> getDefaultConstraints() {
- return defaultConstraints;
- }
-
- /**
- * Get the default validator implementation types for the specified constraint annotation type.
- * @param annotationType the annotation type
- * @return array of {@link ConstraintValidator} implementation classes
- */
- @SuppressWarnings("unchecked")
- public <A extends Annotation> Class<? extends ConstraintValidator<A, ?>>[] getValidatorClasses(
- Class<A> annotationType) {
- return (Class<? extends ConstraintValidator<A, ?>>[]) getDefaultConstraints().get(annotationType.getName());
+ private ConstraintDefaults() {
+ this.properties = loadProperties(DEFAULT_CONSTRAINTS);
}
- @SuppressWarnings("unchecked")
- private Map<String, Class<? extends ConstraintValidator<?, ?>>[]> loadDefaultConstraints(String resource) {
- final Properties constraintProperties = new Properties();
+ private Properties loadProperties(String resource) {
+ final Properties result = new Properties();
final ClassLoader classloader = getClassLoader();
- final InputStream stream = classloader.getResourceAsStream(resource);
- if (stream == null) {
- log.log(Level.WARNING, String.format("Cannot find %s", resource));
- } else {
- try {
- constraintProperties.load(stream);
- } catch (IOException e) {
- log.log(Level.SEVERE, String.format("Cannot load %s", resource), e);
- } finally {
- try {
- stream.close();
- } catch (final IOException e) {
- // no-op
- }
+ try (final InputStream stream = classloader.getResourceAsStream(resource)) {
+ if (stream == null) {
+ log.log(Level.WARNING, String.format("Cannot find %s", resource));
+ } else {
+ result.load(stream);
}
+ } catch (IOException e) {
+ log.log(Level.SEVERE, String.format("Cannot load %s", resource), e);
}
+ return result;
+ }
- final Map<String, Class<? extends ConstraintValidator<?, ?>>[]> loadedConstraints =
- new HashMap<String, Class<? extends ConstraintValidator<?, ?>>[]>();
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ @Override
+ public <A extends Annotation> ValidatorMapping<A> doGetValidatorMapping(Class<A> constraintType) {
- for (final Map.Entry<Object, Object> entry : constraintProperties.entrySet()) {
- final List<Class<?>> classes = new LinkedList<Class<?>>();
- for (String className : StringUtils.split((String) entry.getValue(), ',')) {
- try {
- classes.add(Reflection.toClass(className.trim(), classloader));
- } catch (Exception e) {
- log.log(Level.SEVERE, String.format("Cannot find class %s", className), e);
- }
- }
- loadedConstraints.put((String) entry.getKey(), classes.toArray(new Class[classes.size()]));
- }
- return loadedConstraints;
- }
+ final String validators = properties.getProperty(constraintType.getName());
- private ClassLoader getClassLoader() {
- final ClassLoader classloader = Thread.currentThread().getContextClassLoader();
- return classloader == null ? getClass().getClassLoader() : classloader;
+ if (StringUtils.isBlank(validators)) {
+ return null;
+ }
+ return new ValidatorMapping<>("built-in",
+ load(Stream.of(StringUtils.split(validators, ',')).map(String::trim),
+ (Class<ConstraintValidator<A, ?>>) (Class) ConstraintValidator.class,
+ e -> log.log(Level.SEVERE, "exception loading default constraint validators", e))
+ .collect(Collectors.toList()));
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
index a56e1e1..c4c9d99 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
@@ -21,6 +21,7 @@ package org.apache.bval.jsr;
import javax.validation.ConstraintTarget;
import javax.validation.Payload;
import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ValidateUnwrappedValue;
import java.io.Serializable;
import java.lang.annotation.Annotation;
@@ -220,4 +221,16 @@ public class ConstraintDescriptorImpl<T extends Annotation> implements Constrain
result = 31 * result + (template != null ? template.hashCode() : 0);
return result;
}
+
+ @Override
+ public ValidateUnwrappedValue getValueUnwrapping() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <U> U unwrap(Class<U> arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java
index 5b51141..5ba14ca 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidation.java
@@ -39,6 +39,8 @@ import javax.validation.ValidationException;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
import javax.validation.metadata.ConstraintDescriptor;
+import javax.validation.metadata.ValidateUnwrappedValue;
+
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
@@ -54,6 +56,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
* Description: Adapter between Constraint (JSR303) and Validation (Core)<br/>
@@ -328,10 +331,12 @@ public class ConstraintValidation<T extends Annotation> implements Validation, C
throw new UnexpectedTypeException(message);
}
if (types.size() > 1) {
- throw new UnexpectedTypeException(
- String.format("Ambiguous validators for type %s. See: @%s at %s. Validators are: %s",
- stringForType(targetType), anno.annotationType().getSimpleName(), stringForLocation(owner, access),
- StringUtils.join(types, ", ")));
+ throw new UnexpectedTypeException(String.format(
+ "Ambiguous validators for type %s. See: @%s at %s. Validators are: %s",
+ stringForType(targetType),
+ anno.annotationType().getSimpleName(),
+ stringForLocation(owner, access), types.stream()
+ .map(Object::toString).collect(Collectors.joining(", "))));
}
}
@@ -524,9 +529,13 @@ public class ConstraintValidation<T extends Annotation> implements Validation, C
* {@inheritDoc}
*/
@Override
- @SuppressWarnings("unchecked")
+ @SuppressWarnings({ "unchecked", "rawtypes" })
public Set<ConstraintDescriptor<?>> getComposingConstraints() {
- return composedConstraints == null ? Collections.EMPTY_SET : composedConstraints;
+ if (composedConstraints == null) {
+ return Collections.emptySet();
+ }
+ final Set result = composedConstraints;
+ return result;
}
/**
@@ -581,4 +590,16 @@ public class ConstraintValidation<T extends Annotation> implements Validation, C
public void setValidated(final boolean validated) {
this.validated = validated;
}
+
+ @Override
+ public ValidateUnwrappedValue getValueUnwrapping() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public <U> U unwrap(Class<U> arg0) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java
index 3599603..930170d 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorContextImpl.java
@@ -25,6 +25,7 @@ import org.apache.bval.jsr.util.NodeImpl;
import org.apache.bval.jsr.util.PathImpl;
import org.apache.bval.model.ValidationListener;
+import javax.validation.ClockProvider;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Path;
@@ -38,7 +39,10 @@ import java.util.List;
* Description: Short-lived {@link ConstraintValidatorContext} implementation passed by
* a {@link ConstraintValidation} to its adapted {@link ConstraintValidator}. <br/>
*/
-public class ConstraintValidatorContextImpl implements ConstraintValidatorContext {
+@Deprecated
+public class ConstraintValidatorContextImpl
+ extends org.apache.bval.jsr.job.ConstraintValidatorContextImpl<Object>
+ implements ConstraintValidatorContext {
private final List<ValidationListener.Error> errorMessages = new LinkedList<ValidationListener.Error>();
private final ConstraintValidation<?> constraintDescriptor;
@@ -53,6 +57,7 @@ public class ConstraintValidatorContextImpl implements ConstraintValidatorContex
*/
public ConstraintValidatorContextImpl(GroupValidationContext<?> validationContext,
ConstraintValidation<?> aConstraintValidation) {
+ super();
this.validationContext = validationContext;
this.constraintDescriptor = aConstraintValidation;
}
@@ -154,6 +159,13 @@ public class ConstraintValidatorContextImpl implements ConstraintValidatorContex
parent.addError(messageTemplate, propertyPath);
return parent;
}
+
+ @Override
+ public ContainerElementNodeBuilderCustomizableContext addContainerElementNode(
+ String arg0, Class<?> arg1, Integer arg2) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
/**
@@ -190,4 +202,10 @@ public class ConstraintValidatorContextImpl implements ConstraintValidatorContex
public void addError(String messageTemplate, Path propertyPath) {
errorMessages.add(new ValidationListener.Error(messageTemplate, propertyPath, null));
}
+
+ @Override
+ public ClockProvider getClockProvider() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java
index 1092323..572c39a 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintValidatorIdentity.java
@@ -19,6 +19,8 @@
package org.apache.bval.jsr;
+import java.util.Objects;
+
import javax.validation.ConstraintValidator;
import javax.validation.Path;
@@ -120,12 +122,7 @@ final class ConstraintValidatorIdentity {
*/
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((this.bean == null) ? 0 : this.bean.hashCode());
- result = prime * result + ((this.path == null) ? 0 : this.path.hashCode());
- result = prime * result + ((this.constraintValidator == null) ? 0 : this.constraintValidator.hashCode());
- return result;
+ return Objects.hash(bean, path, constraintValidator);
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
index c367b8e..91ae20d 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintViolationImpl.java
@@ -20,15 +20,20 @@ import javax.validation.ConstraintViolation;
import javax.validation.Path;
import javax.validation.ValidationException;
import javax.validation.metadata.ConstraintDescriptor;
+
+import org.apache.bval.util.Exceptions;
+
import java.io.Serializable;
import java.lang.annotation.ElementType;
import java.util.Arrays;
+import java.util.Objects;
/**
* Description: Describe a constraint validation defect.<br/>
- * From rootBean and propertyPath, it is possible to rebuild the context of the failure
+ * From rootBean and propertyPath, it is possible to rebuild the context of the
+ * failure
*/
-class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable {
+public class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable {
/** Serialization version */
private static final long serialVersionUID = 1L;
@@ -49,8 +54,11 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
/**
* Create a new ConstraintViolationImpl instance.
- * @param messageTemplate - message reason (raw message)
- * @param message - interpolated message (locale specific)
+ *
+ * @param messageTemplate
+ * - message reason (raw message)
+ * @param message
+ * - interpolated message (locale specific)
* @param rootBean
* @param leafBean
* @param propertyPath
@@ -79,8 +87,8 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
}
/**
- * {@inheritDoc}
- * former name getInterpolatedMessage()
+ * {@inheritDoc} former name getInterpolatedMessage()
+ *
* @return The interpolated error message for this constraint violation.
*/
@Override
@@ -98,6 +106,7 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
/**
* {@inheritDoc}
+ *
* @return Root bean being validated
*/
@Override
@@ -133,6 +142,7 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
/**
* {@inheritDoc}
+ *
* @return The value failing to pass the constraint
*/
@Override
@@ -142,8 +152,9 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
/**
* {@inheritDoc}
- * @return the property path to the value from <code>rootBean</code>
- * Null if the value is the rootBean itself
+ *
+ * @return the property path to the value from <code>rootBean</code> Null if
+ * the value is the rootBean itself
*/
@Override
public Path getPropertyPath() {
@@ -160,10 +171,8 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
@Override
public <U> U unwrap(Class<U> type) {
- if (type.isInstance(this)) {
- return type.cast(this);
- }
- throw new ValidationException("Type " + type + " is not supported");
+ Exceptions.raiseUnless(type.isInstance(this), ValidationException::new, "Type %s is not supported", type);
+ return type.cast(this);
}
/**
@@ -171,45 +180,28 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
*/
@Override
public String toString() {
- return "ConstraintViolationImpl{" + "rootBean=" + rootBean + ", propertyPath='" + propertyPath + '\''
- + ", message='" + message + '\'' + ", leafBean=" + leafBean + ", value=" + value + '}';
+ return String.format("%s{rootBean=%s, propertyPath='%s', message='%s', leafBean=%s, value=%s}",
+ ConstraintViolationImpl.class.getSimpleName(), rootBean, propertyPath, message, leafBean, value);
}
@Override
public boolean equals(Object o) {
- if (this == o)
+ if (this == o) {
return true;
- if (o == null || getClass() != o.getClass())
+ }
+ if (o == null || !getClass().equals(o.getClass())) {
return false;
+ }
- ConstraintViolationImpl that = (ConstraintViolationImpl) o;
-
- if (constraintDescriptor != null ? !constraintDescriptor.equals(that.constraintDescriptor)
- : that.constraintDescriptor != null)
- return false;
- if (elementType != that.elementType)
- return false;
- if (leafBean != null ? !leafBean.equals(that.leafBean) : that.leafBean != null)
- return false;
- if (message != null ? !message.equals(that.message) : that.message != null)
- return false;
- if (messageTemplate != null ? !messageTemplate.equals(that.messageTemplate) : that.messageTemplate != null)
- return false;
- // Probably incorrect - comparing Object[] arrays with Arrays.equals
- if (!Arrays.equals(parameters, that.parameters))
- return false;
- if (propertyPath != null ? !propertyPath.equals(that.propertyPath) : that.propertyPath != null)
- return false;
- if (returnValue != null ? !returnValue.equals(that.returnValue) : that.returnValue != null)
- return false;
- if (rootBean != null ? !rootBean.equals(that.rootBean) : that.rootBean != null)
- return false;
- if (rootBeanClass != null ? !rootBeanClass.equals(that.rootBeanClass) : that.rootBeanClass != null)
- return false;
- if (value != null ? !value.equals(that.value) : that.value != null)
- return false;
+ @SuppressWarnings("rawtypes")
+ final ConstraintViolationImpl that = (ConstraintViolationImpl) o;
- return true;
+ return Objects.equals(constraintDescriptor, that.constraintDescriptor) && elementType == that.elementType
+ && Objects.equals(leafBean, that.leafBean) && Objects.equals(message, that.message)
+ && Objects.equals(messageTemplate, that.messageTemplate) && Arrays.equals(parameters, that.parameters)
+ && Objects.equals(propertyPath, that.propertyPath) && Objects.equals(returnValue, that.returnValue)
+ && Objects.equals(rootBean, that.rootBean) && Objects.equals(rootBeanClass, that.rootBeanClass)
+ && Objects.equals(value, that.value);
}
@Override
@@ -217,18 +209,10 @@ class ConstraintViolationImpl<T> implements ConstraintViolation<T>, Serializable
return hashCode;
}
- public int computeHashCode() {
- int result = messageTemplate != null ? messageTemplate.hashCode() : 0;
- result = 31 * result + (message != null ? message.hashCode() : 0);
- result = 31 * result + (rootBean != null ? rootBean.hashCode() : 0);
- result = 31 * result + (rootBeanClass != null ? rootBeanClass.hashCode() : 0);
- result = 31 * result + (leafBean != null ? leafBean.hashCode() : 0);
- result = 31 * result + (value != null ? value.hashCode() : 0);
- result = 31 * result + (propertyPath != null ? propertyPath.hashCode() : 0);
- result = 31 * result + (elementType != null ? elementType.hashCode() : 0);
- result = 31 * result + (constraintDescriptor != null ? constraintDescriptor.hashCode() : 0);
- result = 31 * result + (returnValue != null ? returnValue.hashCode() : 0);
- result = 31 * result + (parameters != null ? Arrays.hashCode(parameters) : 0);
+ private int computeHashCode() {
+ int result = Objects.hash(messageTemplate, message, rootBean, rootBeanClass, leafBean, value, propertyPath,
+ elementType, constraintDescriptor, returnValue);
+ result = 31 * result + (parameters == null ? 0 : Arrays.hashCode(parameters));
return result;
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java
index 4aca48a..9474705 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultConstraintValidatorFactory.java
@@ -32,8 +32,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
* Description: create constraint instances with the default / no-arg constructor <br/>
*/
public class DefaultConstraintValidatorFactory implements ConstraintValidatorFactory, Closeable {
- private final Collection<BValExtension.Releasable<?>> releasables =
- new CopyOnWriteArrayList<BValExtension.Releasable<?>>();
+ private final Collection<BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<>();
private volatile Boolean useCdi = null; // store it to avoid NoClassDefFoundError when cdi is not present (it is slow) + lazily (to wait cdi is started)
/**
@@ -49,9 +48,7 @@ public class DefaultConstraintValidatorFactory implements ConstraintValidatorFac
if (useCdi == null) {
try {
useCdi = BValExtension.getBeanManager() != null;
- } catch (final NoClassDefFoundError error) {
- useCdi = Boolean.FALSE;
- } catch (final Exception e) {
+ } catch (NoClassDefFoundError | Exception error) {
useCdi = Boolean.FALSE;
}
}
@@ -69,10 +66,7 @@ public class DefaultConstraintValidatorFactory implements ConstraintValidatorFac
return instance.getInstance();
}
throw new IllegalStateException("Can't create " + constraintClass.getName());
- } catch (final Exception e) {
- return constraintClass.newInstance();
- } catch (final NoClassDefFoundError error) {
- return constraintClass.newInstance();
+ } catch (Exception | NoClassDefFoundError e) {
}
}
return constraintClass.newInstance();
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
index 8c77162..6a85a2a 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultMessageInterpolator.java
@@ -54,10 +54,10 @@ public class DefaultMessageInterpolator implements MessageInterpolator {
private Locale defaultLocale;
/** User specified resource bundles hashed against their locale. */
- private final Map<Locale, ResourceBundle> userBundlesMap = new ConcurrentHashMap<Locale, ResourceBundle>();
+ private final Map<Locale, ResourceBundle> userBundlesMap = new ConcurrentHashMap<>();
/** Builtin resource bundles hashed against their locale. */
- private final Map<Locale, ResourceBundle> defaultBundlesMap = new ConcurrentHashMap<Locale, ResourceBundle>();
+ private final Map<Locale, ResourceBundle> defaultBundlesMap = new ConcurrentHashMap<>();
private final MessageEvaluator evaluator;
@@ -83,12 +83,12 @@ public class DefaultMessageInterpolator implements MessageInterpolator {
userBundlesMap.put(defaultLocale, resourceBundle);
}
- MessageEvaluator ev = null;
+ MessageEvaluator ev;
try {
ev = MessageEvaluator.class
.cast(getClass().getClassLoader().loadClass("org.apache.bval.el.ELFacade").newInstance());
} catch (final Throwable e) { // can be exception or error
- // no-op
+ ev = null;
}
evaluator = ev;
}
@@ -170,47 +170,42 @@ public class DefaultMessageInterpolator implements MessageInterpolator {
* @return the resource bundle or <code>null</code> if none is found.
*/
private ResourceBundle getFileBasedResourceBundle(Locale locale) {
- ResourceBundle rb = null;
+ ResourceBundle rb;
final ClassLoader classLoader = Reflection.getClassLoader(DefaultMessageInterpolator.class);
if (classLoader != null) {
rb = loadBundle(classLoader, locale, USER_VALIDATION_MESSAGES + " not found by thread local classloader");
- }
-
+ } else {
// 2011-03-27 jw: No privileged action required.
// A class can always access the classloader of itself and of subclasses.
- if (rb == null) {
rb = loadBundle(getClass().getClassLoader(), locale,
USER_VALIDATION_MESSAGES + " not found by validator classloader");
}
if (LOG_FINEST) {
- if (rb != null) {
- log.log(Level.FINEST, String.format("%s found", USER_VALIDATION_MESSAGES));
- } else {
+ if (rb == null) {
log.log(Level.FINEST, String.format("%s not found. Delegating to %s", USER_VALIDATION_MESSAGES,
DEFAULT_VALIDATION_MESSAGES));
+ } else {
+ log.log(Level.FINEST, String.format("%s found", USER_VALIDATION_MESSAGES));
}
}
return rb;
}
private ResourceBundle loadBundle(ClassLoader classLoader, Locale locale, String message) {
- ResourceBundle rb = null;
try {
- rb = ResourceBundle.getBundle(USER_VALIDATION_MESSAGES, locale, classLoader);
+ return ResourceBundle.getBundle(USER_VALIDATION_MESSAGES, locale, classLoader);
} catch (final MissingResourceException e) {
log.fine(message);
}
- return rb;
+ return null;
}
private String replaceVariables(String message, ResourceBundle bundle, Locale locale, boolean recurse) {
final Matcher matcher = messageParameterPattern.matcher(message);
final StringBuffer sb = new StringBuffer(64);
- String resolvedParameterValue;
while (matcher.find()) {
final String parameter = matcher.group(1);
- resolvedParameterValue = resolveParameter(parameter, bundle, locale, recurse);
-
+ String resolvedParameterValue = resolveParameter(parameter, bundle, locale, recurse);
matcher.appendReplacement(sb, sanitizeForAppendReplacement(resolvedParameterValue));
}
matcher.appendTail(sb);
@@ -242,13 +237,13 @@ public class DefaultMessageInterpolator implements MessageInterpolator {
private String resolveParameter(String parameterName, ResourceBundle bundle, Locale locale, boolean recurse) {
String parameterValue;
try {
- if (bundle != null) {
+ if (bundle == null) {
+ parameterValue = parameterName;
+ } else {
parameterValue = bundle.getString(removeCurlyBrace(parameterName));
if (recurse) {
parameterValue = replaceVariables(parameterValue, bundle, locale, recurse);
}
- } else {
- parameterValue = parameterName;
}
} catch (final MissingResourceException e) {
// return parameter itself
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java
index 671b0d9..e63bdf4 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/DefaultValidationProviderResolver.java
@@ -38,6 +38,11 @@ public class DefaultValidationProviderResolver implements ValidationProviderReso
//TODO - Spec recommends caching per classloader
private static final String SPI_CFG = "META-INF/services/javax.validation.spi.ValidationProvider";
+ private static ClassLoader getCurrentClassLoader() {
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ return cl == null ? DefaultValidationProviderResolver.class.getClassLoader() : cl;
+ }
+
/**
* {@inheritDoc}
*/
@@ -46,43 +51,28 @@ public class DefaultValidationProviderResolver implements ValidationProviderReso
List<ValidationProvider<?>> providers = new ArrayList<ValidationProvider<?>>();
try {
// get our classloader
- ClassLoader cl = Thread.currentThread().getContextClassLoader();
- if (cl == null)
- cl = DefaultValidationProviderResolver.class.getClassLoader();
+ ClassLoader cl = getCurrentClassLoader();
// find all service provider cfgs
Enumeration<URL> cfgs = cl.getResources(SPI_CFG);
while (cfgs.hasMoreElements()) {
final URL url = cfgs.nextElement();
- BufferedReader br = null;
- try {
- br = new BufferedReader(new InputStreamReader(url.openStream()), 256);
- String line = br.readLine();
- // cfgs may contain multiple providers and/or comments
- while (line != null) {
- line = line.trim();
- if (!line.startsWith("#")) {
- try {
- // try loading the specified class
- @SuppressWarnings("rawtypes")
- final Class<? extends ValidationProvider> providerType =
- cl.loadClass(line).asSubclass(ValidationProvider.class);
- // create an instance to return
- providers
- .add(Reflection.newInstance(providerType.asSubclass(ValidationProvider.class)));
-
- } catch (ClassNotFoundException e) {
- throw new ValidationException(
- "Failed to load provider " + line + " configured in file " + url, e);
- }
+ try (BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()), 256)) {
+ br.lines().filter(s -> s.charAt(0) != '#').map(String::trim).forEach(line -> {
+ // cfgs may contain multiple providers and/or comments
+ try {
+ // try loading the specified class
+ @SuppressWarnings("rawtypes")
+ final Class<? extends ValidationProvider> providerType =
+ cl.loadClass(line).asSubclass(ValidationProvider.class);
+ // create an instance to return
+ providers.add(Reflection.newInstance(providerType));
+ } catch (ClassNotFoundException e) {
+ throw new ValidationException(
+ "Failed to load provider " + line + " configured in file " + url, e);
}
- line = br.readLine();
- }
+ });
} catch (IOException e) {
throw new ValidationException("Error trying to read " + url, e);
- } finally {
- if (br != null) {
- br.close();
- }
}
}
} catch (IOException e) {
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/GraphBeanIdentity.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/GraphBeanIdentity.java b/bval-jsr/src/main/java/org/apache/bval/jsr/GraphBeanIdentity.java
index 3ec666e..26391e6 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/GraphBeanIdentity.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/GraphBeanIdentity.java
@@ -18,6 +18,8 @@
*/
package org.apache.bval.jsr;
+import java.util.Objects;
+
/**
* Class that stores the needed properties to avoid circular paths when
* validating an object graph.
@@ -80,32 +82,16 @@ public class GraphBeanIdentity {
*/
@Override
public boolean equals(Object obj) {
-
if (this == obj) {
return true;
}
-
- if (obj == null) {
- return false;
- }
-
if (!(obj instanceof GraphBeanIdentity)) {
return false;
}
-
GraphBeanIdentity other = (GraphBeanIdentity) obj;
- // Bean ref must be the same
- if (this.bean != other.bean) {
- return false;
- }
-
- // Group ref must be the same
- if (this.group != other.group) {
- return false;
- }
-
- return true;
+ // Bean ref must be the same; Group ref must be the same
+ return bean == other.bean && group == other.group;
}
/**
@@ -113,11 +99,7 @@ public class GraphBeanIdentity {
*/
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + ((this.bean == null) ? 0 : this.bean.hashCode());
- result = prime * result + ((this.group == null) ? 0 : this.group.hashCode());
- return result;
+ return Objects.hash(bean, group);
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ParameterDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ParameterDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ParameterDescriptorImpl.java
index 187fd7e..65f3ecc 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ParameterDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ParameterDescriptorImpl.java
@@ -21,6 +21,7 @@ import org.apache.bval.jsr.groups.GroupConversionDescriptorImpl;
import org.apache.bval.model.MetaBean;
import org.apache.bval.model.Validation;
+import javax.validation.metadata.ContainerElementTypeDescriptor;
import javax.validation.metadata.GroupConversionDescriptor;
import javax.validation.metadata.ParameterDescriptor;
import java.util.Set;
@@ -86,4 +87,10 @@ public class ParameterDescriptorImpl extends ElementDescriptorImpl implements Pa
groupConversions.add(new GroupConversionDescriptorImpl(from, to));
super.addGroupMapping(from, to);
}
+
+ @Override
+ public Set<ContainerElementTypeDescriptor> getConstrainedContainerElementTypes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/PropertyDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/PropertyDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/PropertyDescriptorImpl.java
index 7f7c56d..03cf5de 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/PropertyDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/PropertyDescriptorImpl.java
@@ -21,6 +21,9 @@ package org.apache.bval.jsr;
import org.apache.bval.model.Features;
import org.apache.bval.model.MetaProperty;
+import java.util.Set;
+
+import javax.validation.metadata.ContainerElementTypeDescriptor;
import javax.validation.metadata.PropertyDescriptor;
/**
@@ -67,4 +70,10 @@ class PropertyDescriptorImpl extends ElementDescriptorImpl implements PropertyDe
return "PropertyDescriptorImpl{" + "returnType=" + elementClass + ", propertyPath='" + propertyPath + '\''
+ '}';
}
+
+ @Override
+ public Set<ContainerElementTypeDescriptor> getConstrainedContainerElementTypes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/ReturnValueDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ReturnValueDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ReturnValueDescriptorImpl.java
index b1fc72d..a6faa9b 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ReturnValueDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ReturnValueDescriptorImpl.java
@@ -18,8 +18,10 @@ package org.apache.bval.jsr;
import org.apache.bval.model.MetaBean;
+import javax.validation.metadata.ContainerElementTypeDescriptor;
import javax.validation.metadata.ReturnValueDescriptor;
import java.util.Collection;
+import java.util.Set;
public class ReturnValueDescriptorImpl extends ElementDescriptorImpl implements ReturnValueDescriptor {
public ReturnValueDescriptorImpl(final MetaBean metaBean, Class<?> returnType,
@@ -32,4 +34,10 @@ public class ReturnValueDescriptorImpl extends ElementDescriptorImpl implements
public boolean hasConstraints() {
return false;
}
+
+ @Override
+ public Set<ContainerElementTypeDescriptor> getConstrainedContainerElementTypes() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
index 4f9d10a..6a211ed 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Group.java
@@ -18,6 +18,8 @@
*/
package org.apache.bval.jsr.groups;
+import java.util.Objects;
+
import javax.validation.groups.Default;
/**
@@ -52,7 +54,7 @@ public final class Group {
*/
@Override
public String toString() {
- return "Group{" + "group=" + group + '}';
+ return String.format("%s{group=%s}", Group.class.getSimpleName(), group);
}
/**
@@ -71,13 +73,10 @@ public final class Group {
if (this == o) {
return true;
}
- if (o == null || getClass() != o.getClass()) {
+ if (o == null || !getClass().equals(o.getClass())) {
return false;
}
-
- Group group1 = (Group) o;
-
- return group != null ? group.equals(group1.group) : group1.group == null;
+ return Objects.equals(group, ((Group) o).group);
}
/**
@@ -85,6 +84,6 @@ public final class Group {
*/
@Override
public int hashCode() {
- return (group != null ? group.hashCode() : 0);
+ return Objects.hashCode(group);
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversionDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversionDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversionDescriptorImpl.java
index ba3a617..6d45ced 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversionDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupConversionDescriptorImpl.java
@@ -26,10 +26,9 @@ public class GroupConversionDescriptorImpl implements GroupConversionDescriptor
public GroupConversionDescriptorImpl(final Group from, final Group to) {
this.from = from.getGroup();
- if (this.from.getAnnotation(GroupSequence.class) != null) {
+ if (this.from.isAnnotationPresent(GroupSequence.class)) {
throw new ConstraintDeclarationException("from() can't get a group sequence");
}
-
this.to = to.getGroup();
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
index 162bb66..3e7f008 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/Groups.java
@@ -18,25 +18,29 @@
*/
package org.apache.bval.jsr.groups;
-import javax.validation.GroupDefinitionException;
-import java.util.LinkedList;
+import java.util.ArrayList;
import java.util.List;
+import javax.validation.GroupDefinitionException;
+
+import org.apache.bval.util.Exceptions;
+
/**
- * Defines the order to validate groups during validation.
- * with some inspiration from reference implementation
+ * Defines the order to validate groups during validation. with some inspiration
+ * from reference implementation
*
* @author Roman Stumm
*/
public class Groups {
- /** The list of single groups. */
- final List<Group> groups = new LinkedList<Group>();
-
/** The list of sequences. */
- final List<List<Group>> sequences = new LinkedList<List<Group>>();
+ private final List<List<Group>> sequences = new ArrayList<>();
+
+ /** The list of single groups. */
+ final List<Group> groups = new ArrayList<>();
/**
* Get the Groups.
+ *
* @return {@link List} of {@link Group}.
*/
public List<Group> getGroups() {
@@ -45,6 +49,7 @@ public class Groups {
/**
* Get the Group sequences.
+ *
* @return {@link List} of {@link List} of {@link Group}
*/
public List<List<Group>> getSequences() {
@@ -53,7 +58,9 @@ public class Groups {
/**
* Insert a {@link Group}.
- * @param group to insert
+ *
+ * @param group
+ * to insert
*/
void insertGroup(Group group) {
if (!groups.contains(group)) {
@@ -63,52 +70,52 @@ public class Groups {
/**
* Insert a sequence.
- * @param groups {@link List} of {@link Group} to insert
+ *
+ * @param groups
+ * {@link List} of {@link Group} to insert
*/
void insertSequence(List<Group> groups) {
- if (groups == null || groups.isEmpty()) {
- return;
- }
-
- if (!sequences.contains(groups)) {
+ if (!(groups == null || groups.isEmpty() || sequences.contains(groups))) {
sequences.add(groups);
}
}
/**
- * Assert that the default group can be expanded to <code>defaultGroups</code>.
+ * Assert that the default group can be expanded to
+ * <code>defaultGroups</code>.
+ *
* @param defaultGroups
*/
public void assertDefaultGroupSequenceIsExpandable(List<Group> defaultGroups) {
for (List<Group> groupList : sequences) {
- int idx = groupList.indexOf(Group.DEFAULT);
- if (idx != -1) {
+ final int idx = groupList.indexOf(Group.DEFAULT);
+ if (idx >= 0) {
ensureExpandable(groupList, defaultGroups, idx);
}
}
}
private void ensureExpandable(List<Group> groupList, List<Group> defaultGroupList, int defaultGroupIndex) {
- for (int i = 0; i < defaultGroupList.size(); i++) {
- Group group = defaultGroupList.get(i);
+ for (int i = 0, sz = defaultGroupList.size(); i < sz; i++) {
+ final Group group = defaultGroupList.get(i);
if (group.isDefault()) {
continue; // the default group is the one we want to replace
}
- int index = groupList.indexOf(group); // sequence contains group of default group sequence
- if (index == -1) {
- continue; // if group is not in the sequence
+ // sequence contains group of default group sequence
+ final int index = groupList.indexOf(group);
+ if (index < 0) {
+ // group is not in the sequence
+ continue;
}
-
if ((i == 0 && index == defaultGroupIndex - 1)
|| (i == defaultGroupList.size() - 1 && index == defaultGroupIndex + 1)) {
- // if we are at the beginning or end of he defaultGroupSequence and the
- // matches are either directly before or after we can continue,
- // since we basically have two groups
+ // if we are at the beginning or end of he defaultGroupSequence
+ // and the matches are either directly before or after we can
+ // continue, since we basically have two groups
continue;
}
- throw new GroupDefinitionException(
- "Unable to expand default group list" + defaultGroupList + " into sequence " + groupList);
+ Exceptions.raise(GroupDefinitionException::new, "Unable to expand default group list %s into sequence %s",
+ defaultGroupList, groupList);
}
}
-
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
index 398d6c3..ae6f629 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/groups/GroupsComputer.java
@@ -18,126 +18,115 @@
*/
package org.apache.bval.jsr.groups;
-import javax.validation.GroupDefinitionException;
-import javax.validation.GroupSequence;
-import javax.validation.ValidationException;
-import javax.validation.groups.Default;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import javax.validation.GroupDefinitionException;
+import javax.validation.GroupSequence;
+import javax.validation.ValidationException;
+import javax.validation.groups.Default;
+
+import org.apache.bval.util.Exceptions;
+import org.apache.bval.util.Validate;
+
/**
* Description: compute group order, based on the RI behavior as to guarantee
* compatibility with interpretations of the spec.<br/>
* Implementation is thread-safe.
*/
public class GroupsComputer {
- public static final Class<?>[] DEFAULT_GROUP = new Class<?>[] { Default.class };
+ public static final Class<?>[] DEFAULT_GROUP = { Default.class };
- /** The default group array used in case any of the validate methods is called without a group. */
+ /**
+ * The default group array used in case any of the validate methods is
+ * called without a group.
+ */
private static final Groups DEFAULT_GROUPS;
static {
- DEFAULT_GROUPS = new GroupsComputer().computeGroups(Arrays.asList(DEFAULT_GROUP));
+ DEFAULT_GROUPS = new Groups();
+ for (Class<?> g : DEFAULT_GROUP) {
+ DEFAULT_GROUPS.insertGroup(new Group(g));
+ }
}
/** caching resolved groups in a thread-safe map. */
- private final Map<Class<?>, List<Group>> resolvedSequences = new ConcurrentHashMap<Class<?>, List<Group>>();
+ private final Map<Class<?>, List<Group>> resolvedSequences = new ConcurrentHashMap<>();
/**
* Compute groups from an array of group classes.
+ *
* @param groups
* @return {@link Groups}
*/
- public Groups computeGroups(Class<?>[] groups) {
- if (groups == null) {
- throw new IllegalArgumentException("null passed as group");
- }
-
- // if no groups is specified use the default
- if (groups.length == 0) {
- return DEFAULT_GROUPS;
- }
-
+ @SafeVarargs
+ public final Groups computeGroups(Class<?>... groups) {
+ Exceptions.raiseIf(groups == null, IllegalArgumentException::new, "null validation groups specified");
return computeGroups(Arrays.asList(groups));
}
/**
* Main compute implementation.
+ *
* @param groups
* @return {@link Groups}
*/
protected Groups computeGroups(Collection<Class<?>> groups) {
- if (groups == null || groups.size() == 0) {
- throw new IllegalArgumentException("At least one group has to be specified.");
+ Validate.notNull(groups, "groups");
+
+ if (groups.isEmpty() || Arrays.asList(DEFAULT_GROUP).equals(new ArrayList<>(groups))) {
+ return DEFAULT_GROUPS;
}
+ Exceptions.raiseIf(groups.stream().anyMatch(Objects::isNull), IllegalArgumentException::new,
+ "Null group specified");
for (final Class<?> clazz : groups) {
- if (clazz == null) {
- throw new IllegalArgumentException("At least one group has to be specified.");
- }
-
- if (!clazz.isInterface()) {
- throw new ValidationException("A group has to be an interface. " + clazz.getName() + " is not.");
- }
+ Exceptions.raiseUnless(clazz.isInterface(), ValidationException::new,
+ "A group must be an interface. %s is not.", clazz);
}
-
- Groups chain = new Groups();
+ final Groups chain = new Groups();
for (Class<?> clazz : groups) {
- GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
+ final GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
if (anno == null) {
- Group group = new Group(clazz);
- chain.insertGroup(group);
+ chain.insertGroup(new Group(clazz));
insertInheritedGroups(clazz, chain);
- } else {
- insertSequence(clazz, anno, chain);
+ continue;
}
+ chain.insertSequence(
+ resolvedSequences.computeIfAbsent(clazz, g -> resolveSequence(g, anno, new HashSet<>())));
}
-
return chain;
}
private void insertInheritedGroups(Class<?> clazz, Groups chain) {
for (Class<?> extendedInterface : clazz.getInterfaces()) {
- Group group = new Group(extendedInterface);
- chain.insertGroup(group);
+ chain.insertGroup(new Group(extendedInterface));
insertInheritedGroups(extendedInterface, chain);
}
}
- private void insertSequence(Class<?> clazz, GroupSequence anno, Groups chain) {
- List<Group> sequence;
- if (resolvedSequences.containsKey(clazz)) {
- sequence = resolvedSequences.get(clazz);
- } else {
- sequence = resolveSequence(clazz, anno, new HashSet<Class<?>>());
- }
- chain.insertSequence(sequence);
- }
-
private List<Group> resolveSequence(Class<?> group, GroupSequence sequenceAnnotation,
Set<Class<?>> processedSequences) {
- if (processedSequences.contains(group)) {
- throw new GroupDefinitionException("Cyclic dependency in groups definition");
- } else {
- processedSequences.add(group);
- }
- List<Group> resolvedGroupSequence = new LinkedList<Group>();
- Class<?>[] sequenceArray = sequenceAnnotation.value();
- for (Class<?> clazz : sequenceArray) {
- GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
+ Exceptions.raiseUnless(processedSequences.add(group), GroupDefinitionException::new,
+ "Cyclic dependency in groups definition");
+
+ final List<Group> resolvedGroupSequence = new ArrayList<>();
+ for (Class<?> clazz : sequenceAnnotation.value()) {
+ final GroupSequence anno = clazz.getAnnotation(GroupSequence.class);
if (anno == null) {
- resolvedGroupSequence.add(new Group(clazz)); // group part of sequence
+ // group part of sequence
+ resolvedGroupSequence.add(new Group(clazz));
} else {
- List<Group> tmpSequence = resolveSequence(clazz, anno, processedSequences); // recursion!
- resolvedGroupSequence.addAll(tmpSequence);
+ // recursion!
+ resolvedGroupSequence.addAll(resolveSequence(clazz, anno, processedSequences));
}
}
- resolvedSequences.put(group, resolvedGroupSequence);
return resolvedGroupSequence;
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/f87be824/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java b/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java
index 2b43bcd..dec9ae8 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/parameter/DefaultParameterNameProvider.java
@@ -18,30 +18,29 @@
*/
package org.apache.bval.jsr.parameter;
-import javax.validation.ParameterNameProvider;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Executable;
import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.lang.reflect.Parameter;
import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.validation.ParameterNameProvider;
public class DefaultParameterNameProvider implements ParameterNameProvider {
- private static final String ARG = "arg";
+
+ private static List<String> parameterNames(Executable exe) {
+ return Stream.of(exe.getParameters()).map(Parameter::getName).collect(Collectors.toList());
+ }
@Override
public List<String> getParameterNames(Constructor<?> constructor) {
- return names(constructor.getParameterTypes().length);
+ return parameterNames(constructor);
}
@Override
public List<String> getParameterNames(Method method) {
- return names(method.getParameterTypes().length);
- }
-
- private static List<String> names(final int length) {
- final List<String> list = new ArrayList<String>();
- for (int i = 0; i < length; i++) {
- list.add(ARG + i);
- }
- return list;
+ return parameterNames(method);
}
}