You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by ro...@apache.org on 2010/05/18 13:51:04 UTC

svn commit: r945599 - in /incubator/bval/trunk: bval-core/src/main/java/org/apache/bval/ bval-jsr303/src/main/java/org/apache/bval/jsr303/ bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/

Author: romanstumm
Date: Tue May 18 11:51:04 2010
New Revision: 945599

URL: http://svn.apache.org/viewvc?rev=945599&view=rev
Log:
caching MetaBean also for MethodValidation (resolved TODO), 
using MethodValidatorMetaBeanFactory also for related beans for MethodValidation (fixed potential bug)

Modified:
    incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/MetaBeanBuilder.java
    incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheFactoryContext.java
    incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java
    incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java
    incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorMetaBeanFactory.java

Modified: incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/MetaBeanBuilder.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/MetaBeanBuilder.java?rev=945599&r1=945598&r2=945599&view=diff
==============================================================================
--- incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/MetaBeanBuilder.java (original)
+++ incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/MetaBeanBuilder.java Tue May 18 11:51:04 2010
@@ -34,39 +34,45 @@ import java.util.Map;
  * Description: internal implementation class to construct metabeans with factories<br/>
  */
 public class MetaBeanBuilder {
-    private static final Log log = LogFactory.getLog(MetaBeanBuilder.class);
+  private static final Log log = LogFactory.getLog(MetaBeanBuilder.class);
 
-    /** here you can install different kinds of factories to create MetaBeans from */
-    private MetaBeanFactory[] factories;
-    private XMLMetaBeanFactory xmlFactory;
-
-    public MetaBeanBuilder() {
-        this(new MetaBeanFactory[]{new IntrospectorMetaBeanFactory(),
-              new XMLMetaBeanFactory()});
-    }
-
-    public MetaBeanBuilder(MetaBeanFactory[] factories) {
-        setFactories(factories);
-    }
-
-    private void setFactories(MetaBeanFactory[] factories) {
-        this.factories = factories;
-        updateXmlFactory();
-    }
-
-    private void updateXmlFactory() {
-        for (MetaBeanFactory each : factories) {
-            if (each instanceof XMLMetaBeanFactory) { // use the first one!
-                xmlFactory = (XMLMetaBeanFactory) each;
-                return;
-            }
-        }
-        xmlFactory = null; // none
-    }
-
-    public XMLMetaBeanFactory getXmlFactory() {
-        return xmlFactory;
-    }
+  /**
+   * here you can install different kinds of factories to create MetaBeans from
+   */
+  private MetaBeanFactory[] factories;
+  private XMLMetaBeanFactory xmlFactory;
+
+  public MetaBeanBuilder() {
+    this(new MetaBeanFactory[]{new IntrospectorMetaBeanFactory(),
+        new XMLMetaBeanFactory()});
+  }
+
+  public MetaBeanBuilder(MetaBeanFactory[] factories) {
+    setFactories(factories);
+  }
+
+  public MetaBeanFactory[] getFactories() {
+    return factories;
+  }
+
+  public void setFactories(MetaBeanFactory[] factories) {
+    this.factories = factories;
+    updateXmlFactory();
+  }
+
+  private void updateXmlFactory() {
+    for (MetaBeanFactory each : factories) {
+      if (each instanceof XMLMetaBeanFactory) { // use the first one!
+        xmlFactory = (XMLMetaBeanFactory) each;
+        return;
+      }
+    }
+    xmlFactory = null; // none
+  }
+
+  public XMLMetaBeanFactory getXmlFactory() {
+    return xmlFactory;
+  }
 /*
     *//** convenience method *//*
     public void addLastFactory(MetaBeanFactory metaBeanFactory) {
@@ -80,7 +86,11 @@ public class MetaBeanBuilder {
         updateXmlFactory();
     }
 
-    *//** convenience method *//*
+    */
+
+  /**
+   * convenience method
+   *//*
     public void addFirstFactory(MetaBeanFactory metaBeanFactory) {
         if (factories == null) factories = new MetaBeanFactory[1];
         else {
@@ -91,146 +101,145 @@ public class MetaBeanBuilder {
         factories[0] = metaBeanFactory;
         updateXmlFactory();
     }*/
+  public void addLoader(XMLMetaBeanLoader loader) {
+    assertXmlFactory();
+    xmlFactory.addLoader(loader);
+  }
+
+  public Map<String, MetaBean> buildAll() throws Exception {
+    final Map<String, MetaBean> all = new HashMap<String, MetaBean>();
+    if (xmlFactory != null) {
+      xmlFactory.visitXMLBeanMeta(null, new XMLMetaBeanFactory.Visitor() {
+        public void visit(XMLMetaBean empty, XMLMetaBeanInfos xmlInfos)
+            throws Exception {
+          if (xmlInfos.getBeans() == null) return; // empty file, ignore
+          XMLMetaBeanFactory.XMLResult carrier =
+              new XMLMetaBeanFactory.XMLResult(null, xmlInfos);
+
+          for (XMLMetaBean xmlMeta : xmlInfos.getBeans()) {
+            MetaBean meta = all.get(xmlMeta.getId());
+            if (meta == null) {
+              meta = createMetaBean(xmlMeta);
+              all.put(xmlMeta.getId(), meta);
+            }
+            carrier.xmlMeta = xmlMeta;
+            xmlFactory.enrichMetaBean(meta, carrier);
+          }
+        }
+
+        public MetaBean getMetaBean() {
+          return null;  // do nothing
+        }
+      });
+    }
+    return all;
+  }
+
+  public Map<String, MetaBean> enrichCopies(Map<String, MetaBean> all,
+                                            XMLMetaBeanInfos... infosArray)
+      throws Exception {
+    assertXmlFactory();
+    final Map<String, MetaBean> copies = new HashMap<String, MetaBean>(all.size());
+    boolean nothing = true;
+    XMLMetaBeanFactory.XMLResult carrier = new XMLMetaBeanFactory.XMLResult();
+    for (XMLMetaBeanInfos xmlMetaBeanInfos : infosArray) {
+      carrier.xmlInfos = xmlMetaBeanInfos;
+      if (xmlMetaBeanInfos == null) continue;
+      try {
+        for (XMLMetaBean xmlMeta : xmlMetaBeanInfos.getBeans()) {
+          nothing = false;
+          MetaBean copy = copies.get(xmlMeta.getId());
+          if (copy == null) { // ist noch nicht kopiert
+            MetaBean meta = all.get(xmlMeta.getId());
+            if (meta == null) { // gibt es nicht
+              copy = createMetaBean(xmlMeta);
+            } else { // gibt es, jetzt kopieren
+              copy = meta.copy();
+            }
+            copies.put(xmlMeta.getId(), copy);
+          }
+          carrier.xmlMeta = xmlMeta;
+          xmlFactory.enrichMetaBean(copy, carrier);
+        }
+      } catch (IOException e) {
+        xmlFactory.handleLoadException(xmlMetaBeanInfos, e);
+      }
+    }
+    if (nothing) return all;
+    for (Map.Entry<String, MetaBean> entry : all.entrySet()) {
+      /*
+      * alle unveraenderten werden AUCH KOPIERT (nur zwar nur, wegen
+      * potentieller CrossReferenzen durch Relationships)
+      */
+      if (!copies.containsKey(entry.getKey())) {
+        if (entry.getValue().hasRelationships()) {
+          copies.put(entry.getKey(), (MetaBean) entry.getValue().copy());
+        } else { // no relationship: do not clone()
+          copies.put(entry.getKey(), entry.getValue());
+        }
+      }
+    }
+    return copies;
+  }
+
+  private void assertXmlFactory() {
+    if (xmlFactory == null) {
+      throw new IllegalStateException("no xmlFactory available");
+    }
+  }
+
+  public MetaBean buildForId(String beanInfoId) throws Exception {
+    final XMLMetaBeanFactory.Visitor v;
+    assertXmlFactory();
+    xmlFactory.visitXMLBeanMeta(beanInfoId, v = new XMLMetaBeanFactory.Visitor() {
+      private MetaBean meta;
 
-    public void addLoader(XMLMetaBeanLoader loader) {
-        assertXmlFactory();
-        xmlFactory.addLoader(loader);
-    }
-
-    public Map<String, MetaBean> buildAll() throws Exception {
-        final Map<String, MetaBean> all = new HashMap<String, MetaBean>();
-        if (xmlFactory != null) {
-            xmlFactory.visitXMLBeanMeta(null, new XMLMetaBeanFactory.Visitor() {
-                public void visit(XMLMetaBean empty, XMLMetaBeanInfos xmlInfos)
-                      throws Exception {
-                    if (xmlInfos.getBeans() == null) return; // empty file, ignore
-                    XMLMetaBeanFactory.XMLResult carrier =
-                          new XMLMetaBeanFactory.XMLResult(null, xmlInfos);
-
-                    for (XMLMetaBean xmlMeta : xmlInfos.getBeans()) {
-                        MetaBean meta = all.get(xmlMeta.getId());
-                        if (meta == null) {
-                            meta = createMetaBean(xmlMeta);
-                            all.put(xmlMeta.getId(), meta);
-                        }
-                        carrier.xmlMeta = xmlMeta;
-                        xmlFactory.enrichMetaBean(meta, carrier);
-                    }
-                }
-
-                public MetaBean getMetaBean() {
-                    return null;  // do nothing
-                }
-            });
-        }
-        return all;
-    }
+      public MetaBean getMetaBean() {
+        return meta;
+      }
 
-    public Map<String, MetaBean> enrichCopies(Map<String, MetaBean> all,
-                                              XMLMetaBeanInfos... infosArray)
+      public void visit(XMLMetaBean xmlMeta, XMLMetaBeanInfos xmlInfos)
           throws Exception {
-        assertXmlFactory();
-        final Map<String, MetaBean> copies = new HashMap<String, MetaBean>(all.size());
-        boolean nothing = true;
-        XMLMetaBeanFactory.XMLResult carrier = new XMLMetaBeanFactory.XMLResult();
-        for (XMLMetaBeanInfos xmlMetaBeanInfos : infosArray) {
-            carrier.xmlInfos = xmlMetaBeanInfos;
-            if (xmlMetaBeanInfos == null) continue;
-            try {
-                for (XMLMetaBean xmlMeta : xmlMetaBeanInfos.getBeans()) {
-                    nothing = false;
-                    MetaBean copy = copies.get(xmlMeta.getId());
-                    if (copy == null) { // ist noch nicht kopiert
-                        MetaBean meta = all.get(xmlMeta.getId());
-                        if (meta == null) { // gibt es nicht
-                            copy = createMetaBean(xmlMeta);
-                        } else { // gibt es, jetzt kopieren
-                            copy = meta.copy();
-                        }
-                        copies.put(xmlMeta.getId(), copy);
-                    }
-                    carrier.xmlMeta = xmlMeta;
-                    xmlFactory.enrichMetaBean(copy, carrier);
-                }
-            } catch (IOException e) {
-                xmlFactory.handleLoadException(xmlMetaBeanInfos, e);
-            }
+        if (meta == null) {
+          meta = createMetaBean(xmlMeta);
         }
-        if (nothing) return all;
-        for (Map.Entry<String, MetaBean> entry : all.entrySet()) {
-            /*
-            * alle unveraenderten werden AUCH KOPIERT (nur zwar nur, wegen
-            * potentieller CrossReferenzen durch Relationships)
-            */
-            if (!copies.containsKey(entry.getKey())) {
-                if (entry.getValue().hasRelationships()) {
-                    copies.put(entry.getKey(), (MetaBean) entry.getValue().copy());
-                } else { // no relationship: do not clone()
-                    copies.put(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-        return copies;
+        xmlFactory.enrichMetaBean(meta,
+            new XMLMetaBeanFactory.XMLResult(xmlMeta, xmlInfos));
+      }
+
+
+    });
+    if (v.getMetaBean() == null) {
+      throw new IllegalArgumentException("MetaBean " + beanInfoId + " not found");
+    }
+    return v.getMetaBean();
+  }
+
+  private MetaBean createMetaBean(XMLMetaBean xmlMeta) throws Exception {
+    return buildForClass(findLocalClass(xmlMeta.getImpl()));
+  }
+
+  protected Class<?> findLocalClass(String className) {
+    if (className != null) {
+      try {
+        return ClassUtils.getClass(className);
+      } catch (ClassNotFoundException e) {
+        log.warn("class not found: " + className, e);
+      }
+    }
+    return null;
+  }
+
+  public MetaBean buildForClass(Class<?> clazz) throws Exception {
+    MetaBean meta = new MetaBean();
+    if (clazz != null) { // local class here?
+      meta.setBeanClass(clazz);
+      meta.setId(clazz.getName()); // default id = full class name!
     }
-
-    private void assertXmlFactory() {
-        if (xmlFactory == null) {
-            throw new IllegalStateException("no xmlFactory available");
-        }
-    }
-
-    public MetaBean buildForId(String beanInfoId) throws Exception {
-        final XMLMetaBeanFactory.Visitor v;
-        assertXmlFactory();
-        xmlFactory.visitXMLBeanMeta(beanInfoId, v = new XMLMetaBeanFactory.Visitor() {
-            private MetaBean meta;
-
-            public MetaBean getMetaBean() {
-                return meta;
-            }
-
-            public void visit(XMLMetaBean xmlMeta, XMLMetaBeanInfos xmlInfos)
-                  throws Exception {
-                if (meta == null) {
-                    meta = createMetaBean(xmlMeta);
-                }
-                xmlFactory.enrichMetaBean(meta,
-                      new XMLMetaBeanFactory.XMLResult(xmlMeta, xmlInfos));
-            }
-
-
-        });
-        if (v.getMetaBean() == null) {
-            throw new IllegalArgumentException("MetaBean " + beanInfoId + " not found");
-        }
-        return v.getMetaBean();
-    }
-
-    private MetaBean createMetaBean(XMLMetaBean xmlMeta) throws Exception {
-        return buildForClass(findLocalClass(xmlMeta.getImpl()));
-    }
-
-    protected Class<?> findLocalClass(String className) {
-        if (className != null) {
-            try {
-                return ClassUtils.getClass(className);
-            } catch (ClassNotFoundException e) {
-                log.warn("class not found: " + className, e);
-            }
-        }
-        return null;
-    }
-
-    public MetaBean buildForClass(Class<?> clazz) throws Exception {
-        MetaBean meta = new MetaBean();
-        if (clazz != null) { // local class here?
-            meta.setBeanClass(clazz);
-            meta.setId(clazz.getName()); // default id = full class name!
-        }
-        for (MetaBeanFactory factory : factories) {
-            factory.buildMetaBean(meta);
-        }
-        return meta;
+    for (MetaBeanFactory factory : factories) {
+      factory.buildMetaBean(meta);
     }
+    return meta;
+  }
 
 }
\ No newline at end of file

Modified: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheFactoryContext.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheFactoryContext.java?rev=945599&r1=945598&r2=945599&view=diff
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheFactoryContext.java (original)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheFactoryContext.java Tue May 18 11:51:04 2010
@@ -48,7 +48,7 @@ public class ApacheFactoryContext implem
         this.metaBeanFinder = metaBeanFinder;
     }
 
-  public ApacheValidatorFactory getFactory() {
+    public ApacheValidatorFactory getFactory() {
         return factory;
     }
 

Modified: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java?rev=945599&r1=945598&r2=945599&view=diff
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java (original)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/Jsr303MetaBeanFactory.java Tue May 18 11:51:04 2010
@@ -234,7 +234,7 @@ public class Jsr303MetaBeanFactory imple
         addXmlConstraints(beanClass, metabean);
     }
     
-    private boolean hasValidationConstraintsDefined(Method method) {
+    protected boolean hasValidationConstraintsDefined(Method method) {
         boolean ret = false;
         for ( Annotation annot : method.getDeclaredAnnotations() ) {
             if ( true == (ret = hasValidationConstraintsDefined(annot)) ) {

Modified: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java?rev=945599&r1=945598&r2=945599&view=diff
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java (original)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java Tue May 18 11:51:04 2010
@@ -16,22 +16,15 @@
  */
 package org.apache.bval.jsr303.extensions;
 
-import javax.validation.ConstraintViolation;
-import javax.validation.ValidationException;
-import javax.validation.metadata.BeanDescriptor;
-import javax.validation.metadata.ConstraintDescriptor;
-
-import org.apache.bval.jsr303.ApacheFactoryContext;
-import org.apache.bval.jsr303.BeanDescriptorImpl;
-import org.apache.bval.jsr303.ClassValidator;
-import org.apache.bval.jsr303.ConstraintValidation;
-import org.apache.bval.jsr303.ConstraintValidationListener;
-import org.apache.bval.jsr303.GroupValidationContext;
-import org.apache.bval.jsr303.Jsr303Features;
+import org.apache.bval.MetaBeanFactory;
+import org.apache.bval.MetaBeanManager;
+import org.apache.bval.jsr303.*;
 import org.apache.bval.jsr303.groups.Group;
 import org.apache.bval.jsr303.groups.Groups;
 import org.apache.bval.model.MetaBean;
 
+import javax.validation.ConstraintViolation;
+import javax.validation.metadata.ConstraintDescriptor;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.Collections;
@@ -42,249 +35,254 @@ import java.util.Set;
  * Description: experimental implementation of method-level-validation <br/>
  */
 class MethodValidatorImpl extends ClassValidator implements MethodValidator {
-
-    public MethodValidatorImpl(ApacheFactoryContext factoryContext) {
-        super(factoryContext);
-    }
-
-    
-    @Override
-    public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
-        // TODO: Cache this MetaBean
-        MetaBean uncachedStubmetaBean = new MetaBean();
-        uncachedStubmetaBean.setBeanClass(clazz);
-        BeanDescriptorImpl edesc = createBeanDescriptor(uncachedStubmetaBean);
-        return edesc;
-    }
-
-
-    @Override
-    protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
-        MethodBeanDescriptorImpl descriptor = new MethodBeanDescriptorImpl(factoryContext,
-              metaBean, metaBean.getValidations());
-        MethodValidatorMetaBeanFactory factory =
-              new MethodValidatorMetaBeanFactory(factoryContext);
-        factory.buildMethodDescriptor(descriptor);
-        return descriptor;
-    }
-
-    /**
-     * enhancement: method-level-validation not yet completly implemented
-     * <pre>example:
-     * <code>
-     * public @NotNull String saveItem(@Valid @NotNull Item item, @Max(23) BigDecimal
-     * </code></pre>
-     * spec:
-     * The constraints declarations evaluated are the constraints hosted on the
-     * parameters of the method or constructor. If @Valid is placed on a parameter,
-     * constraints declared on the object itself are considered.
-     *
-     * @throws IllegalArgumentException enhancement: if the method does not belong to <code>T</code>
-     *                                  or if the Object[] does not match the method signature
-     */
-    public <T> Set<ConstraintViolation<T>> validateParameters(Class<T> clazz, Method method,
-                                                              Object[] parameters,
-                                                              Class<?>... groupArray) {
-        MethodBeanDescriptorImpl beanDesc =
-              (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
-        MethodDescriptorImpl methodDescriptor =
-              (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
-        return validateParameters(methodDescriptor.getMetaBean(),
-              methodDescriptor.getParameterDescriptors(), parameters, groupArray);
-    }
-
-    public <T> Set<ConstraintViolation<T>> validateParameter(Class<T> clazz, Method method,
-                                                             Object parameter,
-                                                             int parameterIndex,
-                                                             Class<?>... groupArray) {
-        MethodBeanDescriptorImpl beanDesc =
-              (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
-        MethodDescriptorImpl methodDescriptor =
-              (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
-        ParameterDescriptorImpl paramDesc = (ParameterDescriptorImpl) methodDescriptor
-              .getParameterDescriptors().get(parameterIndex);
-        return validateParameter(paramDesc, parameter, groupArray);
-    }
-
-    public <T> Set<ConstraintViolation<T>> validateParameters(Class<T> clazz,
-                                                              Constructor<T> constructor,
-                                                              Object[] parameters,
-                                                              Class<?>... groupArray) {
-        MethodBeanDescriptorImpl beanDesc =
-              (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
-        ConstructorDescriptorImpl constructorDescriptor =
-              (ConstructorDescriptorImpl) beanDesc.getConstraintsForConstructor(constructor);
-        return validateParameters(constructorDescriptor.getMetaBean(),
-              constructorDescriptor.getParameterDescriptors(), parameters, groupArray);
-    }
-
-    public <T> Set<ConstraintViolation<T>> validateParameter(Class<T> clazz,
-                                                             Constructor<T> constructor,
-                                                             Object parameter,
-                                                             int parameterIndex,
+  public MethodValidatorImpl(ApacheFactoryContext factoryContext) {
+    super(factoryContext);
+    patchFactoryContextForMethodValidation(factoryContext);
+  }
+
+  /**
+   * experimental: replace the Jsr303MetaBeanFactory with a MethodValidatorMetaBeanFactory in the factoryContext.
+   */
+  private void patchFactoryContextForMethodValidation(ApacheFactoryContext factoryContext) {
+    MetaBeanFactory[] factories = ((MetaBeanManager) getMetaBeanFinder()).getBuilder().getFactories();
+    for(int i=0;i<factories.length;i++) {
+      if(factories[i] instanceof Jsr303MetaBeanFactory && !(factories[i] instanceof MethodValidatorMetaBeanFactory)) {
+        factories[i] = new MethodValidatorMetaBeanFactory(factoryContext);
+      }
+    }
+  }
+
+  @Override
+  protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
+    MethodBeanDescriptorImpl descriptor = new MethodBeanDescriptorImpl(factoryContext,
+        metaBean, metaBean.getValidations());
+    MethodValidatorMetaBeanFactory factory =
+        new MethodValidatorMetaBeanFactory(factoryContext);
+    factory.buildMethodDescriptor(descriptor);
+    return descriptor;
+  }
+
+  /**
+   * enhancement: method-level-validation not yet completly implemented
+   * <pre>example:
+   * <code>
+   * public @NotNull String saveItem(@Valid @NotNull Item item, @Max(23) BigDecimal
+   * </code></pre>
+   * spec:
+   * The constraints declarations evaluated are the constraints hosted on the
+   * parameters of the method or constructor. If @Valid is placed on a parameter,
+   * constraints declared on the object itself are considered.
+   *
+   * @throws IllegalArgumentException enhancement: if the method does not belong to <code>T</code>
+   *                                  or if the Object[] does not match the method signature
+   */
+  public <T> Set<ConstraintViolation<T>> validateParameters(Class<T> clazz, Method method,
+                                                            Object[] parameters,
+                                                            Class<?>... groupArray) {
+    MethodBeanDescriptorImpl beanDesc =
+        (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
+    MethodDescriptorImpl methodDescriptor =
+        (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
+    return validateParameters(methodDescriptor.getMetaBean(),
+        methodDescriptor.getParameterDescriptors(), parameters, groupArray);
+  }
+
+  public <T> Set<ConstraintViolation<T>> validateParameter(Class<T> clazz, Method method,
+                                                           Object parameter,
+                                                           int parameterIndex,
+                                                           Class<?>... groupArray) {
+    MethodBeanDescriptorImpl beanDesc =
+        (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
+    MethodDescriptorImpl methodDescriptor =
+        (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
+    ParameterDescriptorImpl paramDesc = (ParameterDescriptorImpl) methodDescriptor
+        .getParameterDescriptors().get(parameterIndex);
+    return validateParameter(paramDesc, parameter, groupArray);
+  }
+
+  public <T> Set<ConstraintViolation<T>> validateParameters(Class<T> clazz,
+                                                            Constructor<T> constructor,
+                                                            Object[] parameters,
+                                                            Class<?>... groupArray) {
+    MethodBeanDescriptorImpl beanDesc =
+        (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
+    ConstructorDescriptorImpl constructorDescriptor =
+        (ConstructorDescriptorImpl) beanDesc.getConstraintsForConstructor(constructor);
+    return validateParameters(constructorDescriptor.getMetaBean(),
+        constructorDescriptor.getParameterDescriptors(), parameters, groupArray);
+  }
+
+  public <T> Set<ConstraintViolation<T>> validateParameter(Class<T> clazz,
+                                                           Constructor<T> constructor,
+                                                           Object parameter,
+                                                           int parameterIndex,
+                                                           Class<?>... groupArray) {
+    MethodBeanDescriptorImpl beanDesc =
+        (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
+    ConstructorDescriptorImpl methodDescriptor =
+        (ConstructorDescriptorImpl) beanDesc.getConstraintsForConstructor(constructor);
+    ParameterDescriptorImpl paramDesc = (ParameterDescriptorImpl) methodDescriptor
+        .getParameterDescriptors().get(parameterIndex);
+    return validateParameter(paramDesc, parameter, groupArray);
+  }
+
+  /**
+   * If @Valid  is placed on the method, the constraints declared on the object
+   * itself are considered.
+   */
+  public <T> Set<ConstraintViolation<T>> validateReturnedValue(Class<T> clazz, Method method,
+                                                               Object returnedValue,
+                                                               Class<?>... groupArray) {
+    MethodBeanDescriptorImpl beanDesc =
+        (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
+    MethodDescriptorImpl methodDescriptor =
+        (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
+    final GroupValidationContext<ConstraintValidationListener<Object>> context =
+        createContext(methodDescriptor.getMetaBean(), returnedValue, null, groupArray);
+    validateReturnedValueInContext(context, methodDescriptor);
+    ConstraintValidationListener result = context.getListener();
+    return result.getConstaintViolations();
+  }
+
+  private <T> Set<ConstraintViolation<T>> validateParameters(MetaBean metaBean,
+                                                             List<ParameterDescriptor> paramDescriptors,
+                                                             Object[] parameters,
                                                              Class<?>... groupArray) {
-        MethodBeanDescriptorImpl beanDesc =
-              (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
-        ConstructorDescriptorImpl methodDescriptor =
-              (ConstructorDescriptorImpl) beanDesc.getConstraintsForConstructor(constructor);
-        ParameterDescriptorImpl paramDesc = (ParameterDescriptorImpl) methodDescriptor
-              .getParameterDescriptors().get(parameterIndex);
-        return validateParameter(paramDesc, parameter, groupArray);
-    }
-
-    /**
-     * If @Valid  is placed on the method, the constraints declared on the object
-     * itself are considered.
-     */
-    public <T> Set<ConstraintViolation<T>> validateReturnedValue(Class<T> clazz, Method method,
-                                                                 Object returnedValue,
-                                                                 Class<?>... groupArray) {
-        MethodBeanDescriptorImpl beanDesc =
-              (MethodBeanDescriptorImpl) getConstraintsForClass(clazz);
-        MethodDescriptorImpl methodDescriptor =
-              (MethodDescriptorImpl) beanDesc.getConstraintsForMethod(method);
-        final GroupValidationContext<ConstraintValidationListener<Object>> context =
-              createContext(methodDescriptor.getMetaBean(), returnedValue, null, groupArray);
-        validateReturnedValueInContext(context, methodDescriptor);
+    if (parameters == null) throw new IllegalArgumentException("cannot validate null");
+    if (parameters.length > 0) {
+      try {
+        GroupValidationContext<ConstraintValidationListener<Object[]>> context =
+            createContext(metaBean, null, null, groupArray);
+        for (int i = 0; i < parameters.length; i++) {
+          ParameterDescriptorImpl paramDesc =
+              (ParameterDescriptorImpl) paramDescriptors.get(i);
+          context.setBean(parameters[i]);
+          validateParameterInContext(context, paramDesc);
+        }
         ConstraintValidationListener result = context.getListener();
         return result.getConstaintViolations();
-    }
-
-    private <T> Set<ConstraintViolation<T>> validateParameters(MetaBean metaBean,
-                                                               List<ParameterDescriptor> paramDescriptors,
-                                                               Object[] parameters,
-                                                               Class<?>... groupArray) {
-        if (parameters == null) throw new IllegalArgumentException("cannot validate null");
-        if (parameters.length > 0) {
-            try {
-                GroupValidationContext<ConstraintValidationListener<Object[]>> context =
-                      createContext(metaBean, null, null, groupArray);
-                for (int i = 0; i < parameters.length; i++) {
-                    ParameterDescriptorImpl paramDesc =
-                          (ParameterDescriptorImpl) paramDescriptors.get(i);
-                    context.setBean(parameters[i]);
-                    validateParameterInContext(context, paramDesc);
-                }
-                ConstraintValidationListener result = context.getListener();
-                return result.getConstaintViolations();
-            } catch (RuntimeException ex) {
-                throw unrecoverableValidationError(ex, parameters);
-            }
-        } else {
-            return Collections.EMPTY_SET;
+      } catch (RuntimeException ex) {
+        throw unrecoverableValidationError(ex, parameters);
+      }
+    } else {
+      return Collections.EMPTY_SET;
+    }
+  }
+
+  private <T> Set<ConstraintViolation<T>> validateParameter(
+      ParameterDescriptorImpl paramDesc, Object parameter, Class<?>... groupArray) {
+    try {
+      final GroupValidationContext<ConstraintValidationListener<Object>> context =
+          createContext(paramDesc.getMetaBean(), parameter, null, groupArray);
+      final ConstraintValidationListener result = context.getListener();
+      validateParameterInContext(context, paramDesc);
+      return result.getConstaintViolations();
+    } catch (RuntimeException ex) {
+      throw unrecoverableValidationError(ex, parameter);
+    }
+  }
+
+  /**
+   * validate constraints hosted on parameters of a method
+   */
+  private <T> void validateParameterInContext(
+      GroupValidationContext<ConstraintValidationListener<T>> context,
+      ParameterDescriptorImpl paramDesc) {
+
+    final Groups groups = context.getGroups();
+
+    for (ConstraintDescriptor consDesc : paramDesc.getConstraintDescriptors()) {
+      ConstraintValidation validation = (ConstraintValidation) consDesc;
+      // 1. process groups
+      for (Group current : groups.getGroups()) {
+        context.setCurrentGroup(current);
+        validation.validate(context);
+      }
+      // 2. process sequences
+      for (List<Group> eachSeq : groups.getSequences()) {
+        for (Group current : eachSeq) {
+          context.setCurrentGroup(current);
+          validation.validate(context);
+          /**
+           * if one of the group process in the sequence leads to one or more validation failure,
+           * the groups following in the sequence must not be processed
+           */
+          if (!context.getListener().isEmpty()) break;
         }
+      }
     }
-
-    private <T> Set<ConstraintViolation<T>> validateParameter(
-          ParameterDescriptorImpl paramDesc, Object parameter, Class<?>... groupArray) {
-        try {
-            final GroupValidationContext<ConstraintValidationListener<Object>> context =
-                  createContext(paramDesc.getMetaBean(), parameter, null, groupArray);
-            final ConstraintValidationListener result = context.getListener();
-            validateParameterInContext(context, paramDesc);
-            return result.getConstaintViolations();
-        } catch (RuntimeException ex) {
-            throw unrecoverableValidationError(ex, parameter);
+    if (paramDesc.isCascaded() && context.getValidatedValue() != null) {
+      context.setMetaBean(factoryContext.getMetaBeanFinder().
+          findForClass(context.getValidatedValue().getClass()));
+      // 1. process groups
+      for (Group current : groups.getGroups()) {
+        context.setCurrentGroup(current);
+        validateContext(context);
+      }
+      // 2. process sequences
+      for (List<Group> eachSeq : groups.getSequences()) {
+        for (Group current : eachSeq) {
+          context.setCurrentGroup(current);
+          validateContext(context);
+          /**
+           * if one of the group process in the sequence leads to one or more validation failure,
+           * the groups following in the sequence must not be processed
+           */
+          if (!context.getListener().isEmpty()) break;
         }
+      }
     }
+  }
 
-    /** validate constraints hosted on parameters of a method */
-    private <T> void validateParameterInContext(
-          GroupValidationContext<ConstraintValidationListener<T>> context,
-          ParameterDescriptorImpl paramDesc) {
-
-        final Groups groups = context.getGroups();
-
-        for (ConstraintDescriptor consDesc : paramDesc.getConstraintDescriptors()) {
-            ConstraintValidation validation = (ConstraintValidation) consDesc;
-            // 1. process groups
-            for (Group current : groups.getGroups()) {
-                context.setCurrentGroup(current);
-                validation.validate(context);
-            }
-            // 2. process sequences
-            for (List<Group> eachSeq : groups.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    validation.validate(context);
-                    /**
-                     * if one of the group process in the sequence leads to one or more validation failure,
-                     * the groups following in the sequence must not be processed
-                     */
-                    if (!context.getListener().isEmpty()) break;
-                }
-            }
-        }
-        if (paramDesc.isCascaded() && context.getValidatedValue() != null) {
-            context.setMetaBean(factoryContext.getMetaBeanFinder().
-                  findForClass(context.getValidatedValue().getClass()));
-            // 1. process groups
-            for (Group current : groups.getGroups()) {
-                context.setCurrentGroup(current);
-                validateContext(context);
-            }
-            // 2. process sequences
-            for (List<Group> eachSeq : groups.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    validateContext(context);
-                    /**
-                     * if one of the group process in the sequence leads to one or more validation failure,
-                     * the groups following in the sequence must not be processed
-                     */
-                    if (!context.getListener().isEmpty()) break;
-                }
-            }
+  /**
+   * validate constraints hosted on parameters of a method
+   */
+  private <T> void validateReturnedValueInContext(
+      GroupValidationContext<ConstraintValidationListener<T>> context,
+      MethodDescriptorImpl methodDescriptor) {
+
+    final Groups groups = context.getGroups();
+
+    for (ConstraintDescriptor consDesc : methodDescriptor.getConstraintDescriptors()) {
+      ConstraintValidation validation = (ConstraintValidation) consDesc;
+      // 1. process groups
+      for (Group current : groups.getGroups()) {
+        context.setCurrentGroup(current);
+        validation.validate(context);
+      }
+      // 2. process sequences
+      for (List<Group> eachSeq : groups.getSequences()) {
+        for (Group current : eachSeq) {
+          context.setCurrentGroup(current);
+          validation.validate(context);
+          /**
+           * if one of the group process in the sequence leads to one or more validation failure,
+           * the groups following in the sequence must not be processed
+           */
+          if (!context.getListener().isEmpty()) break;
         }
+      }
     }
-
-    /** validate constraints hosted on parameters of a method */
-    private <T> void validateReturnedValueInContext(
-          GroupValidationContext<ConstraintValidationListener<T>> context,
-          MethodDescriptorImpl methodDescriptor) {
-
-        final Groups groups = context.getGroups();
-
-        for (ConstraintDescriptor consDesc : methodDescriptor.getConstraintDescriptors()) {
-            ConstraintValidation validation = (ConstraintValidation) consDesc;
-            // 1. process groups
-            for (Group current : groups.getGroups()) {
-                context.setCurrentGroup(current);
-                validation.validate(context);
-            }
-            // 2. process sequences
-            for (List<Group> eachSeq : groups.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    validation.validate(context);
-                    /**
-                     * if one of the group process in the sequence leads to one or more validation failure,
-                     * the groups following in the sequence must not be processed
-                     */
-                    if (!context.getListener().isEmpty()) break;
-                }
-            }
-        }
-        if (methodDescriptor.isCascaded() && context.getValidatedValue() != null) {
-            context.setMetaBean(factoryContext.getMetaBeanFinder().
-                  findForClass(context.getValidatedValue().getClass()));
-            // 1. process groups
-            for (Group current : groups.getGroups()) {
-                context.setCurrentGroup(current);
-                validateContext(context);
-            }
-            // 2. process sequences
-            for (List<Group> eachSeq : groups.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    validateContext(context);
-                    /**
-                     * if one of the group process in the sequence leads to one or more validation failure,
-                     * the groups following in the sequence must not be processed
-                     */
-                    if (!context.getListener().isEmpty()) break;
-                }
-            }
+    if (methodDescriptor.isCascaded() && context.getValidatedValue() != null) {
+      context.setMetaBean(factoryContext.getMetaBeanFinder().
+          findForClass(context.getValidatedValue().getClass()));
+      // 1. process groups
+      for (Group current : groups.getGroups()) {
+        context.setCurrentGroup(current);
+        validateContext(context);
+      }
+      // 2. process sequences
+      for (List<Group> eachSeq : groups.getSequences()) {
+        for (Group current : eachSeq) {
+          context.setCurrentGroup(current);
+          validateContext(context);
+          /**
+           * if one of the group process in the sequence leads to one or more validation failure,
+           * the groups following in the sequence must not be processed
+           */
+          if (!context.getListener().isEmpty()) break;
         }
+      }
     }
+  }
 }

Modified: incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorMetaBeanFactory.java
URL: http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorMetaBeanFactory.java?rev=945599&r1=945598&r2=945599&view=diff
==============================================================================
--- incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorMetaBeanFactory.java (original)
+++ incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorMetaBeanFactory.java Tue May 18 11:51:04 2010
@@ -38,115 +38,120 @@ import java.util.HashMap;
  */
 //TODO RSt - move. this is an optional module: move the whole package. core code has no dependencies on it 
 public class MethodValidatorMetaBeanFactory extends Jsr303MetaBeanFactory {
-    public MethodValidatorMetaBeanFactory(ApacheFactoryContext factoryContext) {
-        super(factoryContext);
-    }
-
-    public void buildMethodDescriptor(MethodBeanDescriptorImpl descriptor) {
-        try {
-            buildMethodConstraints(descriptor);
-            buildConstructorConstraints(descriptor);
-        } catch (Exception e) {
-            throw new IllegalArgumentException(e.getMessage(), e);
+  public MethodValidatorMetaBeanFactory(ApacheFactoryContext factoryContext) {
+    super(factoryContext);
+  }
+
+  @Override
+  protected boolean hasValidationConstraintsDefined(Method method) {
+    return false;
+  }
+
+  public void buildMethodDescriptor(MethodBeanDescriptorImpl descriptor) {
+    try {
+      buildMethodConstraints(descriptor);
+      buildConstructorConstraints(descriptor);
+    } catch (Exception e) {
+      throw new IllegalArgumentException(e.getMessage(), e);
+    }
+  }
+
+  private void buildConstructorConstraints(MethodBeanDescriptorImpl beanDesc)
+      throws InvocationTargetException, IllegalAccessException {
+    beanDesc.setConstructorConstraints(new HashMap<Constructor<?>, ConstructorDescriptor>());
+
+    for (Constructor<?> cons : beanDesc.getMetaBean().getBeanClass()
+        .getDeclaredConstructors()) {
+      if (!factoryContext.getFactory().getAnnotationIgnores()
+          .isIgnoreAnnotations(cons)) {
+
+        ConstructorDescriptorImpl consDesc =
+            new ConstructorDescriptorImpl(beanDesc.getMetaBean(), new Validation[0]);
+        beanDesc.putConstructorDescriptor(cons, consDesc);
+
+        Annotation[][] paramsAnnos = cons.getParameterAnnotations();
+        int idx = 0;
+        for (Annotation[] paramAnnos : paramsAnnos) {
+          ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
+          processAnnotations(consDesc, paramAnnos, access, idx);
+          idx++;
         }
+      }
     }
+  }
 
-    private void buildConstructorConstraints(MethodBeanDescriptorImpl beanDesc)
-          throws InvocationTargetException, IllegalAccessException {
-        beanDesc.setConstructorConstraints(new HashMap<Constructor<?>, ConstructorDescriptor>());
-
-        for (Constructor<?> cons : beanDesc.getMetaBean().getBeanClass()
-              .getDeclaredConstructors()) {
-            if (!factoryContext.getFactory().getAnnotationIgnores()
-                  .isIgnoreAnnotations(cons)) {
-
-                ConstructorDescriptorImpl consDesc =
-                      new ConstructorDescriptorImpl(beanDesc.getMetaBean(), new Validation[0]);
-                beanDesc.putConstructorDescriptor(cons, consDesc);
-
-                Annotation[][] paramsAnnos = cons.getParameterAnnotations();
-                int idx = 0;
-                for (Annotation[] paramAnnos : paramsAnnos) {
-                    ParameterAccess access = new ParameterAccess(cons.getParameterTypes()[idx], idx);
-                    processAnnotations(consDesc, paramAnnos, access, idx);
-                    idx++;
-                }
-            }
-        }
-    }
+  private void buildMethodConstraints(MethodBeanDescriptorImpl beanDesc)
+      throws InvocationTargetException, IllegalAccessException {
+    beanDesc.setMethodConstraints(new HashMap<Method, MethodDescriptor>());
 
-    private void buildMethodConstraints(MethodBeanDescriptorImpl beanDesc)
-          throws InvocationTargetException, IllegalAccessException {
-        beanDesc.setMethodConstraints(new HashMap<Method, MethodDescriptor>());
-
-        for (Method method : beanDesc.getMetaBean().getBeanClass().getDeclaredMethods()) {
-            if (!factoryContext.getFactory().getAnnotationIgnores()
-                  .isIgnoreAnnotations(method)) {
-
-
-                MethodDescriptorImpl methodDesc = new MethodDescriptorImpl(
-                      beanDesc.getMetaBean(), new Validation[0]);
-                beanDesc.putMethodDescriptor(method, methodDesc);
-
-                // return value validations
-                AppendValidationToList validations = new AppendValidationToList();
-                ReturnAccess returnAccess = new ReturnAccess(method.getReturnType());
-                for (Annotation anno : method.getAnnotations()) {
-                    processAnnotation(anno, methodDesc, returnAccess, validations);
-                }
-                methodDesc.getConstraintDescriptors().addAll(validations.getValidations());
-
-                // parameter validations
-                Annotation[][] paramsAnnos = method.getParameterAnnotations();
-                int idx = 0;
-                for (Annotation[] paramAnnos : paramsAnnos) {
-                    ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
-                    processAnnotations(methodDesc, paramAnnos, access, idx);
-                    idx++;
-                }
-            }
-        }
-    }
+    for (Method method : beanDesc.getMetaBean().getBeanClass().getDeclaredMethods()) {
+      if (!factoryContext.getFactory().getAnnotationIgnores()
+          .isIgnoreAnnotations(method)) {
+
+
+        MethodDescriptorImpl methodDesc = new MethodDescriptorImpl(
+            beanDesc.getMetaBean(), new Validation[0]);
+        beanDesc.putMethodDescriptor(method, methodDesc);
 
-    private void processAnnotations(ProcedureDescriptor methodDesc, Annotation[] paramAnnos,
-                                    AccessStrategy access, int idx)
-          throws InvocationTargetException, IllegalAccessException {
+        // return value validations
         AppendValidationToList validations = new AppendValidationToList();
-        for (Annotation anno : paramAnnos) {
-            processAnnotation(anno, methodDesc, access, validations);
+        ReturnAccess returnAccess = new ReturnAccess(method.getReturnType());
+        for (Annotation anno : method.getAnnotations()) {
+          processAnnotation(anno, methodDesc, returnAccess, validations);
+        }
+        methodDesc.getConstraintDescriptors().addAll(validations.getValidations());
+
+        // parameter validations
+        Annotation[][] paramsAnnos = method.getParameterAnnotations();
+        int idx = 0;
+        for (Annotation[] paramAnnos : paramsAnnos) {
+          ParameterAccess access = new ParameterAccess(method.getParameterTypes()[idx], idx);
+          processAnnotations(methodDesc, paramAnnos, access, idx);
+          idx++;
         }
-        ParameterDescriptorImpl paramDesc = new ParameterDescriptorImpl(
-              methodDesc.getMetaBean(), validations.getValidations().toArray(
-              new Validation[validations.getValidations().size()]));
-        paramDesc.setIndex(idx);
-        methodDesc.getParameterDescriptors().add(paramDesc);
+      }
     }
+  }
 
-    private void processAnnotation(Annotation annotation, ProcedureDescriptor desc,
-                                   AccessStrategy access, AppendValidation validations)
-          throws InvocationTargetException, IllegalAccessException {
-
-        if (annotation instanceof Valid) {
-            desc.setCascaded(true);
-        } else {
-            Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
-            if (vcAnno != null) {
-                Class<? extends ConstraintValidator<?, ?>>[] validatorClasses;
-                validatorClasses = findConstraintValidatorClasses(annotation, vcAnno);
-                applyConstraint(annotation, validatorClasses, null,
-                      desc.getMetaBean().getBeanClass(), access, validations);
-            } else {
-                /**
-                 * Multi-valued constraints
-                 */
-                Object result = SecureActions.getAnnotationValue(annotation, ANNOTATION_VALUE);
-                if (result != null && result instanceof Annotation[]) {
-                    for (Annotation each : (Annotation[]) result) {
-                        processAnnotation(each, desc, access, validations); // recursion
-                    }
-                }
-            }
+  private void processAnnotations(ProcedureDescriptor methodDesc, Annotation[] paramAnnos,
+                                  AccessStrategy access, int idx)
+      throws InvocationTargetException, IllegalAccessException {
+    AppendValidationToList validations = new AppendValidationToList();
+    for (Annotation anno : paramAnnos) {
+      processAnnotation(anno, methodDesc, access, validations);
+    }
+    ParameterDescriptorImpl paramDesc = new ParameterDescriptorImpl(
+        methodDesc.getMetaBean(), validations.getValidations().toArray(
+            new Validation[validations.getValidations().size()]));
+    paramDesc.setIndex(idx);
+    methodDesc.getParameterDescriptors().add(paramDesc);
+  }
+
+  private void processAnnotation(Annotation annotation, ProcedureDescriptor desc,
+                                 AccessStrategy access, AppendValidation validations)
+      throws InvocationTargetException, IllegalAccessException {
+
+    if (annotation instanceof Valid) {
+      desc.setCascaded(true);
+    } else {
+      Constraint vcAnno = annotation.annotationType().getAnnotation(Constraint.class);
+      if (vcAnno != null) {
+        Class<? extends ConstraintValidator<?, ?>>[] validatorClasses;
+        validatorClasses = findConstraintValidatorClasses(annotation, vcAnno);
+        applyConstraint(annotation, validatorClasses, null,
+            desc.getMetaBean().getBeanClass(), access, validations);
+      } else {
+        /**
+         * Multi-valued constraints
+         */
+        Object result = SecureActions.getAnnotationValue(annotation, ANNOTATION_VALUE);
+        if (result != null && result instanceof Annotation[]) {
+          for (Annotation each : (Annotation[]) result) {
+            processAnnotation(each, desc, access, validations); // recursion
+          }
         }
+      }
     }
+  }
 
 }