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:02 UTC
[12/17] bval git commit: BV2: new validation implementation
BV2: new validation implementation
Project: http://git-wip-us.apache.org/repos/asf/bval/repo
Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/05df7ee2
Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/05df7ee2
Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/05df7ee2
Branch: refs/heads/bv2
Commit: 05df7ee264cbef9199897b170e89bb7fcac58f26
Parents: a921963
Author: Matt Benson <mb...@apache.org>
Authored: Wed Feb 21 14:54:03 2018 -0600
Committer: Matt Benson <mb...@apache.org>
Committed: Wed Feb 21 14:59:58 2018 -0600
----------------------------------------------------------------------
.../apache/bval/jsr/ApacheFactoryContext.java | 83 ++++++---
.../bval/jsr/ApacheValidatorConfiguration.java | 7 +-
.../apache/bval/jsr/ApacheValidatorFactory.java | 171 ++++++++++++-------
.../bval/jsr/BootstrapConfigurationImpl.java | 29 +++-
.../bval/jsr/CascadingPropertyValidator.java | 96 ++++++++---
.../org/apache/bval/jsr/ConfigurationImpl.java | 128 ++++++++------
.../java/org/apache/bval/jsr/ValidatorImpl.java | 141 +++++++++++++++
7 files changed, 494 insertions(+), 161 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
index 8f68b9e..1e4b263 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheFactoryContext.java
@@ -18,46 +18,56 @@
*/
package org.apache.bval.jsr;
-import org.apache.bval.MetaBeanFinder;
-import org.apache.bval.util.reflection.Reflection;
-import org.apache.commons.weaver.privilizer.Privilizing;
-import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-
+import javax.validation.ClockProvider;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
import javax.validation.TraversableResolver;
import javax.validation.Validator;
import javax.validation.ValidatorContext;
+import javax.validation.valueextraction.ValueExtractor;
+
+import org.apache.bval.MetaBeanFinder;
+import org.apache.bval.jsr.descriptor.DescriptorManager;
+import org.apache.bval.jsr.groups.GroupsComputer;
+import org.apache.bval.jsr.valueextraction.ValueExtractors;
+import org.apache.bval.util.Lazy;
+import org.apache.bval.util.reflection.Reflection;
+import org.apache.commons.weaver.privilizer.Privilizing;
+import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
/**
- * Description: Represents the context that is used to create
- * {@link ClassValidator} instances.
+ * Description: Represents the context that is used to create {@link ClassValidator} instances.
*/
@Privilizing(@CallTo(Reflection.class))
public class ApacheFactoryContext implements ValidatorContext {
+ private final Lazy<GroupsComputer> groupsComputer = new Lazy<>(GroupsComputer::new);
private final ApacheValidatorFactory factory;
+ private final ValueExtractors valueExtractors;
private volatile MetaBeanFinder metaBeanFinder;
private MessageInterpolator messageInterpolator;
private TraversableResolver traversableResolver;
private ParameterNameProvider parameterNameProvider;
private ConstraintValidatorFactory constraintValidatorFactory;
+ private ClockProvider clockProvider;
/**
* Create a new ApacheFactoryContext instance.
*
- * @param factory validator factory
- * @param metaBeanFinder meta finder
+ * @param factory
+ * validator factory
+ * @param metaBeanFinder
+ * meta finder
*/
public ApacheFactoryContext(ApacheValidatorFactory factory, MetaBeanFinder metaBeanFinder) {
this.factory = factory;
this.metaBeanFinder = metaBeanFinder;
+ valueExtractors = factory.getValueExtractors().createChild();
}
/**
- * Get the {@link ApacheValidatorFactory} used by this
- * {@link ApacheFactoryContext}.
+ * Get the {@link ApacheValidatorFactory} used by this {@link ApacheFactoryContext}.
*
* @return {@link ApacheValidatorFactory}
*/
@@ -75,13 +85,13 @@ public class ApacheFactoryContext implements ValidatorContext {
}
/**
- * Discard cached metadata. Calling this method unnecessarily has the effect of severly
- * limiting performance, therefore only do so when changes have been made that affect
- * validation metadata, i.e. particularly NOT in response to:
+ * Discard cached metadata. Calling this method unnecessarily has the effect of severly limiting performance,
+ * therefore only do so when changes have been made that affect validation metadata, i.e. particularly NOT in
+ * response to:
* <ul>
- * <li>{@link #messageInterpolator(MessageInterpolator)}</li>
- * <li>{@link #traversableResolver(TraversableResolver)}</li>
- * <li>{@link #constraintValidatorFactory(ConstraintValidatorFactory)</li>
+ * <li>{@link #messageInterpolator(MessageInterpolator)}</li>
+ * <li>{@link #traversableResolver(TraversableResolver)}</li>
+ * <li>{@link #constraintValidatorFactory(ConstraintValidatorFactory)</li>
* </ul>
*/
private synchronized void resetMeta() {
@@ -92,7 +102,7 @@ public class ApacheFactoryContext implements ValidatorContext {
* {@inheritDoc}
*/
@Override
- public ValidatorContext messageInterpolator(MessageInterpolator messageInterpolator) {
+ public ApacheFactoryContext messageInterpolator(MessageInterpolator messageInterpolator) {
this.messageInterpolator = messageInterpolator;
return this;
}
@@ -101,7 +111,7 @@ public class ApacheFactoryContext implements ValidatorContext {
* {@inheritDoc}
*/
@Override
- public ValidatorContext traversableResolver(TraversableResolver traversableResolver) {
+ public ApacheFactoryContext traversableResolver(TraversableResolver traversableResolver) {
this.traversableResolver = traversableResolver;
return this;
}
@@ -110,18 +120,30 @@ public class ApacheFactoryContext implements ValidatorContext {
* {@inheritDoc}
*/
@Override
- public ValidatorContext constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
+ public ApacheFactoryContext constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
this.constraintValidatorFactory = constraintValidatorFactory;
return this;
}
@Override
- public ValidatorContext parameterNameProvider(ParameterNameProvider parameterNameProvider) {
+ public ApacheFactoryContext parameterNameProvider(ParameterNameProvider parameterNameProvider) {
this.parameterNameProvider = parameterNameProvider;
resetMeta(); // needed since parameter names are a component of validation metadata
return this;
}
+ @Override
+ public ApacheFactoryContext clockProvider(ClockProvider clockProvider) {
+ this.clockProvider = clockProvider;
+ return this;
+ }
+
+ @Override
+ public ApacheFactoryContext addValueExtractor(ValueExtractor<?> extractor) {
+ valueExtractors.add(extractor);
+ return this;
+ }
+
/**
* Get the {@link ConstraintValidatorFactory}.
*
@@ -137,7 +159,7 @@ public class ApacheFactoryContext implements ValidatorContext {
*/
@Override
public Validator getValidator() {
- return new ClassValidator(this);
+ return new ValidatorImpl(this);
}
/**
@@ -162,6 +184,23 @@ public class ApacheFactoryContext implements ValidatorContext {
return parameterNameProvider == null ? factory.getParameterNameProvider() : parameterNameProvider;
}
+ public ClockProvider getClockProvider() {
+ return clockProvider == null ? factory.getClockProvider() : clockProvider;
+ }
+
+ public ValueExtractors getValueExtractors() {
+ return valueExtractors;
+ }
+
+ public DescriptorManager getDescriptorManager() {
+ // TODO handle context customizations
+ return factory.getDescriptorManager();
+ }
+
+ public GroupsComputer getGroupsComputer() {
+ return groupsComputer.get();
+ }
+
boolean isTreatMapsLikeBeans() {
return Boolean
.parseBoolean(factory.getProperties().get(ApacheValidatorConfiguration.Properties.TREAT_MAPS_LIKE_BEANS));
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
index fb64d4e..81187f3 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorConfiguration.java
@@ -32,7 +32,7 @@ public interface ApacheValidatorConfiguration extends Configuration<ApacheValida
/**
* Proprietary property keys for {@link ConfigurationImpl}
*/
- public interface Properties {
+ interface Properties {
/**
* the location where to look for the validation.xml file.
* default: "META-INF/validation.xml"
@@ -91,5 +91,10 @@ public interface ApacheValidatorConfiguration extends Configuration<ApacheValida
* </ol>
*/
String METABEAN_FACTORY_CLASSNAMES = "apache.bval.metabean-factory-classnames";
+
+ /**
+ * Size to use for caching of constraint-related information. Default is {@code 50}.
+ */
+ String CONSTRAINTS_CACHE_SIZE = "apache.bval.constraints-cache-size";
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
index 5e6a611..b516a73 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ApacheValidatorFactory.java
@@ -18,11 +18,39 @@
*/
package org.apache.bval.jsr;
+import java.io.Closeable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import javax.validation.ClockProvider;
+import javax.validation.ConstraintValidatorFactory;
+import javax.validation.MessageInterpolator;
+import javax.validation.ParameterNameProvider;
+import javax.validation.TraversableResolver;
+import javax.validation.Validation;
+import javax.validation.ValidationException;
+import javax.validation.Validator;
+import javax.validation.ValidatorFactory;
+import javax.validation.spi.ConfigurationState;
+
import org.apache.bval.IntrospectorMetaBeanFactory;
import org.apache.bval.MetaBeanBuilder;
import org.apache.bval.MetaBeanFactory;
import org.apache.bval.MetaBeanFinder;
import org.apache.bval.MetaBeanManager;
+import org.apache.bval.jsr.descriptor.DescriptorManager;
+import org.apache.bval.jsr.metadata.MetadataBuilders;
+import org.apache.bval.jsr.util.AnnotationsManager;
+import org.apache.bval.jsr.valueextraction.ValueExtractors;
import org.apache.bval.jsr.xml.AnnotationIgnores;
import org.apache.bval.jsr.xml.MetaConstraint;
import org.apache.bval.jsr.xml.ValidationMappingParser;
@@ -37,28 +65,6 @@ import org.apache.commons.weaver.privilizer.Privileged;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-import javax.validation.ConstraintValidatorFactory;
-import javax.validation.MessageInterpolator;
-import javax.validation.ParameterNameProvider;
-import javax.validation.TraversableResolver;
-import javax.validation.Validation;
-import javax.validation.ValidationException;
-import javax.validation.Validator;
-import javax.validation.ValidatorFactory;
-import javax.validation.spi.ConfigurationState;
-import java.io.Closeable;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
/**
* Description: a factory is a complete configurated object that can create
* validators.<br/>
@@ -68,13 +74,17 @@ import java.util.concurrent.ConcurrentMap;
public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
private static volatile ApacheValidatorFactory DEFAULT_FACTORY;
- private static final ConstraintDefaults DEFAULT_CONSTRAINTS = new ConstraintDefaults();
private MessageInterpolator messageResolver;
private TraversableResolver traversableResolver;
private ConstraintValidatorFactory constraintValidatorFactory;
private ParameterNameProvider parameterNameProvider;
+ private ClockProvider clockProvider;
private final Map<String, String> properties;
+ private final AnnotationsManager annotationsManager;
+ private final DescriptorManager descriptorManager = new DescriptorManager(this);
+ private final MetadataBuilders metadataBuilders = new MetadataBuilders();
+ private final ValueExtractors valueExtractors = new ValueExtractors();
/**
* information from xml parsing
@@ -89,7 +99,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
private final ConcurrentMap<Class<?>, List<AccessStrategy>> validAccesses;
private final ConcurrentMap<Class<?>, List<MetaConstraint<?, ? extends Annotation>>> constraintMap;
- private final Collection<Closeable> toClose = new ArrayList<Closeable>();
+ private final Collection<Closeable> toClose = new ArrayList<>();
private final MetaBeanFinder defaultMetaBeanFinder;
/**
@@ -112,7 +122,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
* @return a new instance of MetaBeanManager with adequate MetaBeanFactories
*/
protected MetaBeanFinder buildMetaBeanFinder() {
- final List<MetaBeanFactory> builders = new ArrayList<MetaBeanFactory>();
+ final List<MetaBeanFactory> builders = new ArrayList<>();
if (Boolean.parseBoolean(getProperties().get(ApacheValidatorConfiguration.Properties.ENABLE_INTROSPECTOR))) {
builders.add(new IntrospectorMetaBeanFactory());
}
@@ -121,9 +131,8 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
if (factoryClassNames != null) {
for (String clsName : factoryClassNames) {
// cast, relying on #createMetaBeanFactory to throw the exception if incompatible:
- @SuppressWarnings("unchecked")
final Class<? extends MetaBeanFactory> factoryClass =
- (Class<? extends MetaBeanFactory>) loadClass(clsName);
+ loadClass(clsName).asSubclass(MetaBeanFactory.class);
builders.add(createMetaBeanFactory(factoryClass));
}
}
@@ -173,24 +182,27 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
* Create a new ApacheValidatorFactory instance.
*/
public ApacheValidatorFactory(ConfigurationState configuration) {
- properties = new HashMap<String, String>(configuration.getProperties());
- defaultSequences = new HashMap<Class<?>, Class<?>[]>();
- validAccesses = new ConcurrentHashMap<Class<?>, List<AccessStrategy>>();
- constraintMap = new ConcurrentHashMap<Class<?>, List<MetaConstraint<?, ? extends Annotation>>>();
+ properties = new HashMap<>(configuration.getProperties());
+ defaultSequences = new HashMap<>();
+ validAccesses = new ConcurrentHashMap<>();
+ constraintMap = new ConcurrentHashMap<>();
parameterNameProvider = configuration.getParameterNameProvider();
messageResolver = configuration.getMessageInterpolator();
traversableResolver = configuration.getTraversableResolver();
constraintValidatorFactory = configuration.getConstraintValidatorFactory();
+ clockProvider = configuration.getClockProvider();
if (ConfigurationImpl.class.isInstance(configuration)) {
- final ConfigurationImpl impl = ConfigurationImpl.class.cast(configuration);
- toClose.add(impl.getClosable());
+ toClose.add(ConfigurationImpl.class.cast(configuration).getClosable());
}
new ValidationMappingParser(this).processMappingConfig(configuration.getMappingStreams());
defaultMetaBeanFinder = buildMetaBeanFinder();
+
+ configuration.getValueExtractors().forEach(valueExtractors::add);
+ annotationsManager = new AnnotationsManager(this);
}
/**
@@ -203,8 +215,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Shortcut method to create a new Validator instance with factory's
- * settings
+ * Shortcut method to create a new Validator instance with factory's settings
*
* @return the new validator instance
*/
@@ -271,6 +282,12 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
}
+ public void setClockProvider(final ClockProvider clockProvider) {
+ if (clockProvider != null) {
+ this.clockProvider = clockProvider;
+ }
+ }
+
/**
* {@inheritDoc}
*/
@@ -307,6 +324,11 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
@Override
+ public ClockProvider getClockProvider() {
+ return clockProvider;
+ }
+
+ @Override
public void close() {
try {
for (final Closeable c : toClose) {
@@ -319,13 +341,14 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Return an object of the specified type to allow access to the
- * provider-specific API. If the Bean Validation provider implementation
- * does not support the specified class, the ValidationException is thrown.
+ * Return an object of the specified type to allow access to the provider-specific API. If the Bean Validation
+ * provider implementation does not support the specified class, the ValidationException is thrown.
*
- * @param type the class of the object to be returned.
+ * @param type
+ * the class of the object to be returned.
* @return an instance of the specified class
- * @throws ValidationException if the provider does not support the call.
+ * @throws ValidationException
+ * if the provider does not support the call.
*/
@Override
public <T> T unwrap(final Class<T> type) {
@@ -365,15 +388,6 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Get the detected {@link ConstraintDefaults}.
- *
- * @return ConstraintDefaults
- */
- public ConstraintDefaults getDefaultConstraints() {
- return DEFAULT_CONSTRAINTS;
- }
-
- /**
* Get the detected {@link AnnotationIgnores}.
*
* @return AnnotationIgnores
@@ -392,8 +406,34 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Add a meta-constraint to this {@link ApacheValidatorFactory}'s runtime
- * customizations.
+ * Get the {@link AnnotationsManager}.
+ *
+ * @return {@link AnnotationsManager}
+ */
+ public AnnotationsManager getAnnotationsManager() {
+ return annotationsManager;
+ }
+
+ /**
+ * Get the {@link DescriptorManager}.
+ *
+ * @return {@link DescriptorManager}
+ */
+ public DescriptorManager getDescriptorManager() {
+ return descriptorManager;
+ }
+
+ /**
+ * Get the {@link ValueExtractors}.
+ *
+ * @return {@link ValueExtractors}
+ */
+ public ValueExtractors getValueExtractors() {
+ return valueExtractors;
+ }
+
+ /**
+ * Add a meta-constraint to this {@link ApacheValidatorFactory}'s runtime customizations.
*
* @param beanClass
* @param metaConstraint
@@ -401,7 +441,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
public void addMetaConstraint(final Class<?> beanClass, final MetaConstraint<?, ?> metaConstraint) {
List<MetaConstraint<?, ? extends Annotation>> slot = constraintMap.get(beanClass);
if (slot == null) {
- slot = new ArrayList<MetaConstraint<?, ? extends Annotation>>();
+ slot = new ArrayList<>();
final List<MetaConstraint<?, ? extends Annotation>> old = constraintMap.putIfAbsent(beanClass, slot);
if (old != null) {
slot = old;
@@ -420,7 +460,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
public void addValid(Class<?> beanClass, AccessStrategy accessStrategy) {
List<AccessStrategy> slot = validAccesses.get(beanClass);
if (slot == null) {
- slot = new ArrayList<AccessStrategy>();
+ slot = new ArrayList<>();
final List<AccessStrategy> old = validAccesses.putIfAbsent(beanClass, slot);
if (old != null) {
slot = old;
@@ -444,8 +484,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
*
* @param <T>
* @param beanClass
- * @return List of {@link MetaConstraint}s applicable to
- * <code>beanClass</code>
+ * @return List of {@link MetaConstraint}s applicable to <code>beanClass</code>
*/
public <T> List<MetaConstraint<T, ? extends Annotation>> getMetaConstraints(Class<T> beanClass) {
final List<MetaConstraint<?, ? extends Annotation>> slot = constraintMap.get(beanClass);
@@ -459,16 +498,15 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Get the {@link AccessStrategy} {@link List} indicating nested bean
- * validations that must be triggered in the course of validating a
- * <code>beanClass</code> graph.
+ * Get the {@link AccessStrategy} {@link List} indicating nested bean validations that must be triggered in the
+ * course of validating a <code>beanClass</code> graph.
*
* @param beanClass
* @return {@link List} of {@link AccessStrategy}
*/
public List<AccessStrategy> getValidAccesses(Class<?> beanClass) {
final List<AccessStrategy> slot = validAccesses.get(beanClass);
- return slot == null ? Collections.<AccessStrategy> emptyList() : Collections.unmodifiableList(slot);
+ return slot == null ? Collections.emptyList() : Collections.unmodifiableList(slot);
}
/**
@@ -481,6 +519,10 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
return safeArray(defaultSequences.get(beanClass));
}
+ public MetadataBuilders getMetadataBuilders() {
+ return metadataBuilders;
+ }
+
private static Class<?>[] safeArray(Class<?>... array) {
return array == null || array.length == 0 ? ObjectUtils.EMPTY_CLASS_ARRAY : array.clone();
}
@@ -519,9 +561,8 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * separate class to prevent the classloader to immediately load optional
- * classes: XMLMetaBeanManager, XMLMetaBeanFactory, XMLMetaBeanBuilder that
- * might not be available in the classpath
+ * separate class to prevent the classloader to immediately load optional classes: XMLMetaBeanManager,
+ * XMLMetaBeanFactory, XMLMetaBeanBuilder that might not be available in the classpath
*/
private static class XMLMetaBeanManagerCreator {
@@ -530,10 +571,10 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable {
}
/**
- * Create the {@link MetaBeanManager} to process JSR303 XML. Requires
- * bval-xstream at RT.
+ * Create the {@link MetaBeanManager} to process JSR303 XML. Requires bval-xstream at RT.
*
- * @param builders meta bean builders
+ * @param builders
+ * meta bean builders
* @return {@link MetaBeanManager}
*/
// NOTE - We return MetaBeanManager instead of XMLMetaBeanManager to
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
index 3a3abf1..d85ab51 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/BootstrapConfigurationImpl.java
@@ -34,12 +34,15 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
private String messageInterpolatorClassName;
private String constraintValidatorFactoryClassName;
private String defaultProviderClassName;
+ private String clockProviderClassName;
+ private Set<String> valueExtractorClassNames;
public BootstrapConfigurationImpl(final String defaultProviderClassName,
final String constraintValidatorFactoryClassName, final String messageInterpolatorClassName,
final String traversableResolverClassName, final String parameterNameProviderClassName,
final Set<String> constraintMappingResourcePaths, final boolean executableValidationEnabled,
- final Set<ExecutableType> defaultValidatedExecutableTypes, final Map<String, String> properties) {
+ final Set<ExecutableType> defaultValidatedExecutableTypes, final Map<String, String> properties,
+ final String clockProviderClassName, final Set<String> valueExtractorClassNames) {
this.properties = Collections.unmodifiableMap(properties);
this.defaultValidatedExecutableTypes = Collections.unmodifiableSet(defaultValidatedExecutableTypes);
this.executableValidationEnabled = executableValidationEnabled;
@@ -49,6 +52,8 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
this.messageInterpolatorClassName = messageInterpolatorClassName;
this.constraintValidatorFactoryClassName = constraintValidatorFactoryClassName;
this.defaultProviderClassName = defaultProviderClassName;
+ this.clockProviderClassName = clockProviderClassName;
+ this.valueExtractorClassNames = valueExtractorClassNames;
}
@Override
@@ -78,7 +83,7 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
@Override
public Set<String> getConstraintMappingResourcePaths() {
- return constraintMappingResourcePaths;
+ return Collections.unmodifiableSet(constraintMappingResourcePaths);
}
@Override
@@ -88,11 +93,27 @@ public class BootstrapConfigurationImpl implements BootstrapConfiguration {
@Override
public Set<ExecutableType> getDefaultValidatedExecutableTypes() {
- return defaultValidatedExecutableTypes;
+ return Collections.unmodifiableSet(defaultValidatedExecutableTypes);
}
@Override
public Map<String, String> getProperties() {
- return properties;
+ return Collections.unmodifiableMap(properties);
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public String getClockProviderClassName() {
+ return clockProviderClassName;
+ }
+
+ /**
+ * @since 2.0
+ */
+ @Override
+ public Set<String> getValueExtractorClassNames() {
+ return Collections.unmodifiableSet(valueExtractorClassNames);
}
}
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java b/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java
index ff2e273..f183c12 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/CascadingPropertyValidator.java
@@ -18,7 +18,9 @@ package org.apache.bval.jsr;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
+import javax.validation.ValidationException;
import javax.validation.Validator;
+
import java.util.Set;
/**
@@ -30,38 +32,90 @@ import java.util.Set;
* It should be noted that {@link Validator#validateProperty(Object, String, Class...)}
* and {@link Validator#validateValue(Class, String, Object, Class...)} are assumed
* semantically equivalent to calling the {@link CascadingPropertyValidator}-defined
- * methods with <code>cascade == false</code>.
+ * methods with {@code cascade == false}.
*
* @version $Rev: 993539 $ $Date: 2010-09-07 16:27:50 -0500 (Tue, 07 Sep 2010) $
*/
public interface CascadingPropertyValidator extends Validator {
/**
- * Validates all constraints placed on <code>object</code>'s
- * <code>propertyName</code> property, with optional validation cascading.
- *
- * @param <T>
- * @param object
- * @param propertyName
- * @param cascade
- * @param groups
- * @return the resulting {@link Set} of {@link ConstraintViolation}s.
+ * {@inheritDoc} Validates all constraints placed on the property of {@code object} named {@code propertyName}.
+ *
+ * @param object object to validate
+ * @param propertyName property to validate (i.e. field and getter constraints). Nested
+ * properties may be referenced (e.g. prop[2].subpropA.subpropB)
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code object} is {@code null}, if {@code propertyName null},
+ * empty or not a valid object property or if {@code null} is
+ * passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ @Override
+ default <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
+ return validateProperty(object, propertyName, false, groups);
+ }
+
+ /**
+ * Validates all constraints placed on the property of {@code object} named {@code propertyName}.
+ *
+ * @param object object to validate
+ * @param propertyName property to validate (i.e. field and getter constraints). Nested
+ * properties may be referenced (e.g. prop[2].subpropA.subpropB)
+ * @param cascade whether to cascade along {@link Valid} properties
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code object} is {@code null}, if {@code propertyName null},
+ * empty or not a valid object property or if {@code null} is
+ * passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
*/
<T> Set<javax.validation.ConstraintViolation<T>> validateProperty(T object, String propertyName, boolean cascade,
Class<?>... groups);
/**
- * Validates all constraints placed on <code>object</code>'s
- * <code>propertyName</code> property, with optional validation cascading,
- * given a hypothetical property <code>value</code>.
- *
- * @param <T>
- * @param beanType
- * @param propertyName
- * @param value
- * @param cascade
- * @param groups
- * @return the resulting {@link Set} of {@link ConstraintViolation}s.
+ * {@inheritDoc} Validates all constraints placed on the property named {@code propertyName} of the class
+ * {@code beanType} would the property value be {@code value}.
+ * <p/>
+ * {@link ConstraintViolation} objects return {@code null} for {@link ConstraintViolation#getRootBean()} and
+ * {@link ConstraintViolation#getLeafBean()}.
+ *
+ * @param beanType the bean type
+ * @param propertyName property to validate
+ * @param value property value to validate
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code beanType} is {@code null}, if
+ * {@code propertyName null}, empty or not a valid object
+ * property or if {@code null} is passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
+ */
+ @Override
+ default <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
+ Class<?>... groups) {
+ return validateValue(beanType, propertyName, value, false, groups);
+ }
+
+ /**
+ * {@inheritDoc} Validates all constraints placed on the property named {@code propertyName} of the class
+ * {@code beanType} would the property value be {@code value}.
+ * <p/>
+ * {@link ConstraintViolation} objects return {@code null} for {@link ConstraintViolation#getRootBean()} and
+ * {@link ConstraintViolation#getLeafBean()}.
+ *
+ * @param beanType the bean type
+ * @param propertyName property to validate
+ * @param value property value to validate
+ * @param groups group or list of groups targeted for validation (default to
+ * {@link javax.validation.groups.Default})
+ * @return constraint violations or an empty {@link Set} if none
+ * @throws IllegalArgumentException if {@code beanType} is {@code null}, if
+ * {@code propertyName null}, empty or not a valid object
+ * property or if {@code null} is passed to the varargs {@code groups}
+ * @throws ValidationException if a non recoverable error happens during the validation process
*/
<T> Set<javax.validation.ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
boolean cascade, Class<?>... groups);
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
index 7c4780f..046d6d2 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConfigurationImpl.java
@@ -19,9 +19,10 @@
package org.apache.bval.jsr;
import java.io.Closeable;
-import java.io.IOException;
import java.io.InputStream;
+import java.time.Clock;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -29,6 +30,7 @@ import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.validation.BootstrapConfiguration;
+import javax.validation.ClockProvider;
import javax.validation.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
@@ -40,6 +42,7 @@ import javax.validation.executable.ExecutableType;
import javax.validation.spi.BootstrapState;
import javax.validation.spi.ConfigurationState;
import javax.validation.spi.ValidationProvider;
+import javax.validation.valueextraction.ValueExtractor;
import org.apache.bval.cdi.BValExtension;
import org.apache.bval.jsr.parameter.DefaultParameterNameProvider;
@@ -76,29 +79,33 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
*/
protected MessageInterpolator defaultMessageInterpolator = new DefaultMessageInterpolator();
protected volatile MessageInterpolator messageInterpolator = defaultMessageInterpolator;
- protected Class<? extends MessageInterpolator> messageInterpolatorClass = null;
+ protected Class<? extends MessageInterpolator> messageInterpolatorClass;
/**
* Configured {@link ConstraintValidatorFactory}
*/
protected ConstraintValidatorFactory defaultConstraintValidatorFactory = new DefaultConstraintValidatorFactory();
protected volatile ConstraintValidatorFactory constraintValidatorFactory = defaultConstraintValidatorFactory;
- protected Class<? extends ConstraintValidatorFactory> constraintValidatorFactoryClass = null;
+ protected Class<? extends ConstraintValidatorFactory> constraintValidatorFactoryClass;
protected TraversableResolver defaultTraversableResolver = new DefaultTraversableResolver();
protected volatile TraversableResolver traversableResolver = defaultTraversableResolver;
- protected Class<? extends TraversableResolver> traversableResolverClass = null;
+ protected Class<? extends TraversableResolver> traversableResolverClass;
protected ParameterNameProvider defaultParameterNameProvider = new DefaultParameterNameProvider();
protected volatile ParameterNameProvider parameterNameProvider = defaultParameterNameProvider;
- protected Class<? extends ParameterNameProvider> parameterNameProviderClass = null;
+ protected Class<? extends ParameterNameProvider> parameterNameProviderClass;
protected BootstrapConfiguration bootstrapConfiguration;
protected Collection<ExecutableType> executableValidation;
- private Collection<BValExtension.Releasable<?>> releasables =
- new CopyOnWriteArrayList<BValExtension.Releasable<?>>();
+ private Collection<BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<>();
+ protected ClockProvider defaultClockProvider = Clock::systemDefaultZone;
+ protected volatile ClockProvider clockProvider = defaultClockProvider;
+ protected Class<? extends ClockProvider> clockProviderClass;
+
+ protected Set<ValueExtractor<?>> valueExtractors = new HashSet<>();
private boolean beforeCdi = false;
@@ -109,8 +116,8 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
private boolean prepared = false;
// END DEFAULTS
- private Set<InputStream> mappingStreams = new HashSet<InputStream>();
- private Map<String, String> properties = new HashMap<String, String>();
+ private Set<InputStream> mappingStreams = new HashSet<>();
+ private Map<String, String> properties = new HashMap<>();
private boolean ignoreXmlConfiguration = false;
private volatile ValidationParser parser;
@@ -134,6 +141,7 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
} else {
throw new ValidationException("either provider or state are required");
}
+ initializePropertyDefaults();
}
/**
@@ -141,13 +149,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
*/
@Override
public ApacheValidatorConfiguration traversableResolver(TraversableResolver resolver) {
- if (resolver == null) {
- return this;
+ if (resolver != null) {
+ this.traversableResolverClass = null;
+ this.traversableResolver = resolver;
+ this.prepared = false;
}
-
- this.traversableResolverClass = null;
- this.traversableResolver = resolver;
- this.prepared = false;
return this;
}
@@ -169,13 +175,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
*/
@Override
public ConfigurationImpl messageInterpolator(MessageInterpolator resolver) {
- if (resolver == null) {
- return this;
+ if (resolver != null) {
+ this.messageInterpolatorClass = null;
+ this.messageInterpolator = resolver;
+ this.prepared = false;
}
-
- this.messageInterpolatorClass = null;
- this.messageInterpolator = resolver;
- this.prepared = false;
return this;
}
@@ -184,23 +188,20 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
*/
@Override
public ConfigurationImpl constraintValidatorFactory(ConstraintValidatorFactory constraintFactory) {
- if (constraintFactory == null) {
- return this;
+ if (constraintFactory != null) {
+ this.constraintValidatorFactoryClass = null;
+ this.constraintValidatorFactory = constraintFactory;
+ this.prepared = false;
}
-
- this.constraintValidatorFactoryClass = null;
- this.constraintValidatorFactory = constraintFactory;
- this.prepared = false;
return this;
}
@Override
public ApacheValidatorConfiguration parameterNameProvider(ParameterNameProvider parameterNameProvider) {
- if (parameterNameProvider == null) {
- return this;
+ if (parameterNameProvider != null) {
+ this.parameterNameProviderClass = null;
+ this.parameterNameProvider = parameterNameProvider;
}
- this.parameterNameProviderClass = null;
- this.parameterNameProvider = parameterNameProvider;
return this;
}
@@ -213,10 +214,9 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
*/
@Override
public ApacheValidatorConfiguration addMapping(InputStream stream) {
- if (stream == null) {
- return this;
+ if (stream != null) {
+ mappingStreams.add(IOs.convertToMarkableInputStream(stream));
}
- mappingStreams.add(IOs.convertToMarkableInputStream(stream));
return this;
}
@@ -297,7 +297,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
if (beforeCdi) {
return defaultMessageInterpolator;
}
-
if (messageInterpolator == defaultMessageInterpolator && messageInterpolatorClass != null) {
synchronized (this) {
if (messageInterpolator == defaultMessageInterpolator && messageInterpolatorClass != null) {
@@ -336,7 +335,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
if (prepared) {
return this;
}
-
createBootstrapConfiguration();
parser.applyConfigWithInstantiation(this); // instantiate the config if needed
@@ -367,7 +365,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
if (beforeCdi) {
return constraintValidatorFactory;
}
-
if (constraintValidatorFactory == defaultConstraintValidatorFactory
&& constraintValidatorFactoryClass != null) {
synchronized (this) {
@@ -388,7 +385,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
if (beforeCdi) {
return defaultTraversableResolver;
}
-
if (traversableResolver == defaultTraversableResolver && traversableResolverClass != null) {
synchronized (this) {
if (traversableResolver == defaultTraversableResolver && traversableResolverClass != null) {
@@ -404,7 +400,6 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
if (beforeCdi) {
return defaultParameterNameProvider;
}
-
if (parameterNameProvider == defaultParameterNameProvider && parameterNameProviderClass != null) {
synchronized (this) {
if (parameterNameProvider == defaultParameterNameProvider && parameterNameProviderClass != null) {
@@ -452,14 +447,11 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
}
public Closeable getClosable() {
- return new Closeable() {
- @Override
- public void close() throws IOException {
- for (final BValExtension.Releasable<?> releasable : releasables) {
- releasable.release();
- }
- releasables.clear();
+ return () -> {
+ for (final BValExtension.Releasable<?> releasable : releasables) {
+ releasable.release();
}
+ releasables.clear();
};
}
@@ -469,8 +461,7 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
final BValExtension.Releasable<T> releasable = BValExtension.inject(cls);
releasables.add(releasable);
return releasable.getInstance();
- } catch (final Exception e) {
- } catch (final NoClassDefFoundError error) {
+ } catch (Exception | NoClassDefFoundError e) {
}
try {
return cls.newInstance();
@@ -494,4 +485,45 @@ public class ConfigurationImpl implements ApacheValidatorConfiguration, Configur
public void parameterNameProviderClass(final Class<? extends ParameterNameProvider> clazz) {
parameterNameProviderClass = clazz;
}
+
+ @Override
+ public ApacheValidatorConfiguration clockProvider(ClockProvider clockProvider) {
+ this.clockProvider = clockProvider;
+ return this;
+ }
+
+ @Override
+ public ApacheValidatorConfiguration addValueExtractor(ValueExtractor<?> extractor) {
+ valueExtractors.add(extractor);
+ return this;
+ }
+
+ @Override
+ public ClockProvider getDefaultClockProvider() {
+ return defaultClockProvider;
+ }
+
+ @Override
+ public Set<ValueExtractor<?>> getValueExtractors() {
+ return Collections.unmodifiableSet(valueExtractors);
+ }
+
+ @Override
+ public ClockProvider getClockProvider() {
+ if (beforeCdi) {
+ return defaultClockProvider;
+ }
+ if (clockProvider == defaultClockProvider && clockProviderClass != null) {
+ synchronized (this) {
+ if (clockProvider == defaultClockProvider && clockProviderClass != null) {
+ clockProvider = newInstance(clockProviderClass);
+ }
+ }
+ }
+ return clockProvider;
+ }
+
+ protected void initializePropertyDefaults() {
+ properties.put(Properties.CONSTRAINTS_CACHE_SIZE, Integer.toString(50));
+ }
}
http://git-wip-us.apache.org/repos/asf/bval/blob/05df7ee2/bval-jsr/src/main/java/org/apache/bval/jsr/ValidatorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ValidatorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ValidatorImpl.java
new file mode 100644
index 0000000..606e191
--- /dev/null
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ValidatorImpl.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.
+ */
+package org.apache.bval.jsr;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.ValidationException;
+import javax.validation.executable.ExecutableValidator;
+import javax.validation.metadata.BeanDescriptor;
+
+import org.apache.bval.jsr.job.ValidationJobFactory;
+import org.apache.bval.util.Validate;
+import org.apache.bval.util.reflection.Reflection;
+
+public class ValidatorImpl implements CascadingPropertyValidator, ExecutableValidator {
+
+ private final ApacheFactoryContext validatorContext;
+ private final ValidationJobFactory validationJobFactory;
+
+ ValidatorImpl(ApacheFactoryContext validatorContext) {
+ super();
+ this.validatorContext = Validate.notNull(validatorContext, "validatorContext");
+ this.validationJobFactory = new ValidationJobFactory(validatorContext);
+ }
+
+ @Override
+ public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
+ return validatorContext.getDescriptorManager().getBeanDescriptor(clazz);
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
+ return validationJobFactory.validateBean(object, groups).getResults();
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, boolean cascade,
+ Class<?>... groups) {
+ return validationJobFactory.validateProperty(object, propertyName, groups).cascade(cascade).getResults();
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
+ boolean cascade, Class<?>... groups) {
+ return validationJobFactory.validateValue(beanType, propertyName, value, groups).cascade(cascade).getResults();
+ }
+
+ @Override
+ public ExecutableValidator forExecutables() {
+ return this;
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateParameters(T object, Method method, Object[] parameterValues,
+ Class<?>... groups) {
+ return validationJobFactory.validateParameters(object, method, parameterValues, groups).getResults();
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateReturnValue(T object, Method method, Object returnValue,
+ Class<?>... groups) {
+ return validationJobFactory.validateReturnValue(object, method, returnValue, groups).getResults();
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateConstructorParameters(Constructor<? extends T> constructor,
+ Object[] parameterValues, Class<?>... groups) {
+ return validationJobFactory.<T> validateConstructorParameters(constructor, parameterValues, groups)
+ .getResults();
+ }
+
+ @Override
+ public <T> Set<ConstraintViolation<T>> validateConstructorReturnValue(Constructor<? extends T> constructor,
+ T createdObject, Class<?>... groups) {
+ return validationJobFactory.<T> validateConstructorReturnValue(constructor, createdObject, groups).getResults();
+ }
+
+ @Override
+ public <T> T unwrap(Class<T> type) {
+ // FIXME 2011-03-27 jw:
+ // This code is unsecure.
+ // It should allow only a fixed set of classes.
+ // Can't fix this because don't know which classes this method should support.
+
+ if (type.isAssignableFrom(getClass())) {
+ @SuppressWarnings("unchecked")
+ final T result = (T) this;
+ return result;
+ }
+ if (!(type.isInterface() || Modifier.isAbstract(type.getModifiers()))) {
+ return newInstance(type);
+ }
+ try {
+ final Class<?> cls = Reflection.toClass(type.getName() + "Impl");
+ if (type.isAssignableFrom(cls)) {
+ @SuppressWarnings("unchecked")
+ final Class<? extends T> implClass = (Class<? extends T>) cls;
+ return newInstance(implClass);
+ }
+ } catch (ClassNotFoundException e) {
+ }
+ throw new ValidationException("Type " + type + " not supported");
+ }
+
+ private <T> T newInstance(final Class<T> cls) {
+ final Constructor<T> cons = Reflection.getDeclaredConstructor(cls, ApacheFactoryContext.class);
+ if (cons == null) {
+ throw new ValidationException("Cannot instantiate " + cls);
+ }
+ final boolean mustUnset = Reflection.setAccessible(cons, true);
+ try {
+ return cons.newInstance(validatorContext);
+ } catch (final Exception ex) {
+ throw new ValidationException("Cannot instantiate " + cls, ex);
+ } finally {
+ if (mustUnset) {
+ Reflection.setAccessible(cons, false);
+ }
+ }
+ }
+}