bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject svn commit: r1513952 - in /bval/branches/bval-11: bval-core/src/main/java/org/apache/bval/model/ bval-jsr303/src/main/java/org/apache/bval/jsr303/
Date Wed, 14 Aug 2013 16:33:15 GMT
Author: rmannibucau
Date: Wed Aug 14 16:33:15 2013
New Revision: 1513952

URL: http://svn.apache.org/r1513952
Log:
adding some caching in BeanDescriptorImpl

Modified:
    bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/model/Features.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/DefaultMessageInterpolator.java
    bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ElementDescriptorImpl.java

Modified: bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/model/Features.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/model/Features.java?rev=1513952&r1=1513951&r2=1513952&view=diff
==============================================================================
--- bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/model/Features.java (original)
+++ bval/branches/bval-11/bval-core/src/main/java/org/apache/bval/model/Features.java Wed Aug 14 16:33:15 2013
@@ -34,6 +34,8 @@ public interface Features {
 
         //        String DISPLAY_NAME = "displayName";
         String UNIQUE_KEY = "uniqueKey";
+
+        String EXECUTABLES = "executables";
     }
 
     /** Features of {@link MetaProperty} */

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=1513952&r1=1513951&r2=1513952&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 16:33:15 2013
@@ -79,21 +79,26 @@ public class BeanDescriptorImpl extends 
      * The {@link ApacheFactoryContext} (not) used by this
      * {@link BeanDescriptorImpl}
      */
-    protected final ApacheFactoryContext factoryContext;
-    private final AnnotationProcessor annotationProcessor;
     private Set<ConstructorDescriptor> constrainedConstructors = new CopyOnWriteArraySet<ConstructorDescriptor>();
-    private Map<String, MethodDescriptor> methodConstraints = new HashMap<String, MethodDescriptor>();
     private Set<MethodDescriptor> containedMethods = new CopyOnWriteArraySet<MethodDescriptor>();
-    private Map<String, ConstructorDescriptor> contructorConstraints = new HashMap<String, ConstructorDescriptor>();
+    private final ExecutableMeta meta;
     private Boolean isBeanConstrained = null;
     private Boolean hasAnyContraints = null;
 
     protected BeanDescriptorImpl(ApacheFactoryContext factoryContext, MetaBean metaBean) {
         super(metaBean, metaBean.getBeanClass(), metaBean.getValidations());
-        this.factoryContext = factoryContext;
-        this.annotationProcessor = new AnnotationProcessor(factoryContext);
 
-        buildExecutableDescriptors();
+        ExecutableMeta executables = metaBean.getFeature(Jsr303Features.Bean.EXECUTABLES);
+        if (executables == null) { // caching the result of it is important to avoid to compute it for each Validator
+            executables = new ExecutableMeta(factoryContext, metaBean, getConstraintDescriptors());
+            metaBean.putFeature(Jsr303Features.Bean.EXECUTABLES, executables);
+        }
+
+        meta = executables;
+        isBeanConstrained = meta.isBeanConstrained;
+        hasAnyContraints = meta.hasAnyContraints;
+        setConstrained(containedMethods, meta.methodConstraints.values());
+        setConstrained(constrainedConstructors, meta.contructorConstraints.values());
     }
 
     private static void addGroupConvertion(final MetaProperty prop, final PropertyDescriptorImpl edesc) {
@@ -180,42 +185,13 @@ public class BeanDescriptorImpl extends 
      * @return true if the bean involves validation
      */
     public boolean isBeanConstrained() {
-        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 isBeanConstrained;
     }
 
     private boolean hasAnyConstraints() {
         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 hasAnyContraints;
@@ -273,7 +249,7 @@ public class BeanDescriptorImpl extends 
         if (methodName == null) {
             throw new IllegalArgumentException("Method name can't be null");
         }
-        final MethodDescriptor methodDescriptor = methodConstraints.get(methodName + Arrays.toString(parameterTypes));
+        final MethodDescriptor methodDescriptor = meta.methodConstraints.get(methodName + Arrays.toString(parameterTypes));
         if (methodDescriptor != null && (methodDescriptor.hasConstrainedParameters() || methodDescriptor.hasConstrainedReturnValue())) {
             return methodDescriptor;
         }
@@ -313,7 +289,7 @@ public class BeanDescriptorImpl extends 
     }
 
     public ConstructorDescriptor getConstraintsForConstructor(final Class<?>... parameterTypes) {
-        final ConstructorDescriptor descriptor = contructorConstraints.get(Arrays.toString(parameterTypes));
+        final ConstructorDescriptor descriptor = meta.contructorConstraints.get(Arrays.toString(parameterTypes));
         if (descriptor != null && (descriptor.hasConstrainedParameters() || descriptor.hasConstrainedReturnValue())) {
             return descriptor;
         }
@@ -332,22 +308,6 @@ public class BeanDescriptorImpl extends 
         return "BeanDescriptorImpl{" + "returnType=" + elementClass + '}';
     }
 
-    public void buildExecutableDescriptors() {
-        try {
-            buildMethodConstraints();
-            setConstrained(containedMethods, methodConstraints.values());
-
-            buildConstructorConstraints();
-            setConstrained(constrainedConstructors, contructorConstraints.values());
-        } catch (final Exception ex) {
-            if (RuntimeException.class.isInstance(ex)) {
-                throw RuntimeException.class.cast(ex);
-            }
-
-            throw new IllegalArgumentException(ex.getMessage(), ex);
-        }
-    }
-
     private <A extends ExecutableDescriptor> void setConstrained(final Set<A> dest, final Collection<A> src) {
         for (final A d : src) {
             if (d.hasConstrainedParameters() || d.hasConstrainedReturnValue()) {
@@ -356,476 +316,536 @@ 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(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());
-
-            final AnnotationIgnores annotationIgnores = factoryContext.getFactory().getAnnotationIgnores();
+    private static class ExecutableMeta {
+        private final ApacheFactoryContext factoryContext;
+        private final AnnotationProcessor annotationProcessor;
+        private final MetaBean metaBean;
+        private final Map<String, MethodDescriptor> methodConstraints = new HashMap<String, MethodDescriptor>();
+        private final Map<String, ConstructorDescriptor> contructorConstraints = new HashMap<String, ConstructorDescriptor>();
+        private Boolean isBeanConstrained = null;
+        private Boolean hasAnyContraints = null;
+
+        private ExecutableMeta(final ApacheFactoryContext factoryContext, final MetaBean metaBean1, final Collection<ConstraintDescriptor<?>> constraintDescriptors) {
+            this.metaBean = metaBean1;
+            this.factoryContext = factoryContext;
+            this.annotationProcessor = new AnnotationProcessor(factoryContext);
+
+            buildExecutableDescriptors();
+
+            // cache hasAnyContraints
+            if (!constraintDescriptors.isEmpty()) {
+                hasAnyContraints = true;
+            } else {
+                hasAnyContraints = false;
+                for (final MetaProperty mprop : metaBean.getProperties()) {
+                    if (getConstraintDescriptors(mprop.getValidations()).size() > 0) {
+                        hasAnyContraints = true;
+                        break;
+                    }
+                }
+            }
 
-            {
-                final Annotation[][] paramsAnnos = cons.getParameterAnnotations();
+            // cache isBeanConstrained
+            if (hasAnyContraints) {
+                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;
+                    }
+                }
+            }
+        }
 
-                int idx = 0;
-                if (isInnerClass) { // paramsAnnos.length = parameterTypes.length - 1 in this case
-                    final ParameterDescriptorImpl paramDesc = new ParameterDescriptorImpl(getMetaBean(), EMPTY_VALIDATION, names.get(idx));
-                    consDesc.getParameterDescriptors().add(paramDesc);
-                    idx++;
+        private void buildConstructorConstraints() throws InvocationTargetException, IllegalAccessException {
+            for (final Constructor<?> cons : Reflection.INSTANCE.getDeclaredConstructors(metaBean.getBeanClass())) {
+                final ConstructorDescriptorImpl consDesc = new ConstructorDescriptorImpl(metaBean, new Validation[0]);
+                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());
+
+                final AnnotationIgnores annotationIgnores = factoryContext.getFactory().getAnnotationIgnores();
+
+                {
+                    final Annotation[][] paramsAnnos = cons.getParameterAnnotations();
+
+                    int idx = 0;
+                    if (isInnerClass) { // paramsAnnos.length = parameterTypes.length - 1 in this case
+                        final ParameterDescriptorImpl paramDesc = new ParameterDescriptorImpl(metaBean, EMPTY_VALIDATION, names.get(idx));
+                        consDesc.getParameterDescriptors().add(paramDesc);
+                        idx++;
+                    }
+
+                    for (final Annotation[] paramAnnos : paramsAnnos) {
+                        if (annotationIgnores.isIgnoreAnnotationOnParameter(cons, idx)) {
+                            consDesc.getParameterDescriptors().add(new ParameterDescriptorImpl(metaBean, EMPTY_VALIDATION, names.get(idx)));
+                        } else if (cons.getParameterTypes().length > idx) {
+                            ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
+                            consDesc.addValidations(processAnnotations(consDesc, paramAnnos, access, idx, names.get(idx)).getValidations());
+                        } // else anonymous class so that's fine
+                        idx++;
+                    }
+
+                    if (!annotationIgnores.isIgnoreAnnotations(cons)) {
+                        for (final Annotation anno : cons.getAnnotations()) {
+                            if (!Valid.class.isInstance(anno)) {
+                                processAnnotations(null, consDesc, cons.getDeclaringClass(), anno);
+                            } else {
+                                consDesc.setCascaded(true);
+                            }
+                        }
+                    }
                 }
 
-                for (final Annotation[] paramAnnos : paramsAnnos) {
-                    if (annotationIgnores.isIgnoreAnnotationOnParameter(cons, idx)) {
-                        consDesc.getParameterDescriptors().add(new ParameterDescriptorImpl(metaBean, EMPTY_VALIDATION, names.get(idx)));
-                    } else if (cons.getParameterTypes().length > idx) {
-                        ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
-                        consDesc.addValidations(processAnnotations(consDesc, paramAnnos, access, idx, names.get(idx)).getValidations());
-                    } // else anonymous class so that's fine
-                    idx++;
+                if (annotationIgnores.isIgnoreAnnotationOnCrossParameter(cons) && consDesc.getCrossParameterDescriptor() != null) {
+                    consDesc.setCrossParameterDescriptor(null);
+                }
+                if (annotationIgnores.isIgnoreAnnotationOnReturn(cons) && consDesc.getReturnValueDescriptor() != null) {
+                    consDesc.setReturnValueDescriptor(null);
                 }
 
-                if (!annotationIgnores.isIgnoreAnnotations(cons)) {
-                    for (final Annotation anno : cons.getAnnotations()) {
+                final MetaConstructor metaConstructor = metaBean.getConstructor(cons);
+                if (metaConstructor != null) {
+                    for (final Annotation anno : metaConstructor.getAnnotations()) {
                         if (!Valid.class.isInstance(anno)) {
                             processAnnotations(null, consDesc, cons.getDeclaringClass(), anno);
                         } else {
                             consDesc.setCascaded(true);
                         }
                     }
-                }
-            }
-
-            if (annotationIgnores.isIgnoreAnnotationOnCrossParameter(cons) && consDesc.getCrossParameterDescriptor() != null) {
-                consDesc.setCrossParameterDescriptor(null);
-            }
-            if (annotationIgnores.isIgnoreAnnotationOnReturn(cons) && consDesc.getReturnValueDescriptor() != null) {
-                consDesc.setReturnValueDescriptor(null);
-            }
 
-            final MetaConstructor metaConstructor = metaBean.getConstructor(cons);
-            if (metaConstructor != null) {
-                for (final Annotation anno : metaConstructor.getAnnotations()) {
-                    if (!Valid.class.isInstance(anno)) {
-                        processAnnotations(null, consDesc, cons.getDeclaringClass(), anno);
-                    } else {
-                        consDesc.setCascaded(true);
+                    // parameter validations
+                    final Collection<MetaParameter> paramsAnnos = metaConstructor.getParameters();
+                    for (final MetaParameter paramAnnos : paramsAnnos) {
+                        final int idx = paramAnnos.getIndex();
+                        final ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
+                        processAnnotations(consDesc, paramAnnos.getAnnotations(), access, idx, names.get(idx));
                     }
                 }
 
-                // parameter validations
-                final Collection<MetaParameter> paramsAnnos = metaConstructor.getParameters();
-                for (final MetaParameter paramAnnos : paramsAnnos) {
-                    final int idx = paramAnnos.getIndex();
-                    final ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
-                    processAnnotations(consDesc, paramAnnos.getAnnotations(), access, idx, names.get(idx));
+                if (!consDesc.getGroupConversions().isEmpty() && !consDesc.isCascaded()) {
+                    throw new ConstraintDeclarationException("@Valid is needed to define a group conversion");
                 }
-            }
 
-            if (!consDesc.getGroupConversions().isEmpty() && !consDesc.isCascaded()) {
-                throw new ConstraintDeclarationException("@Valid is needed to define a group conversion");
+                ensureNotNullDescriptors(cons.getDeclaringClass(), consDesc);
             }
-
-            ensureNotNullDescriptors(cons.getDeclaringClass(), consDesc);
         }
-    }
 
-    private void ensureNotNullDescriptors(final Class<?> returnType, final InvocableElementDescriptor consDesc) {
-        // can't be null
-        if (consDesc.getCrossParameterDescriptor() == null) {
-            consDesc.setCrossParameterDescriptor(new CrossParameterDescriptorImpl(getMetaBean(), NO_CONSTRAINTS));
-        }
-        if (consDesc.getReturnValueDescriptor() == null) {
-            consDesc.setReturnValueDescriptor(new ReturnValueDescriptorImpl(getMetaBean(), returnType, NO_CONSTRAINTS, consDesc.isCascaded()));
-        }
-        // enforce it since ReturnValueDescriptor can be created before cascaded is set to true
-        final ReturnValueDescriptorImpl returnValueDescriptor = ReturnValueDescriptorImpl.class.cast(consDesc.getReturnValueDescriptor());
-        returnValueDescriptor.setCascaded(consDesc.isCascaded());
-        if (returnValueDescriptor.getGroupConversions().isEmpty()) {
-            // loop to not forget to map calling addGroupConversion()
-            for (final GroupConversionDescriptor c : consDesc.getGroupConversions()) {
-                returnValueDescriptor.addGroupConversion(c);
+        private void ensureNotNullDescriptors(final Class<?> returnType, final InvocableElementDescriptor consDesc) {
+            // can't be null
+            if (consDesc.getCrossParameterDescriptor() == null) {
+                consDesc.setCrossParameterDescriptor(new CrossParameterDescriptorImpl(metaBean, NO_CONSTRAINTS));
+            }
+            if (consDesc.getReturnValueDescriptor() == null) {
+                consDesc.setReturnValueDescriptor(new ReturnValueDescriptorImpl(metaBean, returnType, NO_CONSTRAINTS, consDesc.isCascaded()));
+            }
+            // enforce it since ReturnValueDescriptor can be created before cascaded is set to true
+            final ReturnValueDescriptorImpl returnValueDescriptor = ReturnValueDescriptorImpl.class.cast(consDesc.getReturnValueDescriptor());
+            returnValueDescriptor.setCascaded(consDesc.isCascaded());
+            if (returnValueDescriptor.getGroupConversions().isEmpty()) {
+                // loop to not forget to map calling addGroupConversion()
+                for (final GroupConversionDescriptor c : consDesc.getGroupConversions()) {
+                    returnValueDescriptor.addGroupConversion(c);
+                }
             }
+
         }
 
-    }
+        private void processAnnotations(final Method mtd, final InvocableElementDescriptor consDesc, final Class<?> clazz, final Annotation anno) throws InvocationTargetException, IllegalAccessException {
+            if (mtd == null || !factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotationOnReturn(mtd)) {
+                final ReturnAccess returnAccess = new ReturnAccess(clazz);
+                final AppendValidationToList validations = new AppendValidationToList();
+                processAnnotation(anno, consDesc, returnAccess, validations);
+                final List<ConstraintValidation<?>> list = removeFromListValidationAppliesTo(validations.getValidations(), ConstraintTarget.PARAMETERS);
+                consDesc.addValidations(list);
 
-    private void processAnnotations(final Method mtd, final InvocableElementDescriptor consDesc, final Class<?> clazz, final Annotation anno) throws InvocationTargetException, IllegalAccessException {
-        if (mtd == null || !factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotationOnReturn(mtd)) {
-            final ReturnAccess returnAccess = new ReturnAccess(clazz);
-            final AppendValidationToList validations = new AppendValidationToList();
-            processAnnotation(anno, consDesc, returnAccess, validations);
-            final List<ConstraintValidation<?>> list = removeFromListValidationAppliesTo(validations.getValidations(), ConstraintTarget.PARAMETERS);
-            consDesc.addValidations(list);
-
-            ReturnValueDescriptorImpl returnValueDescriptor = ReturnValueDescriptorImpl.class.cast(consDesc.getReturnValueDescriptor());
-            if (consDesc.getReturnValueDescriptor() != null) {
-                returnValueDescriptor.getMutableConstraintDescriptors().addAll(list);
-            } else {
-                returnValueDescriptor = new ReturnValueDescriptorImpl(getMetaBean(), clazz, list, consDesc.isCascaded());
-                consDesc.setReturnValueDescriptor(returnValueDescriptor);
+                ReturnValueDescriptorImpl returnValueDescriptor = ReturnValueDescriptorImpl.class.cast(consDesc.getReturnValueDescriptor());
+                if (consDesc.getReturnValueDescriptor() != null) {
+                    returnValueDescriptor.getMutableConstraintDescriptors().addAll(list);
+                } else {
+                    returnValueDescriptor = new ReturnValueDescriptorImpl(metaBean, clazz, list, consDesc.isCascaded());
+                    consDesc.setReturnValueDescriptor(returnValueDescriptor);
+                }
             }
-        }
 
-        if (mtd == null || !factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotationOnCrossParameter(mtd)) {
-            final ParametersAccess parametersAccess = new ParametersAccess();
-            final AppendValidationToList validations = new AppendValidationToList();
-            processAnnotation(anno, consDesc, parametersAccess, validations);
-            final List<ConstraintValidation<?>> list = removeFromListValidationAppliesTo(validations.getValidations(), ConstraintTarget.RETURN_VALUE);
-            consDesc.addValidations(list);
-            if (consDesc.getCrossParameterDescriptor() != null) {
-                CrossParameterDescriptorImpl.class.cast(consDesc.getCrossParameterDescriptor()).getMutableConstraintDescriptors().addAll(list);
-            } else {
-                consDesc.setCrossParameterDescriptor(new CrossParameterDescriptorImpl(getMetaBean(), list));
+            if (mtd == null || !factoryContext.getFactory().getAnnotationIgnores().isIgnoreAnnotationOnCrossParameter(mtd)) {
+                final ParametersAccess parametersAccess = new ParametersAccess();
+                final AppendValidationToList validations = new AppendValidationToList();
+                processAnnotation(anno, consDesc, parametersAccess, validations);
+                final List<ConstraintValidation<?>> list = removeFromListValidationAppliesTo(validations.getValidations(), ConstraintTarget.RETURN_VALUE);
+                consDesc.addValidations(list);
+                if (consDesc.getCrossParameterDescriptor() != null) {
+                    CrossParameterDescriptorImpl.class.cast(consDesc.getCrossParameterDescriptor()).getMutableConstraintDescriptors().addAll(list);
+                } else {
+                    consDesc.setCrossParameterDescriptor(new CrossParameterDescriptorImpl(metaBean, list));
+                }
             }
         }
-    }
 
-    private static List<ConstraintValidation<?>> removeFromListValidationAppliesTo(final List<ConstraintValidation<?>> validations, final ConstraintTarget constraint) {
-        final Iterator<ConstraintValidation<?>> i = validations.iterator();
-        while (i.hasNext()) {
-            if (constraint.equals(i.next().getValidationAppliesTo())) {
-                i.remove();
+        private static List<ConstraintValidation<?>> removeFromListValidationAppliesTo(final List<ConstraintValidation<?>> validations, final ConstraintTarget constraint) {
+            final Iterator<ConstraintValidation<?>> i = validations.iterator();
+            while (i.hasNext()) {
+                if (constraint.equals(i.next().getValidationAppliesTo())) {
+                    i.remove();
+                }
             }
+            return validations;
         }
-        return validations;
-    }
 
-    private void buildMethodConstraints() throws InvocationTargetException, IllegalAccessException {
+        private void buildMethodConstraints() throws InvocationTargetException, IllegalAccessException {
 
-        final Class<?> current = getMetaBean().getBeanClass();
-        final List<Class<?>> classHierarchy = ClassHelper.fillFullClassHierarchyAsList(new ArrayList<Class<?>>(), current);
-        classHierarchy.remove(current);
+            final Class<?> current = metaBean.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;
-            }
+            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 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 String key = method.getName() + Arrays.toString(method.getParameterTypes());
+                MethodDescriptorImpl methodDesc = MethodDescriptorImpl.class.cast(methodConstraints.get(key));
+                if (methodDesc == null) {
+                    methodDesc = new MethodDescriptorImpl(metaBean, 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 (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");
+                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");
+                        }
+                    } 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 {
                             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");
-                            }
+
+                    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);
                         }
-                    } else {
-                        ensureMethodDoesntDefineParameterConstraint(methodDesc);
                     }
-                }
+                    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");
+                    }
 
-                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);
+                    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 (itfWithThisMethod.size() > 1) {
-                    for (final Method m : itfWithThisMethod) {
-                        ensureNoConvertGroup(m, "ConvertGroup can't be used in parallel interfaces");
+                    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");
                     }
-                } else if (itfWithThisMethod.size() == 1) {
-                    ensureNoConvertGroup(itfWithThisMethod.iterator().next(), "ConvertGroup can't be used in interface AND parent class");
                 }
 
-                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 (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);
                     }
                 }
-                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 (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);
+                if (!methodDesc.getGroupConversions().isEmpty() && !methodDesc.isCascaded()) {
+                    throw new ConstraintDeclarationException("@Valid is needed to define a group conversion");
                 }
             }
 
-            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.meta.methodConstraints.keySet()) {
+                    if (!methodConstraints.containsKey(s)) { // method from the parent only
+                        methodConstraints.put(s, desc.meta.methodConstraints.get(s));
+                    }
+                }
             }
         }
 
-        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) {
+            for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
+                if (!pd.getConstraintDescriptors().isEmpty()) {
+                    throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
+                }
+                if (pd.isCascaded()) { // @Valid
+                    throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
                 }
             }
         }
-    }
 
-    private void ensureMethodDoesntDefineParameterConstraint(MethodDescriptorImpl methodDesc) {
-        for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
-            if (!pd.getConstraintDescriptors().isEmpty()) {
-                throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
+        private void ensureNoReturnValueAddedInChild(final ReturnValueDescriptor returnValueDescriptor, final MethodDescriptor parentMtdDesc, final String msg) {
+            if (parentMtdDesc == null) {
+                return;
             }
-            if (pd.isCascaded()) { // @Valid
-                throw new ConstraintDeclarationException("child shouldn't get more constraint than parent");
-            }
-        }
-    }
-
-    private void ensureNoReturnValueAddedInChild(final ReturnValueDescriptor returnValueDescriptor, final MethodDescriptor parentMtdDesc, final String msg) {
-        if (parentMtdDesc == null) {
-            return;
-        }
-
-        final ReturnValueDescriptor parentReturnDesc = parentMtdDesc.getReturnValueDescriptor();
-        if (parentReturnDesc.isCascaded() && !returnValueDescriptor.isCascaded() || parentReturnDesc.getConstraintDescriptors().size() > returnValueDescriptor.getConstraintDescriptors().size()) {
-            throw new ConstraintDeclarationException(msg);
-        }
-    }
 
-    private static void ensureNoParameterConstraint(final InvocableElementDescriptor constraintsForMethod, final String msg) {
-        for (final ParameterDescriptor parameterDescriptor : constraintsForMethod.getParameterDescriptors()) {
-            if (!parameterDescriptor.getConstraintDescriptors().isEmpty() || parameterDescriptor.isCascaded()) {
+            final ReturnValueDescriptor parentReturnDesc = parentMtdDesc.getReturnValueDescriptor();
+            if (parentReturnDesc.isCascaded() && !returnValueDescriptor.isCascaded() || parentReturnDesc.getConstraintDescriptors().size() > returnValueDescriptor.getConstraintDescriptors().size()) {
                 throw new ConstraintDeclarationException(msg);
             }
         }
-    }
 
-    private static void ensureNoConvertGroup(final Method method, final String msg) {
-        for (final Annotation[] annotations : method.getParameterAnnotations()) {
-            for (final Annotation a : annotations) {
-                if (ConvertGroup.class.isInstance(a)) {
+        private static void ensureNoParameterConstraint(final InvocableElementDescriptor constraintsForMethod, final String msg) {
+            for (final ParameterDescriptor parameterDescriptor : constraintsForMethod.getParameterDescriptors()) {
+                if (!parameterDescriptor.getConstraintDescriptors().isEmpty() || parameterDescriptor.isCascaded()) {
                     throw new ConstraintDeclarationException(msg);
                 }
             }
         }
-        if (method.getAnnotation(ConvertGroup.class) != null) {
-            throw new ConstraintDeclarationException(msg);
+
+        private static void ensureNoConvertGroup(final Method method, final String msg) {
+            for (final Annotation[] annotations : method.getParameterAnnotations()) {
+                for (final Annotation a : annotations) {
+                    if (ConvertGroup.class.isInstance(a)) {
+                        throw new ConstraintDeclarationException(msg);
+                    }
+                }
+            }
+            if (method.getAnnotation(ConvertGroup.class) != null) {
+                throw new ConstraintDeclarationException(msg);
+            }
         }
-    }
 
-    private void processMethod(final Method method, final MethodDescriptorImpl methodDesc) throws InvocationTargetException, IllegalAccessException {
-        final AnnotationIgnores annotationIgnores = factoryContext.getFactory().getAnnotationIgnores();
+        private void processMethod(final Method method, final MethodDescriptorImpl methodDesc) throws InvocationTargetException, IllegalAccessException {
+            final AnnotationIgnores annotationIgnores = factoryContext.getFactory().getAnnotationIgnores();
 
-        { // reflection
-            if (!annotationIgnores.isIgnoreAnnotations(method)) {
-                // return value validations and/or cross-parameter validation
-                for (Annotation anno : method.getAnnotations()) {
-                    if (anno instanceof Valid || anno instanceof Validate) {
-                        methodDesc.setCascaded(true);
+            { // reflection
+                if (!annotationIgnores.isIgnoreAnnotations(method)) {
+                    // return value validations and/or cross-parameter validation
+                    for (Annotation anno : method.getAnnotations()) {
+                        if (anno instanceof Valid || anno instanceof Validate) {
+                            methodDesc.setCascaded(true);
+                        } else {
+                            processAnnotations(method, methodDesc, method.getReturnType(), anno);
+                        }
+                    }
+                }
+
+                // parameter validations
+                final Annotation[][] paramsAnnos = method.getParameterAnnotations();
+                int idx = 0;
+                final List<String> names = factoryContext.getParameterNameProvider().getParameterNames(method);
+                for (final Annotation[] paramAnnos : paramsAnnos) {
+                    if (!annotationIgnores.isIgnoreAnnotationOnParameter(method, idx)) {
+                        final ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
+                        processAnnotations(methodDesc, paramAnnos, access, idx, names.get(idx));
                     } else {
-                        processAnnotations(method, methodDesc, method.getReturnType(), anno);
+                        final ParameterDescriptorImpl parameterDescriptor = new ParameterDescriptorImpl(metaBean, new Validation[0], names.get(idx));
+                        parameterDescriptor.setIndex(idx);
+                        methodDesc.getParameterDescriptors().add(parameterDescriptor);
                     }
+                    idx++;
                 }
             }
 
-            // parameter validations
-            final Annotation[][] paramsAnnos = method.getParameterAnnotations();
-            int idx = 0;
-            final List<String> names = factoryContext.getParameterNameProvider().getParameterNames(method);
-            for (final Annotation[] paramAnnos : paramsAnnos) {
-                if (!annotationIgnores.isIgnoreAnnotationOnParameter(method, idx)) {
-                    final ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
-                    processAnnotations(methodDesc, paramAnnos, access, idx, names.get(idx));
-                } else {
-                    final ParameterDescriptorImpl parameterDescriptor = new ParameterDescriptorImpl(metaBean, new Validation[0], names.get(idx));
-                    parameterDescriptor.setIndex(idx);
-                    methodDesc.getParameterDescriptors().add(parameterDescriptor);
-                }
-                idx++;
+            if (annotationIgnores.isIgnoreAnnotationOnCrossParameter(method) && methodDesc.getCrossParameterDescriptor() != null) {
+                methodDesc.setCrossParameterDescriptor(null);
+            }
+            if (annotationIgnores.isIgnoreAnnotationOnReturn(method) && methodDesc.getReturnValueDescriptor() != null) {
+                methodDesc.setReturnValueDescriptor(null);
             }
-        }
 
-        if (annotationIgnores.isIgnoreAnnotationOnCrossParameter(method) && methodDesc.getCrossParameterDescriptor() != null) {
-            methodDesc.setCrossParameterDescriptor(null);
-        }
-        if (annotationIgnores.isIgnoreAnnotationOnReturn(method) && methodDesc.getReturnValueDescriptor() != null) {
-            methodDesc.setReturnValueDescriptor(null);
-        }
+            final MetaMethod metaMethod = metaBean.getMethod(method);
+            if (metaMethod != null) {
+                for (final Annotation anno : metaMethod.getAnnotations()) {
+                    if (anno instanceof Valid) {
+                        methodDesc.setCascaded(true);
+                    } else {
+                        // set first param as null to force it to be read
+                        processAnnotations(null, methodDesc, method.getReturnType(), anno);
+                    }
+                }
 
-        final MetaMethod metaMethod = metaBean.getMethod(method);
-        if (metaMethod != null) {
-            for (final Annotation anno : metaMethod.getAnnotations()) {
-                if (anno instanceof Valid) {
-                    methodDesc.setCascaded(true);
-                } else {
-                    // set first param as null to force it to be read
-                    processAnnotations(null, methodDesc, method.getReturnType(), anno);
+                // parameter validations
+                final Collection<MetaParameter> paramsAnnos = metaMethod.getParameters();
+                final List<String> names = factoryContext.getParameterNameProvider().getParameterNames(method);
+                for (final MetaParameter paramAnnos : paramsAnnos) {
+                    final int idx = paramAnnos.getIndex();
+                    final ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
+                    processAnnotations(methodDesc, paramAnnos.getAnnotations(), access, idx, names.get(idx));
                 }
-            }
 
-            // parameter validations
-            final Collection<MetaParameter> paramsAnnos = metaMethod.getParameters();
-            final List<String> names = factoryContext.getParameterNameProvider().getParameterNames(method);
-            for (final MetaParameter paramAnnos : paramsAnnos) {
-                final int idx = paramAnnos.getIndex();
-                final ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
-                processAnnotations(methodDesc, paramAnnos.getAnnotations(), access, idx, names.get(idx));
             }
 
         }
 
-    }
-
-    private AppendValidationToList processAnnotations(InvocableElementDescriptor methodDesc, Annotation[] paramAnnos, AccessStrategy access, int idx, String name)
-        throws InvocationTargetException, IllegalAccessException {
-        final AppendValidationToList validations = new AppendValidationToList();
-        boolean cascaded = false;
+        private AppendValidationToList processAnnotations(InvocableElementDescriptor methodDesc, Annotation[] paramAnnos, AccessStrategy access, int idx, String name)
+            throws InvocationTargetException, IllegalAccessException {
+            final AppendValidationToList validations = new AppendValidationToList();
+            boolean cascaded = false;
 
-        Group[] from = null;
-        Group[] to = null;
+            Group[] from = null;
+            Group[] to = null;
 
-        for (final Annotation anno : paramAnnos) {
-            if (anno instanceof Valid || anno instanceof Validate) {
-                cascaded = true;
-            } else if (ConvertGroup.class.isInstance(anno)) {
-                final ConvertGroup cg = ConvertGroup.class.cast(anno);
-                from = new Group[]{new Group(cg.from())};
-                to = new Group[]{new Group(cg.to())};
-            } else if (ConvertGroup.List.class.isInstance(anno)) {
-                final ConvertGroup.List cgl = ConvertGroup.List.class.cast(anno);
-                final ConvertGroup[] groups = cgl.value();
-                from = new Group[groups.length];
-                to = new Group[groups.length];
-                for (int i = 0; i < to.length; i++) {
-                    from[i] = new Group(groups[i].from());
-                    to[i] = new Group(groups[i].to());
+            for (final Annotation anno : paramAnnos) {
+                if (anno instanceof Valid || anno instanceof Validate) {
+                    cascaded = true;
+                } else if (ConvertGroup.class.isInstance(anno)) {
+                    final ConvertGroup cg = ConvertGroup.class.cast(anno);
+                    from = new Group[]{new Group(cg.from())};
+                    to = new Group[]{new Group(cg.to())};
+                } else if (ConvertGroup.List.class.isInstance(anno)) {
+                    final ConvertGroup.List cgl = ConvertGroup.List.class.cast(anno);
+                    final ConvertGroup[] groups = cgl.value();
+                    from = new Group[groups.length];
+                    to = new Group[groups.length];
+                    for (int i = 0; i < to.length; i++) {
+                        from[i] = new Group(groups[i].from());
+                        to[i] = new Group(groups[i].to());
+                    }
+                } else {
+                    processAnnotation(anno, methodDesc, access, validations);
                 }
-            } else {
-                processAnnotation(anno, methodDesc, access, validations);
             }
-        }
 
-        ParameterDescriptorImpl paramDesc = null;
-        for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
-            if (pd.getIndex() == idx) {
-                paramDesc = ParameterDescriptorImpl.class.cast(pd);
+            ParameterDescriptorImpl paramDesc = null;
+            for (final ParameterDescriptor pd : methodDesc.getParameterDescriptors()) {
+                if (pd.getIndex() == idx) {
+                    paramDesc = ParameterDescriptorImpl.class.cast(pd);
+                }
             }
-        }
 
-        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);
-            paramDesc.setIndex(idx);
-            final List<ParameterDescriptor> parameterDescriptors = methodDesc.getParameterDescriptors();
-            if (!parameterDescriptors.contains(paramDesc)) {
-                parameterDescriptors.add(paramDesc);
-            }
-            paramDesc.setCascaded(cascaded);
-        } else {
-            final List<ConstraintValidation<?>> newValidations = validations.getValidations();
-            for (final ConstraintValidation<?> validation : newValidations) { // don't add it if exactly the same is already here
-                boolean alreadyHere = false;
-                for (final ConstraintDescriptor<?> existing : paramDesc.getMutableConstraintDescriptors()) {
-                    if (existing.getAnnotation().annotationType().equals(validation.getAnnotation().annotationType())) { // TODO: make it a bit finer
-                        alreadyHere = true;
-                        break;
+            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);
+                paramDesc.setIndex(idx);
+                final List<ParameterDescriptor> parameterDescriptors = methodDesc.getParameterDescriptors();
+                if (!parameterDescriptors.contains(paramDesc)) {
+                    parameterDescriptors.add(paramDesc);
+                }
+                paramDesc.setCascaded(cascaded);
+            } else {
+                final List<ConstraintValidation<?>> newValidations = validations.getValidations();
+                for (final ConstraintValidation<?> validation : newValidations) { // don't add it if exactly the same is already here
+                    boolean alreadyHere = false;
+                    for (final ConstraintDescriptor<?> existing : paramDesc.getMutableConstraintDescriptors()) {
+                        if (existing.getAnnotation().annotationType().equals(validation.getAnnotation().annotationType())) { // TODO: make it a bit finer
+                            alreadyHere = true;
+                            break;
+                        }
+                    }
+                    if (!alreadyHere) {
+                        paramDesc.getMutableConstraintDescriptors().add(validation);
                     }
                 }
-                if (!alreadyHere) {
-                    paramDesc.getMutableConstraintDescriptors().add(validation);
+
+                if (cascaded) {
+                    paramDesc.setCascaded(true);
+                } // else keep previous config
+            }
+            if (paramDesc.isCascaded() && from != null) {
+                for (int i = 0; i < from.length; i++) {
+                    paramDesc.addGroupConversion(new GroupConversionDescriptorImpl(from[i], to[i]));
                 }
+            } else if (from != null) {
+                throw new ConstraintDeclarationException("Group conversion is only relevant for @Valid cases");
             }
 
-            if (cascaded) {
-                paramDesc.setCascaded(true);
-            } // else keep previous config
-        }
-        if (paramDesc.isCascaded() && from != null) {
-            for (int i = 0; i < from.length; i++) {
-                paramDesc.addGroupConversion(new GroupConversionDescriptorImpl(from[i], to[i]));
-            }
-        } else if (from != null) {
-            throw new ConstraintDeclarationException("Group conversion is only relevant for @Valid cases");
+            return validations;
         }
 
-        return validations;
-    }
-
-    private <A extends Annotation> void processAnnotation(A annotation, InvocableElementDescriptor desc,
-                                                          AccessStrategy access, AppendValidation validations) throws InvocationTargetException, IllegalAccessException {
+        private <A extends Annotation> void processAnnotation(final A annotation, final InvocableElementDescriptor desc,
+                                                              final AccessStrategy access, final AppendValidation validations) throws InvocationTargetException, IllegalAccessException {
+            if (annotation.annotationType().getName().startsWith("java.lang.annotation.")) {
+                return;
+            }
 
-        if (annotation instanceof Valid || annotation instanceof Validate) {
-            desc.setCascaded(true);
-        } else if (ConvertGroup.class.isInstance(annotation) && ReturnAccess.class.isInstance(access)) { // access is just tested to ensure to not read it twice with cross parameter
-            final ConvertGroup cg = ConvertGroup.class.cast(annotation);
-            desc.addGroupConversion(new GroupConversionDescriptorImpl(new Group(cg.from()), new Group(cg.to())));
-        } else if (ConvertGroup.List.class.isInstance(annotation) && ReturnAccess.class.isInstance(access)) {
-            final ConvertGroup.List cgl = ConvertGroup.List.class.cast(annotation);
-            for (final ConvertGroup cg : cgl.value()) {
+            if (annotation instanceof Valid || annotation instanceof Validate) {
+                desc.setCascaded(true);
+            } else if (ConvertGroup.class.isInstance(annotation) && ReturnAccess.class.isInstance(access)) { // access is just tested to ensure to not read it twice with cross parameter
+                final ConvertGroup cg = ConvertGroup.class.cast(annotation);
                 desc.addGroupConversion(new GroupConversionDescriptorImpl(new Group(cg.from()), new Group(cg.to())));
-            }
-        } else {
-            Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
-            if (vcAnno != null) {
-                annotationProcessor.processAnnotation(annotation, null, ClassUtils.primitiveToWrapper((Class<?>) access.getJavaType()), access, validations, true);
+            } else if (ConvertGroup.List.class.isInstance(annotation) && ReturnAccess.class.isInstance(access)) {
+                final ConvertGroup.List cgl = ConvertGroup.List.class.cast(annotation);
+                for (final ConvertGroup cg : cgl.value()) {
+                    desc.addGroupConversion(new GroupConversionDescriptorImpl(new Group(cg.from()), new Group(cg.to())));
+                }
             } else {
-                /**
-                 * Multi-valued constraints
-                 */
-                final ConstraintAnnotationAttributes.Worker<? extends Annotation> worker = ConstraintAnnotationAttributes.VALUE.analyze(annotation.annotationType());
-                if (worker.isValid()) {
-                    Annotation[] children = Annotation[].class.cast(worker.read(annotation));
-                    if (children != null) {
-                        for (Annotation child : children) {
-                            processAnnotation(child, desc, access, validations); // recursion
+                Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
+                if (vcAnno != null) {
+                    annotationProcessor.processAnnotation(annotation, null, ClassUtils.primitiveToWrapper((Class<?>) access.getJavaType()), access, validations, true);
+                } else {
+                    /**
+                     * Multi-valued constraints
+                     */
+                    final ConstraintAnnotationAttributes.Worker<? extends Annotation> worker = ConstraintAnnotationAttributes.VALUE.analyze(annotation.annotationType());
+                    if (worker.isValid()) {
+                        Annotation[] children = Annotation[].class.cast(worker.read(annotation));
+                        if (children != null) {
+                            for (Annotation child : children) {
+                                processAnnotation(child, desc, access, validations); // recursion
+                            }
                         }
                     }
                 }
             }
         }
+
+        private void buildExecutableDescriptors() {
+            try {
+                buildMethodConstraints();
+                buildConstructorConstraints();
+            } catch (final Exception ex) {
+                if (RuntimeException.class.isInstance(ex)) {
+                    throw RuntimeException.class.cast(ex);
+                }
+
+                throw new IllegalArgumentException(ex.getMessage(), ex);
+            }
+        }
     }
 }

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultMessageInterpolator.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultMessageInterpolator.java?rev=1513952&r1=1513951&r2=1513952&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultMessageInterpolator.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/DefaultMessageInterpolator.java Wed Aug 14 16:33:15 2013
@@ -72,19 +72,14 @@ public class DefaultMessageInterpolator 
     public DefaultMessageInterpolator(ResourceBundle resourceBundle) {
         defaultLocale = Locale.getDefault();
 
+        // feed the cache with defaults at least
+        findDefaultResourceBundle(defaultLocale);
         if (resourceBundle == null) {
-            ResourceBundle bundle = getFileBasedResourceBundle(defaultLocale);
-            if (bundle != null) {
-                userBundlesMap.put(defaultLocale, bundle);
-            }
-
+            findUserResourceBundle(defaultLocale);
         } else {
             userBundlesMap.put(defaultLocale, resourceBundle);
         }
 
-        defaultBundlesMap.put(defaultLocale,
-                ResourceBundle.getBundle(DEFAULT_VALIDATION_MESSAGES, defaultLocale));
-
         MessageEvaluator ev = null;
         try {
             ev = MessageEvaluator.class.cast(getClass().getClassLoader().loadClass("org.apache.bval.el.ELFacade").newInstance());

Modified: bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ElementDescriptorImpl.java
URL: http://svn.apache.org/viewvc/bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ElementDescriptorImpl.java?rev=1513952&r1=1513951&r2=1513952&view=diff
==============================================================================
--- bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ElementDescriptorImpl.java (original)
+++ bval/branches/bval-11/bval-jsr303/src/main/java/org/apache/bval/jsr303/ElementDescriptorImpl.java Wed Aug 14 16:33:15 2013
@@ -48,7 +48,7 @@ public abstract class ElementDescriptorI
      * @param validations
      * @return {@link ConstraintDescriptor} set
      */
-    protected static Set<ConstraintDescriptor<?>> getConstraintDescriptors(Validation[] validations) {
+    protected static Set<ConstraintDescriptor<?>> getConstraintDescriptors(final Validation[] validations) {
         final Set<ConstraintDescriptor<?>> result = new HashSet<ConstraintDescriptor<?>>(validations.length);
         for (Validation validation : validations) {
             if (validation instanceof ConstraintValidation<?>) {



Mime
View raw message