From commits-return-2769-archive-asf-public=cust-asf.ponee.io@bval.apache.org Mon Jun 10 05:02:42 2019 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id 4B2211807BD for ; Mon, 10 Jun 2019 07:02:40 +0200 (CEST) Received: (qmail 81453 invoked by uid 500); 10 Jun 2019 05:02:39 -0000 Mailing-List: contact commits-help@bval.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@bval.apache.org Delivered-To: mailing list commits@bval.apache.org Received: (qmail 81227 invoked by uid 99); 10 Jun 2019 05:02:39 -0000 Received: from ec2-52-202-80-70.compute-1.amazonaws.com (HELO gitbox.apache.org) (52.202.80.70) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 10 Jun 2019 05:02:39 +0000 Received: by gitbox.apache.org (ASF Mail Server at gitbox.apache.org, from userid 33) id 0C84B87A87; Mon, 10 Jun 2019 05:02:39 +0000 (UTC) Date: Mon, 10 Jun 2019 05:02:45 +0000 To: "commits@bval.apache.org" Subject: [bval] 07/19: 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 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit From: rmannibucau@apache.org In-Reply-To: <156014295862.16604.16789784474394942680@gitbox.apache.org> References: <156014295862.16604.16789784474394942680@gitbox.apache.org> X-Git-Host: gitbox.apache.org X-Git-Repo: bval X-Git-Refname: refs/tags/1.1.1 X-Git-Reftype: tag X-Git-Rev: a0f915aa81a24d2ea82354e5abaa8c6d10a050e6 X-Git-NotificationType: diff X-Git-Multimail-Version: 1.5.dev Auto-Submitted: auto-generated Message-Id: <20190610050239.0C84B87A87@gitbox.apache.org> This is an automated email from the ASF dual-hosted git repository. rmannibucau pushed a commit to tag 1.1.1 in repository https://gitbox.apache.org/repos/asf/bval.git commit a0f915aa81a24d2ea82354e5abaa8c6d10a050e6 Author: rmannibucau AuthorDate: Wed Dec 23 12:45:01 2015 +0000 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: http://svn.apache.org/repos/asf/bval/trunk@1721536 13f79535-47bb-0310-9956-ffa450edef68 --- bval-jsr/pom.xml | 2 + .../bval/jsr/AnnotationConstraintBuilder.java | 50 +++--- .../org/apache/bval/jsr/AnnotationProcessor.java | 22 +-- .../org/apache/bval/jsr/ApacheFactoryContext.java | 167 ++------------------- .../apache/bval/jsr/ApacheValidatorFactory.java | 155 +++++++++++++++++-- .../org/apache/bval/jsr/BeanDescriptorImpl.java | 7 +- .../java/org/apache/bval/jsr/ClassValidator.java | 10 +- .../org/apache/bval/jsr/ConstraintValidation.java | 12 +- .../apache/bval/jsr/GroupValidationContext.java | 7 + .../bval/jsr/GroupValidationContextImpl.java | 12 +- .../org/apache/bval/jsr/JsrMetaBeanFactory.java | 24 +-- .../java/org/apache/bval/jsr/ValidationTest.java | 4 + bval-tck/pom.xml | 49 ++++++ pom.xml | 1 + 14 files changed, 290 insertions(+), 232 deletions(-) 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 @@ + 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.Set; 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 @@ final class AnnotationConstraintBuilder { /** * Create a new AnnotationConstraintBuilder instance. - * + * * @param validatorClasses * @param annotation * @param owner * @param access */ - public AnnotationConstraintBuilder(ConstraintValidatorFactory factory, - Class>[] validatorClasses, A annotation, Class owner, - AccessStrategy access, ConstraintTarget target) { + public AnnotationConstraintBuilder( + Class>[] validatorClasses, A annotation, Class owner, + AccessStrategy access, ConstraintTarget target) { final boolean reportFromComposite = annotation != null && annotation.annotationType().isAnnotationPresent(ReportAsSingleViolation.class); constraintValidation = - new ConstraintValidation(factory, validatorClasses, annotation, owner, access, reportFromComposite, + new ConstraintValidation(validatorClasses, annotation, owner, access, reportFromComposite, target); buildFromAnnotation(); } @@ -259,7 +257,7 @@ final class AnnotationConstraintBuilder { /** * Get the configured {@link ConstraintValidation}. - * + * * @return {@link ConstraintValidation} */ public ConstraintValidation getConstraintValidation() { @@ -309,7 +307,7 @@ final class AnnotationConstraintBuilder { * 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.SupportedValidationTarget; 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 @@ import java.util.Set; @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 @@ public final class AnnotationProcessor { * @throws InvocationTargetException */ public 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 @@ public final class AnnotationProcessor { } final Class annotationType = (Class) annotation.annotationType(); Class>[] validatorClasses = - factoryContext.getFactory().getConstraintsCache().getConstraintValidators(annotationType); + factory.getConstraintsCache().getConstraintValidators(annotationType); if (validatorClasses == null) { validatorClasses = (Class>[]) vcAnno.validatedBy(); if (validatorClasses.length == 0) { - validatorClasses = - factoryContext.getFactory().getDefaultConstraints().getValidatorClasses(annotationType); + validatorClasses = factory.getDefaultConstraints().getValidatorClasses(annotationType); } } return validatorClasses; @@ -234,7 +232,8 @@ public final class AnnotationProcessor { * @throws IllegalAccessException * @throws InvocationTargetException */ - private boolean applyConstraint(A annotation, + private boolean applyConstraint( + A annotation, Class>[] rawConstraintClasses, Meta prop, Class owner, AccessStrategy access, AppendValidation appender) throws IllegalAccessException, InvocationTargetException { @@ -244,7 +243,8 @@ public final class AnnotationProcessor { } final AnnotationConstraintBuilder builder = - new AnnotationConstraintBuilder(factoryContext.getConstraintValidatorFactory(), constraintClasses, + new AnnotationConstraintBuilder( + 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 * ClassValidator instances.
@@ -52,7 +37,7 @@ import org.apache.commons.weaver.privilizer.Privilizing.CallTo; @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 @@ public class ApacheFactoryContext implements ValidatorContext { * 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 @@ public class ApacheFactoryContext implements ValidatorContext { 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 class ApacheFactoryContext implements ValidatorContext { */ public ValidatorContext traversableResolver(TraversableResolver traversableResolver) { this.traversableResolver = traversableResolver; + resetMeta(); return this; } @@ -120,11 +101,13 @@ public class ApacheFactoryContext implements ValidatorContext { */ 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 @@ public class ApacheFactoryContext implements ValidatorContext { return Boolean.parseBoolean(factory.getProperties().get( ApacheValidatorConfiguration.Properties.TREAT_MAPS_LIKE_BEANS)); } - - /** - * Create MetaBeanManager that uses factories: - *
    - *
  1. if enabled by - * {@link ApacheValidatorConfiguration.Properties#ENABLE_INTROSPECTOR}, an - * {@link IntrospectorMetaBeanFactory}
  2. - *
  3. {@link MetaBeanFactory} types (if any) specified by - * {@link ApacheValidatorConfiguration.Properties#METABEAN_FACTORY_CLASSNAMES} - *
  4. - *
  5. if no {@link JsrMetaBeanFactory} has yet been specified (this - * allows factory order customization), a {@link JsrMetaBeanFactory} - * which handles both JSR303-XML and JSR303-Annotations
  6. - *
  7. if enabled by - * {@link ApacheValidatorConfiguration.Properties#ENABLE_METABEANS_XML}, an - * {@link XMLMetaBeanFactory}
  8. - *
- * - * @return a new instance of MetaBeanManager with adequate MetaBeanFactories - */ - protected MetaBeanFinder buildMetaBeanFinder() { - final List builders = new ArrayList(); - 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 factoryClass = (Class) 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 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 createMetaBeanFactory(final Class cls) { - try { - Constructor 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 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 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.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; @@ -80,6 +91,60 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { private final ConcurrentMap, List>> constraintMap; private final Collection toClose = new ArrayList(); + private final MetaBeanFinder defaultMetaBeanFinder; + + /** + * Create MetaBeanManager that uses factories: + *
    + *
  1. if enabled by + * {@link ApacheValidatorConfiguration.Properties#ENABLE_INTROSPECTOR}, an + * {@link IntrospectorMetaBeanFactory}
  2. + *
  3. {@link MetaBeanFactory} types (if any) specified by + * {@link ApacheValidatorConfiguration.Properties#METABEAN_FACTORY_CLASSNAMES} + *
  4. + *
  5. if no {@link JsrMetaBeanFactory} has yet been specified (this + * allows factory order customization), a {@link JsrMetaBeanFactory} + * which handles both JSR303-XML and JSR303-Annotations
  6. + *
  7. if enabled by + * {@link ApacheValidatorConfiguration.Properties#ENABLE_METABEANS_XML}, an + * {@link XMLMetaBeanFactory}
  8. + *
+ * + * @return a new instance of MetaBeanManager with adequate MetaBeanFactories + */ + protected MetaBeanFinder buildMetaBeanFinder() { + final List builders = new ArrayList(); + 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 factoryClass = (Class) 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 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { /** * Create a new ApacheValidatorFactory instance. */ - public ApacheValidatorFactory(ConfigurationState configurationState) { - properties = new HashMap(); + public ApacheValidatorFactory(ConfigurationState configuration) { + properties = new HashMap(configuration.getProperties()); defaultSequences = new HashMap, Class[]>(); validAccesses = new ConcurrentHashMap, List>(); constraintMap = new ConcurrentHashMap, List>>(); - 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 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { } new ValidationMappingParser(this).processMappingConfig(configuration.getMappingStreams()); + + defaultMetaBeanFinder = buildMetaBeanFinder(); } /** @@ -165,7 +221,7 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { * @return the validator factory's context */ public ApacheFactoryContext usingContext() { - return new ApacheFactoryContext(this); + return new ApacheFactoryContext(this, defaultMetaBeanFinder); } /** @@ -428,4 +484,73 @@ public class ApacheValidatorFactory implements ValidatorFactory, Cloneable { 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 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 createMetaBeanFactory(final Class cls) { + try { + Constructor 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 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 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.MethodType; 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 @@ public class BeanDescriptorImpl extends ElementDescriptorImpl implements BeanDes private ExecutableMeta(final ApacheFactoryContext factoryContext, final MetaBean metaBean1, final Collection> constraintDescriptors) { this.metaBean = metaBean1; this.factoryContext = factoryContext; - this.annotationProcessor = new AnnotationProcessor(factoryContext); + this.annotationProcessor = new AnnotationProcessor(factoryContext.getFactory()); buildExecutableDescriptors(); @@ -840,7 +839,9 @@ public class BeanDescriptorImpl extends ElementDescriptorImpl implements BeanDes } } } 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 @@ public class ClassValidator implements CascadingPropertyValidator, ExecutableVal protected GroupValidationContext createContext(MetaBean metaBean, T object, Class objectClass, Class... groups) { final ConstraintValidationListener listener = new ConstraintValidationListener(object, objectClass); final GroupValidationContextImpl context = - new GroupValidationContextImpl(listener, this.factoryContext.getMessageInterpolator(), - this.factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(), metaBean); + new GroupValidationContextImpl(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 @@ public class ClassValidator implements CascadingPropertyValidator, ExecutableVal protected GroupValidationContext createInvocableContext(MetaBean metaBean, T object, Class objectClass, Class... groups) { final ConstraintValidationListener listener = new ConstraintValidationListener(object, objectClass); final GroupValidationContextImpl context = - new GroupValidationContextImpl(listener, this.factoryContext.getMessageInterpolator(), - this.factoryContext.getTraversableResolver(), factoryContext.getParameterNameProvider(), metaBean); + new GroupValidationContextImpl(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.ValidationException; 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 @@ import java.util.Set; * this instance is immutable!
*/ public class ConstraintValidation implements Validation, ConstraintDescriptor { - private final ConstraintValidatorFactory factory; private final AccessStrategy access; private final boolean reportFromComposite; private final Map attributes; @@ -82,11 +80,9 @@ public class ConstraintValidation implements Validation, C private Class>[] validatorClasses; private ConstraintTarget validationAppliesTo = null; - public ConstraintValidation(ConstraintValidatorFactory factory, - Class>[] validatorClasses, + public ConstraintValidation(Class>[] validatorClasses, T annotation, Class owner, AccessStrategy access, boolean reportFromComposite, ConstraintTarget target) { - this.factory = factory; this.attributes = new HashMap(); this.validatorClasses = ArrayUtils.clone(validatorClasses); this.annotation = annotation; @@ -158,7 +154,8 @@ public class ConstraintValidation implements Validation, C 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 @@ public class ConstraintValidation implements Validation, C } } - private
ConstraintValidator getConstraintValidator(A annotation, + private ConstraintValidator getConstraintValidator( + ConstraintValidatorFactory factory, A annotation, Class>[] 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.MetaBean; 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 @@ public interface GroupValidationContext 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.model.MetaProperty; 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 @@ final class GroupValidationContextImpl extends BeanValidationContext constraintValidation; private final TraversableResolver traversableResolver; + private final ConstraintValidatorFactory constraintValidatorFactory; private Object[] parameters; private Object returnValue; @@ -86,11 +88,14 @@ final class GroupValidationContextImpl extends BeanValidationContext listener, MessageInterpolator aMessageResolver, - TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider, MetaBean rootMetaBean) { + TraversableResolver traversableResolver, ParameterNameProvider parameterNameProvider, + ConstraintValidatorFactory constraintValidatorFactory, + MetaBean rootMetaBean) { // inherited variable 'validatedObjects' is of type: // HashMap> in this class super(listener, new HashMap>()); this.messageResolver = aMessageResolver; + this.constraintValidatorFactory = constraintValidatorFactory; this.traversableResolver = CachingTraversableResolver.cacheFor(traversableResolver); this.parameterNameProvider = parameterNameProvider; this.rootMetaBean = rootMetaBean; @@ -313,6 +318,11 @@ final class GroupValidationContextImpl extends BeanValidationContext beanClass, MetaBean metabean) throws IllegalAccessException, InvocationTargetException { - for (final MetaConstraint metaConstraint : factoryContext.getFactory().getMetaConstraints(beanClass)) { + for (final MetaConstraint metaConstraint : factory.getMetaConstraints(beanClass)) { Meta meta; AccessStrategy access = metaConstraint.getAccessStrategy(); boolean create = false; @@ -263,7 +263,7 @@ public class JsrMetaBeanFactory implements MetaBeanFactory { 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 @@ public class JsrMetaBeanFactory implements MetaBeanFactory { if (groupSeq == null) { groupSeq = metabean.initFeature(key, new ArrayList(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 @@ public class ValidationTest extends TestCase { 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 @@ 1.0.0 + + + + repository.jboss.org + JBoss Public Maven Repository Group + https://repository.jboss.org/nexus/content/groups/public/ + default + + true + never + fail + + + false + never + warn + + + + jboss + JBoss Public Maven Repository Group (again) + https://repository.jboss.org/nexus/content/groups/public/ + default + + true + never + fail + + + false + never + warn + + + + snapshots.jboss.org + https://repository.jboss.org/nexus/content/repositories/snapshots/ + + true + + + + jboss-snapshots + https://repository.jboss.org/nexus/content/repositories/snapshots/ + + true + + + diff --git a/pom.xml b/pom.xml index fb4f2b7..d60115c 100644 --- a/pom.xml +++ b/pom.xml @@ -571,6 +571,7 @@ commons-weaver-maven-plugin ${commons.weaver.version} + true DYNAMIC