You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by rm...@apache.org on 2015/04/23 10:17:47 UTC

svn commit: r1675554 - in /bval/branches/bval-11: bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java bval-tck11/pom.xml bval-tck11/work-tests-suite.xml

Author: rmannibucau
Date: Thu Apr 23 08:17:47 2015
New Revision: 1675554

URL: http://svn.apache.org/r1675554
Log:
using last released spec jars + owb release + using AnnotatedType instead of pure reflection for BValInterceptor

Modified:
    bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
    bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java
    bval/branches/bval-11/bval-tck11/pom.xml
    bval/branches/bval-11/bval-tck11/work-tests-suite.xml

Modified: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java?rev=1675554&r1=1675553&r2=1675554&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java (original)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValExtension.java Thu Apr 23 08:17:47 2015
@@ -31,6 +31,7 @@ import javax.enterprise.inject.spi.Exten
 import javax.enterprise.inject.spi.InjectionTarget;
 import javax.enterprise.inject.spi.ProcessAnnotatedType;
 import javax.enterprise.inject.spi.ProcessBean;
+import javax.enterprise.inject.spi.WithAnnotations;
 import javax.validation.BootstrapConfiguration;
 import javax.validation.Configuration;
 import javax.validation.Validation;
@@ -151,6 +152,7 @@ public class BValExtension implements Ex
         beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(BValInterceptor.class));
     }
 
+    // @WithAnnotations(ValidateOnExecution.class) doesn't check interfaces so not enough
     public <A> void processAnnotatedType(final @Observes ProcessAnnotatedType<A> pat) {
         if (!isExecutableValidationEnabled) {
             return;
@@ -178,9 +180,6 @@ public class BValExtension implements Ex
                                 || validBusinessMethods && !classConstraints.getConstrainedMethods(MethodType.NON_GETTER).isEmpty()
                                 || validGetterMethods && !classConstraints.getConstrainedMethods(MethodType.GETTER).isEmpty())
                             ) {
-                        // TODO: keep track of bValAnnotatedType and remove @BValBinding in
-                        // ProcessBean event if needed cause here we can't really add @ValidateOnExecution
-                        // through an extension
                         final BValAnnotatedType<A> bValAnnotatedType = new BValAnnotatedType<A>(annotatedType);
                         pat.setAnnotatedType(bValAnnotatedType);
                     }

Modified: bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java?rev=1675554&r1=1675553&r2=1675554&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java (original)
+++ bval/branches/bval-11/bval-jsr/src/main/java/org/apache/bval/cdi/BValInterceptor.java Thu Apr 23 08:17:47 2015
@@ -21,7 +21,23 @@ package org.apache.bval.cdi;
 import org.apache.bval.jsr.util.ClassHelper;
 import org.apache.bval.jsr.util.Proxies;
 
+import java.io.Serializable;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.annotation.Priority;
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.CDI;
 import javax.inject.Inject;
 import javax.interceptor.AroundConstruct;
 import javax.interceptor.AroundInvoke;
@@ -37,17 +53,7 @@ import javax.validation.executable.Valid
 import javax.validation.metadata.ConstructorDescriptor;
 import javax.validation.metadata.MethodDescriptor;
 
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
+import static java.util.Arrays.asList;
 
 /**
  * Interceptor class for the {@link BValBinding} {@link InterceptorBinding}.
@@ -57,10 +63,10 @@ import java.util.concurrent.ConcurrentHa
 @Priority(4800)
 // TODO: maybe add it through ASM to be compliant with CDI 1.0 containers using simply this class as a template to
 // generate another one for CDI 1.1 impl
-public class BValInterceptor {
-    private final Map<Method, Boolean> methodConfiguration = new ConcurrentHashMap<Method, Boolean>();
-    private Set<ExecutableType> classConfiguration;
-    private Boolean constructorValidated;
+public class BValInterceptor implements Serializable {
+    private transient volatile Map<Method, Boolean> methodConfiguration = new ConcurrentHashMap<Method, Boolean>();
+    private transient volatile Set<ExecutableType> classConfiguration;
+    private transient volatile Boolean constructorValidated;
 
     @Inject
     private Validator validator;
@@ -68,10 +74,9 @@ public class BValInterceptor {
     @Inject
     private BValExtension globalConfiguration;
 
-    private ExecutableValidator executableValidator;
+    private transient volatile ExecutableValidator executableValidator;
 
-    @AroundConstruct
-    // TODO: see previous one
+    @AroundConstruct // TODO: see previous one
     public Object construct(final InvocationContext context) throws Exception {
         @SuppressWarnings("rawtypes")
         final Constructor constructor = context.getConstructor();
@@ -156,9 +161,18 @@ public class BValInterceptor {
         if (constructorValidated == null) {
             synchronized (this) {
                 if (constructorValidated == null) {
-                    final ValidateOnExecution annotation =
-                        targetClass.getConstructor(constructor.getParameterTypes()).getAnnotation(
-                            ValidateOnExecution.class);
+                    final AnnotatedType<?> annotatedType = CDI.current().getBeanManager().createAnnotatedType(constructor.getDeclaringClass());
+                    AnnotatedConstructor<?> annotatedConstructor = null;
+                    for (final AnnotatedConstructor<?> ac : annotatedType.getConstructors()) {
+                        if (!constructor.equals(ac.getJavaMember())) {
+                            continue;
+                        }
+                        annotatedConstructor = ac;
+                        break;
+                    }
+                    final ValidateOnExecution annotation = annotatedConstructor != null ?
+                            annotatedConstructor.getAnnotation(ValidateOnExecution.class) :
+                            targetClass.getConstructor(constructor.getParameterTypes()).getAnnotation(ValidateOnExecution.class);
                     if (annotation == null) {
                         constructorValidated = classConfiguration.contains(ExecutableType.CONSTRUCTORS);
                     } else {
@@ -171,36 +185,56 @@ public class BValInterceptor {
             }
         }
 
-        return constructorValidated.booleanValue();
+        return constructorValidated;
     }
 
     private boolean isMethodValidated(final Class<?> targetClass, final Method method) throws NoSuchMethodException {
         initClassConfig(targetClass);
 
+        if (methodConfiguration == null) {
+            synchronized (this) {
+                if (methodConfiguration == null) {
+                    methodConfiguration = new ConcurrentHashMap<Method, Boolean>();
+                }
+            }
+        }
+
         Boolean methodConfig = methodConfiguration.get(method);
         if (methodConfig == null) {
             synchronized (this) {
                 methodConfig = methodConfiguration.get(method);
                 if (methodConfig == null) {
                     final List<Class<?>> classHierarchy =
-                        ClassHelper.fillFullClassHierarchyAsList(new ArrayList<Class<?>>(), targetClass);
-
-                    Class<?> lastClassWithTheMethod = null;
+                            ClassHelper.fillFullClassHierarchyAsList(new LinkedList<Class<?>>(), targetClass);
+                    Collections.reverse(classHierarchy);
 
                     // search on method @ValidateOnExecution
-                    Collections.reverse(classHierarchy);
                     ValidateOnExecution validateOnExecution = null;
+                    ValidateOnExecution validateOnExecutionType = null;
                     for (final Class<?> c : classHierarchy) {
+                        final AnnotatedType<?> annotatedType = CDI.current().getBeanManager().createAnnotatedType(c);
+                        AnnotatedMethod<?> annotatedMethod = null;
+                        for (final AnnotatedMethod<?> m : annotatedType.getMethods()) {
+                            if (!m.getJavaMember().getName().equals(method.getName())
+                                    || !asList(method.getGenericParameterTypes()).equals(asList(m.getJavaMember().getGenericParameterTypes()))) {
+                                continue;
+                            }
+                            annotatedMethod = m;
+                            break;
+                        }
                         try {
-                            validateOnExecution =
-                                c.getDeclaredMethod(method.getName(), method.getParameterTypes()).getAnnotation(
-                                    ValidateOnExecution.class);
-                            if (lastClassWithTheMethod == null) {
-                                lastClassWithTheMethod = c;
+                            if (annotatedMethod == null) {
+                                continue;
                             }
-                            if (validateOnExecution != null) {
-                                lastClassWithTheMethod = null;
-                                break;
+                            if (validateOnExecutionType == null) {
+                                final ValidateOnExecution vat = annotatedType.getAnnotation(ValidateOnExecution.class);
+                                if (vat != null) {
+                                    validateOnExecutionType = vat;
+                                }
+                            }
+                            final ValidateOnExecution mvat = annotatedMethod.getAnnotation(ValidateOnExecution.class);
+                            if (mvat != null) {
+                                validateOnExecution = mvat;
                             }
                         } catch (final Throwable h) {
                             // no-op
@@ -208,8 +242,10 @@ public class BValInterceptor {
                     }
 
                     // if not found look in the class declaring the method
-                    if (validateOnExecution == null && lastClassWithTheMethod != null) {
-                        validateOnExecution = lastClassWithTheMethod.getAnnotation(ValidateOnExecution.class);
+                    boolean classMeta = false;
+                    if (validateOnExecution == null) {
+                        validateOnExecution = validateOnExecutionType;
+                        classMeta = validateOnExecution != null;
                     }
 
                     if (validateOnExecution == null) {
@@ -227,7 +263,7 @@ public class BValInterceptor {
                             }
                             if (ExecutableType.IMPLICIT == type) { // on method it just means validate, even on getters
                                 config.add(ExecutableType.NON_GETTER_METHODS);
-                                if (lastClassWithTheMethod == null) {
+                                if (!classMeta) {
                                     config.add(ExecutableType.GETTER_METHODS);
                                 } // else the annotation was not on the method so implicit doesn't mean getters
                             } else {
@@ -250,7 +286,8 @@ public class BValInterceptor {
                 if (classConfiguration == null) {
                     classConfiguration = EnumSet.noneOf(ExecutableType.class);
 
-                    final ValidateOnExecution annotation = targetClass.getAnnotation(ValidateOnExecution.class);
+                    final AnnotatedType<?> annotatedType = CDI.current().getBeanManager().createAnnotatedType(targetClass);
+                    final ValidateOnExecution annotation = annotatedType.getAnnotation(ValidateOnExecution.class);
                     if (annotation == null) {
                         classConfiguration.addAll(globalConfiguration.getGlobalExecutableTypes());
                     } else {

Modified: bval/branches/bval-11/bval-tck11/pom.xml
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-tck11/pom.xml?rev=1675554&r1=1675553&r2=1675554&view=diff
==============================================================================
--- bval/branches/bval-11/bval-tck11/pom.xml (original)
+++ bval/branches/bval-11/bval-tck11/pom.xml Thu Apr 23 08:17:47 2015
@@ -34,8 +34,8 @@ under the License.
 
     <properties>
         <tck.version>1.1.3.Final</tck.version>
-        <owb.version>1.5.0-SNAPSHOT</owb.version>
-        <arquillian.version>1.1.7.Final</arquillian.version>
+        <owb.version>1.5.0</owb.version>
+        <arquillian.version>1.1.8.Final</arquillian.version>
         <validation.provider>org.apache.bval.jsr.ApacheValidationProvider</validation.provider>
     </properties>
 
@@ -56,19 +56,19 @@ under the License.
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-jcdi_1.1_spec</artifactId>
-            <version>1.0-alpha-1</version>
+            <version>1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-annotation_1.2_spec</artifactId>
-            <version>1.0-alpha-1</version>
+            <version>1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-interceptor_1.2_spec</artifactId>
-            <version>1.0-alpha-1</version>
+            <version>1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

Modified: bval/branches/bval-11/bval-tck11/work-tests-suite.xml
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-tck11/work-tests-suite.xml?rev=1675554&r1=1675553&r2=1675554&view=diff
==============================================================================
--- bval/branches/bval-11/bval-tck11/work-tests-suite.xml (original)
+++ bval/branches/bval-11/bval-tck11/work-tests-suite.xml Thu Apr 23 08:17:47 2015
@@ -21,7 +21,7 @@ think to add -Dvalidation.provider=org.a
 <suite name="tmp" verbose="1">
   <test name="tmp">
     <classes>
-      <class name="org.hibernate.beanvalidation.tck.tests.integration.cdi.executable.types.ExecutableTypesTest">
+      <class name="org.hibernate.beanvalidation.tck.tests.integration.cdi.executable.ExecutableValidationTest">
         <methods>
 
         </methods>