BVAL-143 caching should be hold by the factory or shouldnt be for performance reason + reactivating jboss repo since tck (1.0) modules are not on central
git-svn-id: https://svn.apache.org/repos/asf/bval/trunk@1721536 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bval-jsr/pom.xml b/bval-jsr/pom.xml
index ac5ad97..5a93460 100644
--- a/bval-jsr/pom.xml
+++ b/bval-jsr/pom.xml
@@ -297,10 +297,12 @@
</includes>
</configuration>
</plugin>
+ <!-- TODO: activate but ATM it just doesnt build with it
<plugin>
<groupId>org.apache.commons</groupId>
<artifactId>commons-weaver-maven-plugin</artifactId>
</plugin>
+ -->
</plugins>
</build>
</project>
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 ababfbd..d75bb31 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
@@ -18,6 +18,23 @@
*/
package org.apache.bval.jsr;
+import org.apache.bval.jsr.groups.GroupsComputer;
+import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
+import org.apache.bval.util.AccessStrategy;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.reflect.TypeUtils;
+import org.apache.commons.weaver.privilizer.Privileged;
+
+import javax.validation.Constraint;
+import javax.validation.ConstraintDeclarationException;
+import javax.validation.ConstraintDefinitionException;
+import javax.validation.ConstraintTarget;
+import javax.validation.ConstraintValidator;
+import javax.validation.OverridesAttribute;
+import javax.validation.Payload;
+import javax.validation.ReportAsSingleViolation;
+import javax.validation.constraintvalidation.SupportedValidationTarget;
+import javax.validation.constraintvalidation.ValidationTarget;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -32,25 +49,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-import javax.validation.Constraint;
-import javax.validation.ConstraintDeclarationException;
-import javax.validation.ConstraintDefinitionException;
-import javax.validation.ConstraintTarget;
-import javax.validation.ConstraintValidator;
-import javax.validation.ConstraintValidatorFactory;
-import javax.validation.OverridesAttribute;
-import javax.validation.Payload;
-import javax.validation.ReportAsSingleViolation;
-import javax.validation.constraintvalidation.SupportedValidationTarget;
-import javax.validation.constraintvalidation.ValidationTarget;
-
-import org.apache.bval.jsr.groups.GroupsComputer;
-import org.apache.bval.jsr.xml.AnnotationProxyBuilder;
-import org.apache.bval.util.AccessStrategy;
-import org.apache.commons.lang3.ArrayUtils;
-import org.apache.commons.lang3.reflect.TypeUtils;
-import org.apache.commons.weaver.privilizer.Privileged;
-
/**
* Description: helper class that builds a {@link ConstraintValidation} or its
* composite constraint validations by parsing the jsr-annotations and
@@ -64,19 +62,19 @@
/**
* Create a new AnnotationConstraintBuilder instance.
- *
+ *
* @param validatorClasses
* @param annotation
* @param owner
* @param access
*/
- public AnnotationConstraintBuilder(ConstraintValidatorFactory factory,
- Class<? extends ConstraintValidator<A, ?>>[] validatorClasses, A annotation, Class<?> owner,
- AccessStrategy access, ConstraintTarget target) {
+ public AnnotationConstraintBuilder(
+ Class<? extends ConstraintValidator<A, ?>>[] validatorClasses, A annotation, Class<?> owner,
+ AccessStrategy access, ConstraintTarget target) {
final boolean reportFromComposite =
annotation != null && annotation.annotationType().isAnnotationPresent(ReportAsSingleViolation.class);
constraintValidation =
- new ConstraintValidation<A>(factory, validatorClasses, annotation, owner, access, reportFromComposite,
+ new ConstraintValidation<A>(validatorClasses, annotation, owner, access, reportFromComposite,
target);
buildFromAnnotation();
}
@@ -259,7 +257,7 @@
/**
* Get the configured {@link ConstraintValidation}.
- *
+ *
* @return {@link ConstraintValidation}
*/
public ConstraintValidation<?> getConstraintValidation() {
@@ -309,7 +307,7 @@
* Calculates the index of the composite constraint. The index represents
* the order in which it is added in reference to other constraints of the
* same type.
- *
+ *
* @param composite
* The composite constraint (not yet added).
* @return An integer index always >= 0
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 a5332c0..7fcd4d7 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
@@ -34,7 +34,6 @@
import javax.validation.constraintvalidation.ValidationTarget;
import javax.validation.groups.ConvertGroup;
import javax.validation.groups.Default;
-
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
@@ -50,15 +49,15 @@
@Privilizing(@CallTo(Reflection.class))
public final class AnnotationProcessor {
/** {@link ApacheFactoryContext} used */
- private final ApacheFactoryContext factoryContext;
+ private final ApacheValidatorFactory factory;
/**
* Create a new {@link AnnotationProcessor} instance.
*
- * @param factoryContext
+ * @param factory the validator factory.
*/
- public AnnotationProcessor(ApacheFactoryContext factoryContext) {
- this.factoryContext = factoryContext;
+ public AnnotationProcessor(ApacheValidatorFactory factory) {
+ this.factory = factory;
}
/**
@@ -112,7 +111,7 @@
* @throws InvocationTargetException
*/
public <A extends Annotation> boolean processAnnotation(A annotation, Meta prop, Class<?> owner,
- AccessStrategy access, AppendValidation appender, boolean reflection) throws IllegalAccessException,
+ AccessStrategy access, AppendValidation appender, boolean reflection) throws IllegalAccessException,
InvocationTargetException {
if (annotation instanceof Valid) {
return addAccessStrategy(prop, access);
@@ -204,12 +203,11 @@
}
final Class<A> annotationType = (Class<A>) annotation.annotationType();
Class<? extends ConstraintValidator<A, ?>>[] validatorClasses =
- factoryContext.getFactory().getConstraintsCache().getConstraintValidators(annotationType);
+ factory.getConstraintsCache().getConstraintValidators(annotationType);
if (validatorClasses == null) {
validatorClasses = (Class<? extends ConstraintValidator<A, ?>>[]) vcAnno.validatedBy();
if (validatorClasses.length == 0) {
- validatorClasses =
- factoryContext.getFactory().getDefaultConstraints().getValidatorClasses(annotationType);
+ validatorClasses = factory.getDefaultConstraints().getValidatorClasses(annotationType);
}
}
return validatorClasses;
@@ -234,7 +232,8 @@
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
- private <A extends Annotation> boolean applyConstraint(A annotation,
+ private <A extends Annotation> boolean applyConstraint(
+ A annotation,
Class<? extends ConstraintValidator<A, ?>>[] rawConstraintClasses, Meta prop, Class<?> owner,
AccessStrategy access, AppendValidation appender) throws IllegalAccessException, InvocationTargetException {
@@ -244,7 +243,8 @@
}
final AnnotationConstraintBuilder<A> builder =
- new AnnotationConstraintBuilder<A>(factoryContext.getConstraintValidatorFactory(), constraintClasses,
+ new AnnotationConstraintBuilder<A>(
+ constraintClasses,
annotation, owner, access, null);
// JSR-303 3.4.4: Add implicit groups
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 05f6fa0..700c0a8 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,33 +18,18 @@
*/
package org.apache.bval.jsr;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
+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.ConstraintValidatorFactory;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
import javax.validation.TraversableResolver;
-import javax.validation.ValidationException;
import javax.validation.Validator;
import javax.validation.ValidatorContext;
-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.util.reflection.Reflection;
-import org.apache.bval.xml.XMLMetaBeanBuilder;
-import org.apache.bval.xml.XMLMetaBeanFactory;
-import org.apache.bval.xml.XMLMetaBeanManager;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.commons.lang3.reflect.ConstructorUtils;
-import org.apache.commons.weaver.privilizer.Privileged;
-import org.apache.commons.weaver.privilizer.Privilizing;
-import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-
/**
* Description: Represents the context that is used to create
* <code>ClassValidator</code> instances.<br/>
@@ -52,7 +37,7 @@
@Privilizing(@CallTo(Reflection.class))
public class ApacheFactoryContext implements ValidatorContext {
private final ApacheValidatorFactory factory;
- private final MetaBeanFinder metaBeanFinder;
+ private volatile MetaBeanFinder metaBeanFinder;
private MessageInterpolator messageInterpolator;
private TraversableResolver traversableResolver;
@@ -63,19 +48,9 @@
* Create a new ApacheFactoryContext instance.
*
* @param factory validator factory
- */
- public ApacheFactoryContext(ApacheValidatorFactory factory) {
- this.factory = factory;
- this.metaBeanFinder = buildMetaBeanFinder();
- }
-
- /**
- * Create a new ApacheFactoryContext instance.
- *
- * @param factory validator factory
* @param metaBeanFinder meta finder
*/
- protected ApacheFactoryContext(ApacheValidatorFactory factory, MetaBeanFinder metaBeanFinder) {
+ public ApacheFactoryContext(ApacheValidatorFactory factory, MetaBeanFinder metaBeanFinder) {
this.factory = factory;
this.metaBeanFinder = metaBeanFinder;
}
@@ -99,11 +74,16 @@
return metaBeanFinder;
}
+ private synchronized void resetMeta() { // ensure to ingnore the cache and rebuild constraint with new model
+ metaBeanFinder = factory.buildMetaBeanFinder();
+ }
+
/**
* {@inheritDoc}
*/
public ValidatorContext messageInterpolator(MessageInterpolator messageInterpolator) {
this.messageInterpolator = messageInterpolator;
+ resetMeta();
return this;
}
@@ -112,6 +92,7 @@
*/
public ValidatorContext traversableResolver(TraversableResolver traversableResolver) {
this.traversableResolver = traversableResolver;
+ resetMeta();
return this;
}
@@ -120,11 +101,13 @@
*/
public ValidatorContext constraintValidatorFactory(ConstraintValidatorFactory constraintValidatorFactory) {
this.constraintValidatorFactory = constraintValidatorFactory;
+ resetMeta();
return this;
}
public ValidatorContext parameterNameProvider(ParameterNameProvider parameterNameProvider) {
this.parameterNameProvider = parameterNameProvider;
+ resetMeta();
return this;
}
@@ -171,126 +154,4 @@
return Boolean.parseBoolean(factory.getProperties().get(
ApacheValidatorConfiguration.Properties.TREAT_MAPS_LIKE_BEANS));
}
-
- /**
- * Create MetaBeanManager that uses factories:
- * <ol>
- * <li>if enabled by
- * {@link ApacheValidatorConfiguration.Properties#ENABLE_INTROSPECTOR}, an
- * {@link IntrospectorMetaBeanFactory}</li>
- * <li>{@link MetaBeanFactory} types (if any) specified by
- * {@link ApacheValidatorConfiguration.Properties#METABEAN_FACTORY_CLASSNAMES}
- * </li>
- * <li>if no {@link JsrMetaBeanFactory} has yet been specified (this
- * allows factory order customization), a {@link JsrMetaBeanFactory}
- * which handles both JSR303-XML and JSR303-Annotations</li>
- * <li>if enabled by
- * {@link ApacheValidatorConfiguration.Properties#ENABLE_METABEANS_XML}, an
- * {@link XMLMetaBeanFactory}</li>
- * </ol>
- *
- * @return a new instance of MetaBeanManager with adequate MetaBeanFactories
- */
- protected MetaBeanFinder buildMetaBeanFinder() {
- final List<MetaBeanFactory> builders = new ArrayList<MetaBeanFactory>();
- if (Boolean.parseBoolean(factory.getProperties().get(
- ApacheValidatorConfiguration.Properties.ENABLE_INTROSPECTOR))) {
- builders.add(new IntrospectorMetaBeanFactory());
- }
- final String[] factoryClassNames =
- StringUtils.split(factory.getProperties().get(
- ApacheValidatorConfiguration.Properties.METABEAN_FACTORY_CLASSNAMES));
- 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);
- builders.add(createMetaBeanFactory(factoryClass));
- }
- }
- boolean jsrFound = false;
- for (MetaBeanFactory builder : builders) {
- jsrFound |= builder instanceof JsrMetaBeanFactory;
- }
- if (!jsrFound) {
- builders.add(new JsrMetaBeanFactory(this));
- }
- @SuppressWarnings("deprecation")
- final boolean enableMetaBeansXml =
- Boolean.parseBoolean(factory.getProperties().get(
- ApacheValidatorConfiguration.Properties.ENABLE_METABEANS_XML));
- if (enableMetaBeansXml) {
- XMLMetaBeanManagerCreator.addFactory(builders);
- }
- return createMetaBeanManager(builders);
- }
-
- /**
- * Create a {@link MetaBeanManager} using the specified builders.
- *
- * @param builders
- * {@link MetaBeanFactory} {@link List}
- * @return {@link MetaBeanManager}
- */
- @SuppressWarnings("deprecation")
- protected MetaBeanFinder createMetaBeanManager(List<MetaBeanFactory> builders) {
- // as long as we support both: jsr (in the builders list) and xstream-xml metabeans:
- if (Boolean.parseBoolean(factory.getProperties().get(
- ApacheValidatorConfiguration.Properties.ENABLE_METABEANS_XML))) {
- return XMLMetaBeanManagerCreator.createXMLMetaBeanManager(builders);
- }
- return new MetaBeanManager(new MetaBeanBuilder(builders.toArray(new MetaBeanFactory[builders.size()])));
- }
-
- @Privileged
- private <F extends MetaBeanFactory> F createMetaBeanFactory(final Class<F> cls) {
- try {
- Constructor<F> c = ConstructorUtils.getMatchingAccessibleConstructor(cls, ApacheFactoryContext.this.getClass());
- if (c != null) {
- return c.newInstance(ApacheFactoryContext.this);
- }
- c = ConstructorUtils.getMatchingAccessibleConstructor(cls, getFactory().getClass());
- if (c != null) {
- return c.newInstance(getFactory());
- }
- return cls.newInstance();
- } catch (Exception e) {
- throw new ValidationException(e);
- }
- }
-
- /**
- * 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 {
-
- static void addFactory(List<MetaBeanFactory> builders) {
- builders.add(new XMLMetaBeanFactory());
- }
-
- /**
- * Create the {@link MetaBeanManager} to process JSR303 XML. Requires
- * bval-xstream at RT.
- *
- * @param builders meta bean builders
- * @return {@link MetaBeanManager}
- */
- // NOTE - We return MetaBeanManager instead of XMLMetaBeanManager to
- // keep
- // bval-xstream an optional module.
- protected static MetaBeanManager createXMLMetaBeanManager(List<MetaBeanFactory> builders) {
- return new XMLMetaBeanManager(
- new XMLMetaBeanBuilder(builders.toArray(new MetaBeanFactory[builders.size()])));
- }
- }
-
- private Class<?> loadClass(final String className) {
- try {
- return Class.forName(className, true, Reflection.getClassLoader(ApacheFactoryContext.class));
- } catch (ClassNotFoundException ex) {
- throw new ValidationException("Unable to load class: " + className, ex);
- }
- }
}
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 5fd313a..f9b2743 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,13 +18,24 @@
*/
package org.apache.bval.jsr;
+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.xml.AnnotationIgnores;
import org.apache.bval.jsr.xml.MetaConstraint;
import org.apache.bval.jsr.xml.ValidationMappingParser;
import org.apache.bval.util.AccessStrategy;
import org.apache.bval.util.reflection.Reflection;
+import org.apache.bval.xml.XMLMetaBeanBuilder;
+import org.apache.bval.xml.XMLMetaBeanFactory;
+import org.apache.bval.xml.XMLMetaBeanManager;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.reflect.ConstructorUtils;
+import org.apache.commons.weaver.privilizer.Privileged;
import org.apache.commons.weaver.privilizer.Privilizing;
import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
@@ -37,9 +48,9 @@
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;
@@ -80,6 +91,60 @@
private final ConcurrentMap<Class<?>, List<MetaConstraint<?, ? extends Annotation>>> constraintMap;
private final Collection<Closeable> toClose = new ArrayList<Closeable>();
+ private final MetaBeanFinder defaultMetaBeanFinder;
+
+ /**
+ * Create MetaBeanManager that uses factories:
+ * <ol>
+ * <li>if enabled by
+ * {@link ApacheValidatorConfiguration.Properties#ENABLE_INTROSPECTOR}, an
+ * {@link IntrospectorMetaBeanFactory}</li>
+ * <li>{@link MetaBeanFactory} types (if any) specified by
+ * {@link ApacheValidatorConfiguration.Properties#METABEAN_FACTORY_CLASSNAMES}
+ * </li>
+ * <li>if no {@link JsrMetaBeanFactory} has yet been specified (this
+ * allows factory order customization), a {@link JsrMetaBeanFactory}
+ * which handles both JSR303-XML and JSR303-Annotations</li>
+ * <li>if enabled by
+ * {@link ApacheValidatorConfiguration.Properties#ENABLE_METABEANS_XML}, an
+ * {@link XMLMetaBeanFactory}</li>
+ * </ol>
+ *
+ * @return a new instance of MetaBeanManager with adequate MetaBeanFactories
+ */
+ protected MetaBeanFinder buildMetaBeanFinder() {
+ final List<MetaBeanFactory> builders = new ArrayList<MetaBeanFactory>();
+ if (Boolean.parseBoolean(getProperties().get(
+ ApacheValidatorConfiguration.Properties.ENABLE_INTROSPECTOR))) {
+ builders.add(new IntrospectorMetaBeanFactory());
+ }
+ final String[] factoryClassNames =
+ StringUtils.split(getProperties().get(
+ ApacheValidatorConfiguration.Properties.METABEAN_FACTORY_CLASSNAMES));
+ 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);
+ builders.add(createMetaBeanFactory(factoryClass));
+ }
+ }
+ boolean jsrFound = false;
+ for (MetaBeanFactory builder : builders) {
+ jsrFound |= builder instanceof JsrMetaBeanFactory;
+ }
+ if (!jsrFound) {
+ builders.add(new JsrMetaBeanFactory(this));
+ }
+ @SuppressWarnings("deprecation")
+ final boolean enableMetaBeansXml =
+ Boolean.parseBoolean(getProperties().get(
+ ApacheValidatorConfiguration.Properties.ENABLE_METABEANS_XML));
+ if (enableMetaBeansXml) {
+ XMLMetaBeanManagerCreator.addFactory(builders);
+ }
+ return createMetaBeanManager(builders);
+ }
/**
* Convenience method to retrieve a default global ApacheValidatorFactory
@@ -110,22 +175,11 @@
/**
* Create a new ApacheValidatorFactory instance.
*/
- public ApacheValidatorFactory(ConfigurationState configurationState) {
- properties = new HashMap<String, String>();
+ 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>>>();
- configure(configurationState);
- }
-
- /**
- * Configure this {@link ApacheValidatorFactory} from a
- * {@link ConfigurationState}.
- *
- * @param configuration
- */
- protected void configure(final ConfigurationState configuration) {
- getProperties().putAll(configuration.getProperties());
parameterNameProvider = configuration.getParameterNameProvider();
messageResolver = configuration.getMessageInterpolator();
@@ -138,6 +192,8 @@
}
new ValidationMappingParser(this).processMappingConfig(configuration.getMappingStreams());
+
+ defaultMetaBeanFinder = buildMetaBeanFinder();
}
/**
@@ -165,7 +221,7 @@
* @return the validator factory's context
*/
public ApacheFactoryContext usingContext() {
- return new ApacheFactoryContext(this);
+ return new ApacheFactoryContext(this, defaultMetaBeanFinder);
}
/**
@@ -428,4 +484,73 @@
private static Class<?>[] safeArray(Class<?>... array) {
return ArrayUtils.isEmpty(array) ? ArrayUtils.EMPTY_CLASS_ARRAY : ArrayUtils.clone(array);
}
+
+ /**
+ * Create a {@link MetaBeanManager} using the specified builders.
+ *
+ * @param builders
+ * {@link MetaBeanFactory} {@link List}
+ * @return {@link MetaBeanManager}
+ */
+ @SuppressWarnings("deprecation")
+ protected MetaBeanFinder createMetaBeanManager(List<MetaBeanFactory> builders) {
+ // as long as we support both: jsr (in the builders list) and xstream-xml metabeans:
+ if (Boolean.parseBoolean(getProperties().get(
+ ApacheValidatorConfiguration.Properties.ENABLE_METABEANS_XML))) {
+ return XMLMetaBeanManagerCreator.createXMLMetaBeanManager(builders);
+ }
+ return new MetaBeanManager(new MetaBeanBuilder(builders.toArray(new MetaBeanFactory[builders.size()])));
+ }
+
+ @Privileged
+ private <F extends MetaBeanFactory> F createMetaBeanFactory(final Class<F> cls) {
+ try {
+ Constructor<F> c = ConstructorUtils.getMatchingAccessibleConstructor(cls, ApacheValidatorFactory.this.getClass());
+ if (c != null) {
+ return c.newInstance(this);
+ }
+ c = ConstructorUtils.getMatchingAccessibleConstructor(cls, getClass());
+ if (c != null) {
+ return c.newInstance(this);
+ }
+ return cls.newInstance();
+ } catch (Exception e) {
+ throw new ValidationException(e);
+ }
+ }
+
+ /**
+ * 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 {
+
+ static void addFactory(List<MetaBeanFactory> builders) {
+ builders.add(new XMLMetaBeanFactory());
+ }
+
+ /**
+ * Create the {@link MetaBeanManager} to process JSR303 XML. Requires
+ * bval-xstream at RT.
+ *
+ * @param builders meta bean builders
+ * @return {@link MetaBeanManager}
+ */
+ // NOTE - We return MetaBeanManager instead of XMLMetaBeanManager to
+ // keep
+ // bval-xstream an optional module.
+ protected static MetaBeanManager createXMLMetaBeanManager(List<MetaBeanFactory> builders) {
+ return new XMLMetaBeanManager(
+ new XMLMetaBeanBuilder(builders.toArray(new MetaBeanFactory[builders.size()])));
+ }
+ }
+
+ private Class<?> loadClass(final String className) {
+ try {
+ return Class.forName(className, true, Reflection.getClassLoader(ApacheValidatorFactory.class));
+ } catch (ClassNotFoundException ex) {
+ throw new ValidationException("Unable to load class: " + className, ex);
+ }
+ }
}
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/BeanDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/BeanDescriptorImpl.java
index df7f911..2b80d50 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/BeanDescriptorImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/BeanDescriptorImpl.java
@@ -51,7 +51,6 @@
import javax.validation.metadata.ParameterDescriptor;
import javax.validation.metadata.PropertyDescriptor;
import javax.validation.metadata.ReturnValueDescriptor;
-
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
@@ -329,7 +328,7 @@
private ExecutableMeta(final ApacheFactoryContext factoryContext, final MetaBean metaBean1, final Collection<ConstraintDescriptor<?>> constraintDescriptors) {
this.metaBean = metaBean1;
this.factoryContext = factoryContext;
- this.annotationProcessor = new AnnotationProcessor(factoryContext);
+ this.annotationProcessor = new AnnotationProcessor(factoryContext.getFactory());
buildExecutableDescriptors();
@@ -840,7 +839,9 @@
}
}
} else {
- annotationProcessor.processAnnotation(annotation, null, ClassUtils.primitiveToWrapper((Class<?>) access.getJavaType()), access, validations, true);
+ annotationProcessor.processAnnotation(
+ annotation, null, ClassUtils.primitiveToWrapper((Class<?>) access.getJavaType()),
+ access, validations, true);
}
}
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
index 7ee0053..e1c1dd3 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
@@ -638,8 +638,9 @@
protected <T> GroupValidationContext<T> createContext(MetaBean metaBean, T object, Class<T> objectClass, Class<?>... groups) {
final ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object, objectClass);
final GroupValidationContextImpl<T> context =
- new GroupValidationContextImpl<T>(listener, this.factoryContext.getMessageInterpolator(),
- this.factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(), metaBean);
+ new GroupValidationContextImpl<T>(listener, factoryContext.getMessageInterpolator(),
+ factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(),
+ factoryContext.getConstraintValidatorFactory(), metaBean);
context.setBean(object, metaBean);
context.setGroups(groupsComputer.computeGroups(groups));
return context;
@@ -648,8 +649,9 @@
protected <T> GroupValidationContext<T> createInvocableContext(MetaBean metaBean, T object, Class<T> objectClass, Class<?>... groups) {
final ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object, objectClass);
final GroupValidationContextImpl<T> context =
- new GroupValidationContextImpl<T>(listener, this.factoryContext.getMessageInterpolator(),
- this.factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(), metaBean);
+ new GroupValidationContextImpl<T>(listener, factoryContext.getMessageInterpolator(),
+ factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(),
+ factoryContext.getConstraintValidatorFactory(), metaBean);
context.setBean(object, metaBean);
final Groups computedGroup = groupsComputer.computeGroups(groups);
if (Collections.singletonList(Group.DEFAULT).equals(computedGroup.getGroups()) && metaBean.getFeature(JsrFeatures.Bean.GROUP_SEQUENCE) != null) {
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 2b58c12..0ce7248 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,7 +39,6 @@
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
import javax.validation.metadata.ConstraintDescriptor;
-
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Array;
@@ -61,7 +60,6 @@
* this instance is immutable!<br/>
*/
public class ConstraintValidation<T extends Annotation> implements Validation, ConstraintDescriptor<T> {
- private final ConstraintValidatorFactory factory;
private final AccessStrategy access;
private final boolean reportFromComposite;
private final Map<String, Object> attributes;
@@ -82,11 +80,9 @@
private Class<? extends ConstraintValidator<T, ?>>[] validatorClasses;
private ConstraintTarget validationAppliesTo = null;
- public ConstraintValidation(ConstraintValidatorFactory factory,
- Class<? extends ConstraintValidator<T, ?>>[] validatorClasses,
+ public ConstraintValidation(Class<? extends ConstraintValidator<T, ?>>[] validatorClasses,
T annotation, Class<?> owner, AccessStrategy access,
boolean reportFromComposite, ConstraintTarget target) {
- this.factory = factory;
this.attributes = new HashMap<String, Object>();
this.validatorClasses = ArrayUtils.clone(validatorClasses);
this.annotation = annotation;
@@ -158,7 +154,8 @@
synchronized (this) {
if (validator == null) {
try {
- validator = getConstraintValidator(annotation, validatorClasses, owner, access);
+ validator = getConstraintValidator(
+ context.getConstraintValidatorFactory(), annotation, validatorClasses, owner, access);
if (validator != null) {
validator.initialize(annotation);
}
@@ -235,7 +232,8 @@
}
}
- private <A extends Annotation> ConstraintValidator<A, ? super T> getConstraintValidator(A annotation,
+ private <A extends Annotation> ConstraintValidator<A, ? super T> getConstraintValidator(
+ ConstraintValidatorFactory factory, A annotation,
Class<? extends ConstraintValidator<A, ?>>[] constraintClasses, Class<?> owner, AccessStrategy access) {
if (ArrayUtils.isNotEmpty(constraintClasses)) {
final Type type = determineTargetedType(owner, access);
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContext.java b/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContext.java
index f3a57a5..70a53f0 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContext.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContext.java
@@ -24,6 +24,7 @@
import org.apache.bval.model.ValidationContext;
import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorFactory;
import javax.validation.ElementKind;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
@@ -107,6 +108,12 @@
TraversableResolver getTraversableResolver();
/**
+ * Get the {@link ConstraintValidatorFactory}.
+ * @return {@link ConstraintValidatorFactory}
+ */
+ ConstraintValidatorFactory getConstraintValidatorFactory();
+
+ /**
* Accumulate a validated constraint.
* @param constraint
* @return true when the constraint for the object in this path was not
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContextImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContextImpl.java
index 778c5d2..2791a25 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContextImpl.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/GroupValidationContextImpl.java
@@ -27,6 +27,7 @@
import org.apache.bval.util.AccessStrategy;
import javax.validation.ConstraintValidator;
+import javax.validation.ConstraintValidatorFactory;
import javax.validation.ElementKind;
import javax.validation.MessageInterpolator;
import javax.validation.ParameterNameProvider;
@@ -70,6 +71,7 @@
private ConstraintValidation<?> constraintValidation;
private final TraversableResolver traversableResolver;
+ private final ConstraintValidatorFactory constraintValidatorFactory;
private Object[] parameters;
private Object returnValue;
@@ -86,11 +88,14 @@
* @param rootMetaBean
*/
public GroupValidationContextImpl(ConstraintValidationListener<T> listener, MessageInterpolator aMessageResolver,
- TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider, MetaBean rootMetaBean) {
+ TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider,
+ ConstraintValidatorFactory constraintValidatorFactory,
+ MetaBean rootMetaBean) {
// inherited variable 'validatedObjects' is of type:
// HashMap<GraphBeanIdentity, Set<PathImpl>> in this class
super(listener, new HashMap<GraphBeanIdentity, Set<PathImpl>>());
this.messageResolver = aMessageResolver;
+ this.constraintValidatorFactory = constraintValidatorFactory;
this.traversableResolver = CachingTraversableResolver.cacheFor(traversableResolver);
this.parameterNameProvider = parameterNameProvider;
this.rootMetaBean = rootMetaBean;
@@ -313,6 +318,11 @@
return traversableResolver;
}
+ @Override
+ public ConstraintValidatorFactory getConstraintValidatorFactory() {
+ return constraintValidatorFactory;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/JsrMetaBeanFactory.java b/bval-jsr/src/main/java/org/apache/bval/jsr/JsrMetaBeanFactory.java
index 68f9346..b86c8d8 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/JsrMetaBeanFactory.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/JsrMetaBeanFactory.java
@@ -63,8 +63,8 @@
// of dubious utility as it's static :/
protected static final Logger log = Logger.getLogger(JsrMetaBeanFactory.class.getName());
- /** {@link ApacheFactoryContext} used */
- protected final ApacheFactoryContext factoryContext;
+ /** {@link javax.validation.ValidatorFactory} used */
+ protected final ApacheValidatorFactory factory;
/**
* {@link AnnotationProcessor} used.
@@ -74,11 +74,11 @@
/**
* Create a new Jsr303MetaBeanFactory instance.
*
- * @param factoryContext
+ * @param factory the validator factory.
*/
- public JsrMetaBeanFactory(ApacheFactoryContext factoryContext) {
- this.factoryContext = factoryContext;
- this.annotationProcessor = new AnnotationProcessor(factoryContext);
+ public JsrMetaBeanFactory(ApacheValidatorFactory factory) {
+ this.factory = factory;
+ this.annotationProcessor = new AnnotationProcessor(factory);
}
/**
@@ -123,7 +123,7 @@
InvocationTargetException {
// if NOT ignore class level annotations
- if (!factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotations(beanClass)) {
+ if (!factory.getAnnotationIgnores().isIgnoreAnnotations(beanClass)) {
annotationProcessor.processAnnotations(null, beanClass, beanClass, null, new AppendValidationToMeta(metabean));
}
@@ -134,7 +134,7 @@
MetaProperty metaProperty = metabean.getProperty(field.getName());
// create a property for those fields for which there is not yet a
// MetaProperty
- if (!factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotations(field)) {
+ if (!factory.getAnnotationIgnores().isIgnoreAnnotations(field)) {
AccessStrategy access = new FieldAccess(field);
boolean create = metaProperty == null;
if (create) {
@@ -160,7 +160,7 @@
propName = MethodAccess.getPropertyName(method);
}
if (propName != null) {
- if (!factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotations(method)) {
+ if (!factory.getAnnotationIgnores().isIgnoreAnnotations(method)) {
AccessStrategy access = new MethodAccess(propName, method);
MetaProperty metaProperty = metabean.getProperty(propName);
boolean create = metaProperty == null;
@@ -198,7 +198,7 @@
*/
private void addXmlConstraints(Class<?> beanClass, MetaBean metabean) throws IllegalAccessException,
InvocationTargetException {
- for (final MetaConstraint<?, ? extends Annotation> metaConstraint : factoryContext.getFactory().getMetaConstraints(beanClass)) {
+ for (final MetaConstraint<?, ? extends Annotation> metaConstraint : factory.getMetaConstraints(beanClass)) {
Meta meta;
AccessStrategy access = metaConstraint.getAccessStrategy();
boolean create = false;
@@ -263,7 +263,7 @@
metabean.putProperty(access.getPropertyName(), null);
}
}
- for (final AccessStrategy access : factoryContext.getFactory().getValidAccesses(beanClass)) {
+ for (final AccessStrategy access : factory.getValidAccesses(beanClass)) {
if (access.getElementType() == ElementType.PARAMETER) {
continue;
}
@@ -289,7 +289,7 @@
if (groupSeq == null) {
groupSeq = metabean.initFeature(key, new ArrayList<Group>(annotation == null ? 1 : annotation.value().length));
}
- Class<?>[] groupClasses = factoryContext.getFactory().getDefaultSequence(beanClass);
+ Class<?>[] groupClasses = factory.getDefaultSequence(beanClass);
if (groupClasses == null || groupClasses.length == 0) {
if (annotation == null) {
groupSeq.add(Group.DEFAULT);
diff --git a/bval-jsr/src/test/java/org/apache/bval/jsr/ValidationTest.java b/bval-jsr/src/test/java/org/apache/bval/jsr/ValidationTest.java
index b0fa685..0419d4a 100644
--- a/bval-jsr/src/test/java/org/apache/bval/jsr/ValidationTest.java
+++ b/bval-jsr/src/test/java/org/apache/bval/jsr/ValidationTest.java
@@ -89,6 +89,10 @@
return factory.getValidator();
}
+ public void testCache() {
+ factory.getValidator().getConstraintsForClass(AccessTestBusinessObject.class);
+ factory.getValidator().getConstraintsForClass(AccessTestBusinessObject.class);
+ }
public void testAccessStrategies_field_method() {
AccessTestBusinessObject o1 = new AccessTestBusinessObject("1");
AccessTestBusinessObjectSub o2 = new AccessTestBusinessObjectSub("3");
diff --git a/bval-tck/pom.xml b/bval-tck/pom.xml
index 2521b04..249276b 100644
--- a/bval-tck/pom.xml
+++ b/bval-tck/pom.xml
@@ -169,6 +169,55 @@
<version>1.0.0</version>
</dependency>
</dependencies>
+ <repositories>
+ <repository>
+ <!-- override outdated URLs for jboss repo ids -->
+ <id>repository.jboss.org</id>
+ <name>JBoss Public Maven Repository Group</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <layout>default</layout>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ <checksumPolicy>fail</checksumPolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ <updatePolicy>never</updatePolicy>
+ <checksumPolicy>warn</checksumPolicy>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>jboss</id>
+ <name>JBoss Public Maven Repository Group (again)</name>
+ <url>https://repository.jboss.org/nexus/content/groups/public/</url>
+ <layout>default</layout>
+ <releases>
+ <enabled>true</enabled>
+ <updatePolicy>never</updatePolicy>
+ <checksumPolicy>fail</checksumPolicy>
+ </releases>
+ <snapshots>
+ <enabled>false</enabled>
+ <updatePolicy>never</updatePolicy>
+ <checksumPolicy>warn</checksumPolicy>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>snapshots.jboss.org</id>
+ <url>https://repository.jboss.org/nexus/content/repositories/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ <repository>
+ <id>jboss-snapshots</id>
+ <url>https://repository.jboss.org/nexus/content/repositories/snapshots/</url>
+ <snapshots>
+ <enabled>true</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
<build>
<plugins>
<plugin>
diff --git a/pom.xml b/pom.xml
index fb4f2b7..d60115c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -571,6 +571,7 @@
<artifactId>commons-weaver-maven-plugin</artifactId>
<version>${commons.weaver.version}</version>
<configuration>
+ <verbose>true</verbose>
<weaverConfig>
<privilizer.policy>DYNAMIC</privilizer.policy>
</weaverConfig>