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 2013/08/14 13:49:44 UTC

svn commit: r1513821 - in /bval/branches/bval-11: bval-extras/ bval-jsr303/src/main/java/org/apache/bval/cdi/ bval-jsr303/src/main/java/org/apache/bval/jsr303/ bval-tck11/

Author: rmannibucau
Date: Wed Aug 14 11:49:43 2013
New Revision: 1513821

URL: http://svn.apache.org/r1513821
Log:
using some contants + removing the loop in buildMethodDescriptors which is useless in fact

Modified:
    bval/branches/bval-11/bval-extras/pom.xml
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/cdi/BValExtension.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationProcessor.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultConstraintValidatorFactory.java
    bval/branches/bval-11/bval-tck11/work-tests-suite.xml

Modified: bval/branches/bval-11/bval-extras/pom.xml
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-extras/pom.xml?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-extras/pom.xml (original)
+++ bval/branches/bval-11/bval-extras/pom.xml Wed Aug 14 11:49:43 2013
@@ -39,7 +39,12 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.bval</groupId>
-            <artifactId>org.apache.bval.bundle</artifactId>
+            <artifactId>bval-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.bval</groupId>
+            <artifactId>bval-jsr303</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/cdi/BValExtension.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/cdi/BValExtension.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/cdi/BValExtension.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/cdi/BValExtension.java Wed Aug 14 11:49:43 2013
@@ -206,8 +206,7 @@ public class BValExtension implements Ex
                     result = bmi.loadTimeBm;
                 }
                 if (result == null) {
-                    throw new IllegalStateException("Unable to find BeanManager. " +
-                            "Please ensure that you configured the CDI implementation of your choice properly.");
+                    return null;
                 }
                 bmi.finalBm = result;
             }
@@ -251,6 +250,9 @@ public class BValExtension implements Ex
     public static <T> Releasable<T> inject(final Class<T> clazz) {
         try {
             final BeanManager beanManager = getInstance().getBeanManager();
+            if (beanManager == null) {
+                return null;
+            }
             final AnnotatedType<T> annotatedType = beanManager.createAnnotatedType(clazz);
             final InjectionTarget<T> it = beanManager.createInjectionTarget(annotatedType);
             final CreationalContext<T> context = beanManager.createCreationalContext(null);

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationConstraintBuilder.java Wed Aug 14 11:49:43 2013
@@ -132,8 +132,13 @@ final class AnnotationConstraintBuilder<
 
         final Pair validationTarget = computeValidationTarget(annotation.validatedBy());
         for (final Annotation a : annotationType.getAnnotations()) {
-            final Constraint inheritedConstraint = a.annotationType().getAnnotation(Constraint.class);
-            if (inheritedConstraint != null && !a.annotationType().getName().startsWith("javax.validation.constraints.")) {
+            final Class<? extends Annotation> aClass = a.annotationType();
+            if (aClass.getName().startsWith("java.lang.annotation.")) {
+                continue;
+            }
+
+            final Constraint inheritedConstraint = aClass.getAnnotation(Constraint.class);
+            if (inheritedConstraint != null && !aClass.getName().startsWith("javax.validation.constraints.")) {
                 final Pair validationTargetInherited = computeValidationTarget(inheritedConstraint.validatedBy());
                 if ((validationTarget.a > 0 && validationTargetInherited.b > 0 && validationTarget.b == 0)
                         || (validationTarget.b > 0 && validationTargetInherited.a > 0 && validationTarget.a == 0)) {

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationProcessor.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationProcessor.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationProcessor.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/AnnotationProcessor.java Wed Aug 14 11:49:43 2013
@@ -94,7 +94,7 @@ public final class AnnotationProcessor {
         boolean changed = false;
         for (final Annotation annotation : element.getDeclaredAnnotations()) {
             final Class<?> type = annotation.annotationType();
-            if (type.getName().startsWith("java.lang.annotation")) {
+            if (type.getName().startsWith("java.lang.annotation.")) {
                 continue;
             }
             changed |= processAnnotation(annotation, prop, owner, access, appender, true);
@@ -161,6 +161,10 @@ public final class AnnotationProcessor {
         if (result instanceof Annotation[]) {
             boolean changed = false;
             for (final Annotation each : (Annotation[]) result) {
+                if (each.annotationType().getName().startsWith("java.lang.annotation")) {
+                    continue;
+                }
+
                 changed |= processAnnotation(each, prop, owner, access, appender, reflection);
             }
             return changed;

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/BeanDescriptorImpl.java Wed Aug 14 11:49:43 2013
@@ -82,9 +82,11 @@ public class BeanDescriptorImpl extends 
     protected final ApacheFactoryContext factoryContext;
     private final AnnotationProcessor annotationProcessor;
     private Set<ConstructorDescriptor> constrainedConstructors = new CopyOnWriteArraySet<ConstructorDescriptor>();
-    private Map<Method, MethodDescriptor> methodConstraints = new HashMap<Method, MethodDescriptor>();
+    private Map<String, MethodDescriptor> methodConstraints = new HashMap<String, MethodDescriptor>();
     private Set<MethodDescriptor> containedMethods = new CopyOnWriteArraySet<MethodDescriptor>();
-    private Map<Constructor<?>, ConstructorDescriptor> contructorConstraints = new HashMap<Constructor<?>, ConstructorDescriptor>();
+    private Map<String, ConstructorDescriptor> contructorConstraints = new HashMap<String, ConstructorDescriptor>();
+    private Boolean isBeanConstrained = null;
+    private Boolean hasAnyContraints = null;
 
     protected BeanDescriptorImpl(ApacheFactoryContext factoryContext, MetaBean metaBean) {
         super(metaBean, metaBean.getBeanClass(), metaBean.getValidations());
@@ -120,8 +122,8 @@ public class BeanDescriptorImpl extends 
             if (!methodFound) {
                 final String name = Character.toUpperCase(prop.getName().charAt(0)) + prop.getName().substring(1);
                 for (final Method method : Arrays.asList(
-                                    Reflection.INSTANCE.getDeclaredMethod(current, "is" + name),
-                                    Reflection.INSTANCE.getDeclaredMethod(current, "get" + name))) {
+                    Reflection.INSTANCE.getDeclaredMethod(current, "is" + name),
+                    Reflection.INSTANCE.getDeclaredMethod(current, "get" + name))) {
 
                     if (method != null) {
                         final ConvertGroup.List convertGroupList = method.getAnnotation(ConvertGroup.List.class);
@@ -178,23 +180,45 @@ public class BeanDescriptorImpl extends 
      * @return true if the bean involves validation
      */
     public boolean isBeanConstrained() {
-        if (hasAnyConstraints())
-            return true;
-        for (MetaProperty mprop : metaBean.getProperties()) {
-            if (mprop.getMetaBean() != null || mprop.getFeature(Features.Property.REF_CASCADE) != null)
-                return true;
+        if (isBeanConstrained == null) {
+            synchronized (this) {
+                if (isBeanConstrained == null) {
+                    if (hasAnyConstraints()) {
+                        isBeanConstrained = true;
+                    } else {
+                        isBeanConstrained = false;
+                        for (final MetaProperty mprop : metaBean.getProperties()) {
+                            if (mprop.getMetaBean() != null || mprop.getFeature(Features.Property.REF_CASCADE) != null) {
+                                isBeanConstrained = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
         }
-        return false;
+        return isBeanConstrained;
     }
 
     private boolean hasAnyConstraints() {
-        if (hasConstraints())
-            return true;
-        for (MetaProperty mprop : metaBean.getProperties()) {
-            if (getConstraintDescriptors(mprop.getValidations()).size() > 0)
-                return true;
+        if (hasAnyContraints == null) {
+            synchronized (this) {
+                if (hasAnyContraints == null) {
+                    if (hasConstraints()) {
+                        hasAnyContraints = true;
+                    } else {
+                        hasAnyContraints = false;
+                        for (final MetaProperty mprop : metaBean.getProperties()) {
+                            if (getConstraintDescriptors(mprop.getValidations()).size() > 0) {
+                                hasAnyContraints = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
         }
-        return false;
+        return hasAnyContraints;
     }
 
     /**
@@ -238,65 +262,24 @@ public class BeanDescriptorImpl extends 
         Set<PropertyDescriptor> validatedProperties = new HashSet<PropertyDescriptor>();
         for (MetaProperty prop : metaBean.getProperties()) {
             if (prop.getValidations().length > 0
-                    || (prop.getMetaBean() != null || prop.getFeature(Features.Property.REF_CASCADE) != null)) {
+                || (prop.getMetaBean() != null || prop.getFeature(Features.Property.REF_CASCADE) != null)) {
                 validatedProperties.add(getPropertyDescriptor(prop));
             }
         }
         return Collections.unmodifiableSet(validatedProperties);
     }
 
-    public MethodDescriptor getConstraintsForMethod(String methodName, Class<?>... parameterTypes) {
+    public MethodDescriptor getConstraintsForMethod(final String methodName, final Class<?>... parameterTypes) {
         if (methodName == null) {
             throw new IllegalArgumentException("Method name can't be null");
         }
-
-        Class<?> beanClass = metaBean.getBeanClass();
-        Method method = null;
-        do {
-            try {
-                method = beanClass.getDeclaredMethod(methodName, parameterTypes);
-                break;
-            } catch (final NoSuchMethodException e) {
-                // no-op
-            }
-            beanClass = beanClass.getSuperclass();
-        } while (beanClass != Object.class && beanClass != null);
-        if (method == null) {
-            return null;
+        final MethodDescriptor methodDescriptor = methodConstraints.get(methodName + Arrays.toString(parameterTypes));
+        if (methodDescriptor != null && (methodDescriptor.hasConstrainedParameters() || methodDescriptor.hasConstrainedReturnValue())) {
+            return methodDescriptor;
         }
-
-        final MethodDescriptor descriptor = methodConstraints.get(method);
-        if (descriptor != null) {
-            final boolean hasConstraint = descriptor.hasConstrainedParameters() || descriptor.hasConstrainedReturnValue();
-            if (!hasConstraint) {
-                return null;
-            }
-            return descriptor;
-        }
-
-        // TODO: surely remove it
-        for (final MetaMethod metaMethod : metaBean.getMethods()) {
-            if (metaMethod.getMethod().equals(method)) {
-                final MethodDescriptorImpl methodDescriptor = createMethodDescriptor(metaMethod);
-                ensureNotNullDescriptors(metaMethod.getMethod().getReturnType(), methodDescriptor);
-                methodConstraints.put(method, methodDescriptor);
-                containedMethods.add(methodDescriptor);
-                return methodDescriptor;
-            }
-        }
-
         return null;
     }
 
-    private MethodDescriptorImpl createMethodDescriptor(final MetaMethod metaMethod) {
-        MethodDescriptorImpl edesc = metaMethod.getFeature(Jsr303Features.Method.MethodDescriptor);
-        if (edesc == null) {
-            edesc = new MethodDescriptorImpl(metaBean, metaMethod);
-            metaMethod.putFeature(Jsr303Features.Method.MethodDescriptor, edesc);
-        }
-        return edesc;
-    }
-
     public Set<MethodDescriptor> getConstrainedMethods(MethodType methodType, MethodType... methodTypes) {
         final Set<MethodDescriptor> desc = new HashSet<MethodDescriptor>();
         desc.addAll(filter(containedMethods, methodType));
@@ -318,7 +301,7 @@ public class BeanDescriptorImpl extends 
                     if (getter) {
                         list.add(d);
                     }
-                break;
+                    break;
 
                 case NON_GETTER:
                     if (!getter) {
@@ -329,15 +312,8 @@ public class BeanDescriptorImpl extends 
         return list;
     }
 
-    public ConstructorDescriptor getConstraintsForConstructor(Class<?>... parameterTypes) {
-        final Constructor<?> declaredConstructor;
-        try {
-            declaredConstructor = metaBean.getBeanClass().getDeclaredConstructor(parameterTypes);
-        } catch (final NoSuchMethodException e) {
-            return null;
-        }
-
-        final ConstructorDescriptor descriptor = contructorConstraints.get(declaredConstructor);
+    public ConstructorDescriptor getConstraintsForConstructor(final Class<?>... parameterTypes) {
+        final ConstructorDescriptor descriptor = contructorConstraints.get(Arrays.toString(parameterTypes));
         if (descriptor != null && (descriptor.hasConstrainedParameters() || descriptor.hasConstrainedReturnValue())) {
             return descriptor;
         }
@@ -383,7 +359,7 @@ public class BeanDescriptorImpl extends 
     private void buildConstructorConstraints() throws InvocationTargetException, IllegalAccessException {
         for (final Constructor<?> cons : Reflection.INSTANCE.getDeclaredConstructors(getMetaBean().getBeanClass())) {
             final ConstructorDescriptorImpl consDesc = new ConstructorDescriptorImpl(getMetaBean(), new Validation[0]);
-            contructorConstraints.put(cons, consDesc);
+            contructorConstraints.put(Arrays.toString(cons.getParameterTypes()), consDesc);
 
             final List<String> names = factoryContext.getParameterNameProvider().getParameterNames(cons);
             final boolean isInnerClass = cons.getDeclaringClass().getEnclosingClass() != null && !Modifier.isStatic(cons.getDeclaringClass().getModifiers());
@@ -518,115 +494,124 @@ public class BeanDescriptorImpl extends 
 
     private void buildMethodConstraints() throws InvocationTargetException, IllegalAccessException {
 
-        final Class<?> beanClass = getMetaBean().getBeanClass();
-        final List<Class<?>> classHierarchy = ClassHelper.fillFullClassHierarchyAsList(new ArrayList<Class<?>>(), beanClass);
-
-        Class<?> current = beanClass;
-        do {
-            classHierarchy.remove(current);
-
-            for (final Method method : Reflection.INSTANCE.getDeclaredMethods(current)) {
-                if (Modifier.isStatic(method.getModifiers()) || method.isSynthetic()) {
-                    continue;
-                }
-
-                final boolean getter = (method.getName().startsWith("get") || method.getName().startsWith("is")) && method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE;
-
-                final MethodDescriptorImpl methodDesc = new MethodDescriptorImpl(getMetaBean(), EMPTY_VALIDATION, method);
-                methodConstraints.put(method, methodDesc);
+        final Class<?> current = getMetaBean().getBeanClass();
+        final List<Class<?>> classHierarchy = ClassHelper.fillFullClassHierarchyAsList(new ArrayList<Class<?>>(), current);
+        classHierarchy.remove(current);
+
+        for (final Method method : Reflection.INSTANCE.getDeclaredMethods(current)) {
+            if (Modifier.isStatic(method.getModifiers()) || method.isSynthetic()) {
+                continue;
+            }
+
+            final boolean getter = (method.getName().startsWith("get") || method.getName().startsWith("is")) && method.getParameterTypes().length == 0 && method.getReturnType() != Void.TYPE;
+
+            final String key = method.getName() + Arrays.toString(method.getParameterTypes());
+            MethodDescriptorImpl methodDesc = MethodDescriptorImpl.class.cast(methodConstraints.get(key));
+            if (methodDesc == null) {
+                methodDesc = new MethodDescriptorImpl(getMetaBean(), EMPTY_VALIDATION, method);
+                methodConstraints.put(key, methodDesc);
+            } else {
+                continue;
+            }
 
-                final Collection<Method> parents = new ArrayList<Method>();
-                for (final Class<?> clazz : classHierarchy) {
-                    final Method overriden = Reflection.INSTANCE.getDeclaredMethod(clazz, method.getName(), method.getParameterTypes());
-                    if (overriden != null) {
-                        parents.add(overriden);
-                        processMethod(overriden, methodDesc);
-                    }
+            final Collection<Method> parents = new ArrayList<Method>();
+            for (final Class<?> clazz : classHierarchy) {
+                final Method overriden = Reflection.INSTANCE.getDeclaredMethod(clazz, method.getName(), method.getParameterTypes());
+                if (overriden != null) {
+                    parents.add(overriden);
+                    processMethod(overriden, methodDesc);
                 }
+            }
 
-                processMethod(method, methodDesc);
+            processMethod(method, methodDesc);
 
-                ensureNotNullDescriptors(method.getReturnType(), methodDesc);
+            ensureNotNullDescriptors(method.getReturnType(), methodDesc);
 
-                if (current == beanClass && parents != null) { // only valid beanClass, other validations are done through inheritance meta building
-                    if (parents.size() > 1) {
-                        for (final Method parent : parents) {
-                            final MethodDescriptor parentDec = factoryContext.getValidator().getConstraintsForClass(parent.getDeclaringClass()).getConstraintsForMethod(parent.getName(), parent.getParameterTypes());
-                            if (parentDec != null) {
-                                ensureNoParameterConstraint(InvocableElementDescriptor.class.cast(parentDec), "Parameter constraints can't be defined for parallel interfaces/parents");
-                            } else {
-                                ensureMethodDoesntDefineParameterConstraint(methodDesc);
-                            }
-                            ensureNoReturnValueAddedInChild(methodDesc.getReturnValueDescriptor(), parentDec, "Return value constraints should be the same for parent and children");
-                        }
-                    } else if (!parents.isEmpty()) {
-                        final Method parent = parents.iterator().next();
-                        final MethodDescriptor parentDesc = factoryContext.getValidator().getConstraintsForClass(parent.getDeclaringClass()).getConstraintsForMethod(parent.getName(), parent.getParameterTypes());
-                        ensureNoReturnValueAddedInChild(methodDesc.getReturnValueDescriptor(), parentDesc, "Return value constraints should be at least the same for parent and children");
-
-                        if (parentDesc != null) {
-                            final Iterator<ParameterDescriptor> parentPd = parentDesc.getParameterDescriptors().iterator();
-                            for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
-                                final ParameterDescriptor next = parentPd.next();
-                                if (pd.getConstraintDescriptors().size() != next.getConstraintDescriptors().size()) {
-                                    throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
-                                }
-                                if (pd.isCascaded() != next.isCascaded()) { // @Valid
-                                    throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
-                                }
-                            }
+            if (parents != null) {
+                if (parents.size() > 1) {
+                    for (final Method parent : parents) {
+                        final MethodDescriptor parentDec = factoryContext.getValidator().getConstraintsForClass(parent.getDeclaringClass()).getConstraintsForMethod(parent.getName(), parent.getParameterTypes());
+                        if (parentDec != null) {
+                            ensureNoParameterConstraint(InvocableElementDescriptor.class.cast(parentDec), "Parameter constraints can't be defined for parallel interfaces/parents");
                         } else {
                             ensureMethodDoesntDefineParameterConstraint(methodDesc);
                         }
+                        ensureNoReturnValueAddedInChild(methodDesc.getReturnValueDescriptor(), parentDec, "Return value constraints should be the same for parent and children");
                     }
-
-                    final Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
-                    final Collection<Method> itfWithThisMethod = new ArrayList<Method>();
-                    for (final Class<?> i : interfaces) {
-                        final Method m = Reflection.INSTANCE.getDeclaredMethod(i, method.getName(), method.getParameterTypes());
-                        if (m != null) {
-                            itfWithThisMethod.add(m);
-                        }
-                    }
-                    if (itfWithThisMethod.size() > 1) {
-                        for (final Method m : itfWithThisMethod) {
-                            ensureNoConvertGroup(m, "ConvertGroup can't be used in parallel interfaces");
+                } else if (!parents.isEmpty()) {
+                    final Method parent = parents.iterator().next();
+                    final MethodDescriptor parentDesc = factoryContext.getValidator().getConstraintsForClass(parent.getDeclaringClass()).getConstraintsForMethod(parent.getName(), parent.getParameterTypes());
+                    ensureNoReturnValueAddedInChild(methodDesc.getReturnValueDescriptor(), parentDesc, "Return value constraints should be at least the same for parent and children");
+
+                    if (parentDesc != null) {
+                        final Iterator<ParameterDescriptor> parentPd = parentDesc.getParameterDescriptors().iterator();
+                        for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
+                            final ParameterDescriptor next = parentPd.next();
+                            if (pd.getConstraintDescriptors().size() != next.getConstraintDescriptors().size()) {
+                                throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
+                            }
+                            if (pd.isCascaded() != next.isCascaded()) { // @Valid
+                                throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
+                            }
                         }
-                    } else if (itfWithThisMethod.size() == 1) {
-                        ensureNoConvertGroup(itfWithThisMethod.iterator().next(), "ConvertGroup can't be used in interface AND parent class");
+                    } else {
+                        ensureMethodDoesntDefineParameterConstraint(methodDesc);
                     }
+                }
 
-                    int returnValid = 0;
-                    if (method.getAnnotation(Valid.class) != null) {
-                        returnValid++;
-                    }
-                    for (final Class<?> clazz : classHierarchy) {
-                        final Method overriden = Reflection.INSTANCE.getDeclaredMethod(clazz, method.getName(), method.getParameterTypes());
-                        if (overriden != null) {
-                            if (overriden.getAnnotation(Valid.class) != null) {
-                                returnValid++;
-                            }
-                        }
+                final Class<?>[] interfaces = method.getDeclaringClass().getInterfaces();
+                final Collection<Method> itfWithThisMethod = new ArrayList<Method>();
+                for (final Class<?> i : interfaces) {
+                    final Method m = Reflection.INSTANCE.getDeclaredMethod(i, method.getName(), method.getParameterTypes());
+                    if (m != null) {
+                        itfWithThisMethod.add(m);
                     }
-                    if (returnValid > 1 && !(interfaces.length == returnValid && method.getAnnotation(Valid.class) == null)) {
-                        throw new ConstraintDeclarationException("@Valid on returned value can't be set more than once");
+                }
+                if (itfWithThisMethod.size() > 1) {
+                    for (final Method m : itfWithThisMethod) {
+                        ensureNoConvertGroup(m, "ConvertGroup can't be used in parallel interfaces");
                     }
+                } else if (itfWithThisMethod.size() == 1) {
+                    ensureNoConvertGroup(itfWithThisMethod.iterator().next(), "ConvertGroup can't be used in interface AND parent class");
                 }
 
-                if (getter) {
-                    final MetaProperty prop = metaBean.getProperty(Introspector.decapitalize(method.getName().substring(3)));
-                    if (prop != null && prop.getFeature(Features.Property.REF_CASCADE) != null) {
-                        methodDesc.setCascaded(true);
+                int returnValid = 0;
+                if (method.getAnnotation(Valid.class) != null) {
+                    returnValid++;
+                }
+                for (final Class<?> clazz : classHierarchy) {
+                    final Method overriden = Reflection.INSTANCE.getDeclaredMethod(clazz, method.getName(), method.getParameterTypes());
+                    if (overriden != null) {
+                        if (overriden.getAnnotation(Valid.class) != null) {
+                            returnValid++;
+                        }
                     }
                 }
+                if (returnValid > 1 && !(interfaces.length == returnValid && method.getAnnotation(Valid.class) == null)) {
+                    throw new ConstraintDeclarationException("@Valid on returned value can't be set more than once");
+                }
+            }
 
-                if (!methodDesc.getGroupConversions().isEmpty() && !methodDesc.isCascaded()) {
-                    throw new ConstraintDeclarationException("@Valid is needed to define a group conversion");
+            if (getter) {
+                final MetaProperty prop = metaBean.getProperty(Introspector.decapitalize(method.getName().substring(3)));
+                if (prop != null && prop.getFeature(Features.Property.REF_CASCADE) != null) {
+                    methodDesc.setCascaded(true);
                 }
             }
 
-            current = current.getSuperclass();
-        } while (current != null && current != Object.class);
+            if (!methodDesc.getGroupConversions().isEmpty() && !methodDesc.isCascaded()) {
+                throw new ConstraintDeclarationException("@Valid is needed to define a group conversion");
+            }
+        }
+
+        for (final Class<?> parent : classHierarchy) {
+            final BeanDescriptorImpl desc = BeanDescriptorImpl.class.cast(factoryContext.getValidator().getConstraintsForClass(parent));
+            for (final String s : desc.methodConstraints.keySet()) {
+                if (!methodConstraints.containsKey(s)) { // method from the parent only
+                    methodConstraints.put(s, desc.methodConstraints.get(s));
+                }
+            }
+        }
     }
 
     private void ensureMethodDoesntDefineParameterConstraint(MethodDescriptorImpl methodDesc) {
@@ -736,7 +721,7 @@ public class BeanDescriptorImpl extends 
     }
 
     private AppendValidationToList processAnnotations(InvocableElementDescriptor methodDesc, Annotation[] paramAnnos, AccessStrategy access, int idx, String name)
-            throws InvocationTargetException, IllegalAccessException {
+        throws InvocationTargetException, IllegalAccessException {
         final AppendValidationToList validations = new AppendValidationToList();
         boolean cascaded = false;
 
@@ -773,7 +758,7 @@ public class BeanDescriptorImpl extends 
 
         if (paramDesc == null) {
             paramDesc = new ParameterDescriptorImpl(Class.class.cast(access.getJavaType()), // set from getParameterTypes() so that's a Class<?>
-                    validations.getValidations().toArray(new Validation[validations.getValidations().size()]), name);
+                validations.getValidations().toArray(new Validation[validations.getValidations().size()]), name);
             paramDesc.setIndex(idx);
             final List<ParameterDescriptor> parameterDescriptors = methodDesc.getParameterDescriptors();
             if (!parameterDescriptors.contains(paramDesc)) {

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java Wed Aug 14 11:49:43 2013
@@ -1117,7 +1117,8 @@ public class ClassValidator implements C
     }
 
     private <T> MethodDescriptorImpl findMethodDescriptor(final T object, final Method method) {
-        return MethodDescriptorImpl.class.cast(getConstraintsForClass(Proxies.classFor(object.getClass())).getConstraintsForMethod(method.getName(), method.getParameterTypes()));
+        // return MethodDescriptorImpl.class.cast(getConstraintsForClass(Proxies.classFor(object.getClass())).getConstraintsForMethod(method.getName(), method.getParameterTypes()));
+        return MethodDescriptorImpl.class.cast(getConstraintsForClass(Proxies.classFor(method.getDeclaringClass())).getConstraintsForMethod(method.getName(), method.getParameterTypes()));
     }
 
     private <T> void initMetaBean(final GroupValidationContext<T> context, final MetaBeanFinder metaBeanFinder, final Class<?> directValueClass) {

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultConstraintValidatorFactory.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultConstraintValidatorFactory.java?rev=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultConstraintValidatorFactory.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultConstraintValidatorFactory.java Wed Aug 14 11:49:43 2013
@@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteA
  */
 public class DefaultConstraintValidatorFactory implements ConstraintValidatorFactory, Closeable {
     private final Collection< BValExtension.Releasable<?>> releasables = new CopyOnWriteArrayList<BValExtension.Releasable<?>>();
+    private Boolean useCdi = null; // store it to avoid NoClassDefFoundError when cdi is not present (it is slow) + lazily (to wait cdi is started)
 
     /**
      * Instantiate a Constraint.
@@ -42,16 +43,35 @@ public class DefaultConstraintValidatorF
      *         The ConstraintFactory is <b>not</b> responsible for calling Constraint#initialize
      */
     public <T extends ConstraintValidator<?, ?>> T getInstance(final Class<T> constraintClass) {
+        if (useCdi == null) {
+            synchronized (this) {
+                if (useCdi == null) {
+                    try {
+                        useCdi = BValExtension.getInstance() != null && BValExtension.getInstance().getBeanManager() != null;
+                    } catch (final NoClassDefFoundError error) {
+                        useCdi = false;
+                    } catch (final Exception e) {
+                        useCdi = false;
+                    }
+                }
+            }
+        }
+
         // 2011-03-27 jw: Do not use PrivilegedAction.
         // Otherwise any user code would be executed with the privileges of this class.
         try {
-            try {
-                return BValExtension.inject(constraintClass).getInstance();
-            } catch (final Exception e) {
-                return constraintClass.newInstance();
-            } catch (final NoClassDefFoundError error) {
-                return constraintClass.newInstance();
+            if (useCdi) {
+                try {
+                    final BValExtension.Releasable<T> instance = BValExtension.inject(constraintClass);
+                    releasables.add(instance);
+                    return instance.getInstance();
+                } catch (final Exception e) {
+                    return constraintClass.newInstance();
+                } catch (final NoClassDefFoundError error) {
+                    return constraintClass.newInstance();
+                }
             }
+            return constraintClass.newInstance();
         } catch (final Exception ex) {
             throw new ValidationException("Cannot instantiate : " + constraintClass, ex);
         }

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=1513821&r1=1513820&r2=1513821&view=diff
==============================================================================
--- bval/branches/bval-11/bval-tck11/work-tests-suite.xml (original)
+++ bval/branches/bval-11/bval-tck11/work-tests-suite.xml Wed Aug 14 11:49:43 2013
@@ -21,9 +21,9 @@ think to add -Dvalidation.provider=org.a
 <suite name="tmp" verbose="1">
   <test name="tmp">
     <classes>
-      <class name="org.hibernate.beanvalidation.tck.tests.metadata.ExecutableDescriptorTest">
+      <class name="org.hibernate.beanvalidation.tck.tests.metadata.BeanDescriptorTest">
         <methods>
-          <include name="testFindConstraintsForMethodDefinedOnSuperTypeLookingAt" />
+          <include name="testGetConstraintsForNonExistingMethod" />
         </methods>
       </class>
     </classes>