You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@bval.apache.org by Carlos Vara <ba...@gmail.com> on 2010/06/22 15:10:26 UTC

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

Aww, I was also working on this, although my approach was simpler (no
abstract beanvalidator, so there were still code repetition issues).

Once you finish your work with this Roman, please tell me so I can merge
some of my changes (mainly documentation, generics, some function name
changing, etc.).

On Tue, Jun 22, 2010 at 1:58 PM, <ro...@apache.org> wrote:

> Author: romanstumm
> Date: Tue Jun 22 12:58:28 2010
> New Revision: 956871
>
> URL: http://svn.apache.org/viewvc?rev=956871&view=rev
> Log:
> BVAL-47 Removed inheritance between ClassValidator and BeanValidator.
> Removed duplicate code
>
> Added:
>
>  incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/AbstractBeanValidator.java
> Modified:
>
>  incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/BeanValidator.java
>
>  incubator/bval/trunk/bval-core/src/test/java/org/apache/bval/ValidationResultsTest.java
>
>  incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheValidatorConfiguration.java
>
>  incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
>
>  incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/extensions/MethodValidatorImpl.java
>
> Added:
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/AbstractBeanValidator.java
> URL:
> http://svn.apache.org/viewvc/incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/AbstractBeanValidator.java?rev=956871&view=auto
>
> ==============================================================================
> ---
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/AbstractBeanValidator.java
> (added)
> +++
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/AbstractBeanValidator.java
> Tue Jun 22 12:58:28 2010
> @@ -0,0 +1,211 @@
> +/**
> + *  Licensed to the Apache Software Foundation (ASF) under one or more
> + *  contributor license agreements.  See the NOTICE file distributed with
> + *  this work for additional information regarding copyright ownership.
> + *  The ASF licenses this file to You under the Apache License, Version
> 2.0
> + *  (the "License"); you may not use this file except in compliance with
> + *  the License.  You may obtain a copy of the License at
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + *  Unless required by applicable law or agreed to in writing, software
> + *  distributed under the License is distributed on an "AS IS" BASIS,
> + *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + *  See the License for the specific language governing permissions and
> + *  limitations under the License.
> + */
> +package org.apache.bval;
> +
> +import org.apache.bval.model.MetaProperty;
> +import org.apache.bval.model.Validation;
> +import org.apache.bval.model.ValidationContext;
> +import org.apache.bval.model.ValidationListener;
> +
> +import java.util.Iterator;
> +import java.util.List;
> +import java.util.Map;
> +
> +/**
> + * Description: <br>
> + * User: roman.stumm<br>
> + * Date: 18.06.2010<br>
> + * Time: 11:25:26<br>
> + * viaboxx GmbH, 2010
> + */
> +public abstract class AbstractBeanValidator {
> +  private boolean treatMapsLikeBeans = false;
> +
> +  /**
> +   * Behavior configuration -
> +   * <pre>
> +   * parameter: treatMapsLikeBeans - true (validate maps like beans, so
> that
> +   *                             you can use Maps to validate dynamic
> classes or
> +   *                             beans for which you have the MetaBean but
> no instances)
> +   *                           - false (default), validate maps like
> collections
> +   *                             (validating the values only)
> +   * </pre>
> +   * (is still configuration to better in BeanValidationContext?)
> +   */
> +  public boolean isTreatMapsLikeBeans() {
> +    return treatMapsLikeBeans;
> +  }
> +
> +  public void setTreatMapsLikeBeans(boolean treatMapsLikeBeans) {
> +    this.treatMapsLikeBeans = treatMapsLikeBeans;
> +  }
> +
> +  /**
> +   * validate a single bean only. no related beans will be validated
> +   */
> +  public <VL extends ValidationListener> void
> validateBean(ValidationContext<VL> context) {
> +    /**
> +     * execute all property level validations
> +     */
> +    for (MetaProperty prop : context.getMetaBean().getProperties()) {
> +      context.setMetaProperty(prop);
> +      validateProperty(context);
> +    }
> +    /**
> +     * execute all bean level validations
> +     */
> +    context.setMetaProperty(null);
> +    for (Validation validation : context.getMetaBean().getValidations()) {
> +      validation.validate(context);
> +    }
> +  }
> +
> +
> +  /**
> +   * validate a single property only. performs all validations
> +   * for this property.
> +   */
> +  public <VL extends ValidationListener> void
> validateProperty(ValidationContext<VL> context) {
> +    for (Validation validation :
> context.getMetaProperty().getValidations()) {
> +      validation.validate(context);
> +    }
> +  }
> +
> +  protected <VL extends ValidationListener> void
> validateBeanInContext(ValidationContext<VL> context) {
> +    if (getDynamicMetaBean(context) != null) {
> +      context.setMetaBean(
> +          getDynamicMetaBean(context).resolveMetaBean(context.getBean()));
> +    }
> +    validateBeanNet(context);
> +  }
> +
> +  protected <VL extends ValidationListener> void
> validateArrayInContext(ValidationContext<VL> context) {
> +    int index = 0;
> +    DynamicMetaBean dyn = getDynamicMetaBean(context);
> +    for (Object each : ((Object[]) context.getBean())) {
> +      context.setCurrentIndex(index++);
> +      if (each == null) continue; // or throw IllegalArgumentException?
> (=> spec)
> +      if (dyn != null) {
> +        context.setBean(each, dyn.resolveMetaBean(each));
> +      } else {
> +        context.setBean(each);
> +      }
> +      validateBeanNet(context);
> +    }
> +  }
> +
> +  /**
> +   * Any object implementing java.lang.Iterable is supported
> +   */
> +  protected <VL extends ValidationListener> void
> validateIteratableInContext(ValidationContext<VL> context) {
> +    Iterator<?> it = ((Iterable<?>) context.getBean()).iterator();
> +    int index = 0;
> +    // jsr303 spec: Each object provided by the iterator is validated.
> +    final DynamicMetaBean dyn = getDynamicMetaBean(context);
> +    while (it.hasNext()) { // to Many
> +      Object each = it.next();
> +      context.setCurrentIndex(index++);
> +      if (each == null)
> +        continue; // enhancement: throw IllegalArgumentException? (=>
> spec)
> +      if (dyn != null) {
> +        context.setBean(each, dyn.resolveMetaBean(each));
> +      } else {
> +        context.setBean(each);
> +      }
> +      validateBeanNet(context);
> +    }
> +  }
> +
> +  protected <VL extends ValidationListener> void
> validateNonPositionalIteratableInContext(
> +      ValidationContext<VL> context) {
> +    Iterator<?> it = ((Iterable<?>) context.getBean()).iterator();
> +    // jsr303 spec: Each object provided by the iterator is validated.
> +    context.setCurrentIndex(null);
> +    final DynamicMetaBean dyn = getDynamicMetaBean(context);
> +    while (it.hasNext()) { // to Many
> +      Object each = it.next();
> +      if (each == null)
> +        continue; // enhancement: throw IllegalArgumentException? (=>
> spec)
> +      if (dyn != null) {
> +        context.setBean(each, dyn.resolveMetaBean(each));
> +      } else {
> +        context.setBean(each);
> +      }
> +      validateBeanNet(context);
> +    }
> +  }
> +
> +  protected <VL extends ValidationListener> void
> validateMapInContext(ValidationContext<VL> context) {
> +    // jsr303 spec: For Map, the value of each Map.Entry is validated (key
> is not validated).
> +    Iterator<Map.Entry<Object, Object>> it = ((Map<Object, Object>)
> context.getBean()).entrySet().iterator();
> +    final DynamicMetaBean dyn = getDynamicMetaBean(context);
> +    while (it.hasNext()) { // to Many
> +      Map.Entry<Object, Object> entry = it.next();
> +      context.setCurrentKey(entry.getKey());
> +      if (entry.getValue() == null)
> +        continue; // enhancement: throw IllegalArgumentException? (=>
> spec)
> +      if (dyn != null) {
> +        context.setBean(entry.getValue(),
> dyn.resolveMetaBean(entry.getValue()));
> +      } else {
> +        context.setBean(entry.getValue());
> +      }
> +      validateBeanNet(context);
> +    }
> +  }
> +
> +  private <VL extends ValidationListener> DynamicMetaBean
> getDynamicMetaBean(ValidationContext<VL> context) {
> +    return context.getMetaBean() instanceof DynamicMetaBean ?
> +        (DynamicMetaBean) context.getMetaBean() : null;
> +  }
> +
> +  /**
> +   * internal validate a bean (=not a collection of beans) and its related
> beans
> +   */
> +  protected abstract <VL extends ValidationListener> void
> validateBeanNet(ValidationContext<VL> context);
> +
> +
> +  /**
> +   * validate a complex 'bean' with related beans according to
> +   * validation rules in 'metaBean'
> +   *
> +   * @param context - the context is initialized with:
> +   *                <br>&nbsp;&nbsp;bean - the root object start
> validation at
> +   *                or a collection of root objects
> +   *                <br>&nbsp;&nbsp;metaBean - the meta information for
> the root object(s)
> +   * @param context The current validation context.
> +   * @return a new instance of validation results
> +   *         <p/>
> +   *         Methods defined in {@link BeanValidator} take care of setting
> the path
> +   *         and current bean correctly and call
> +   *         {@link #validateBeanNet(ValidationContext)} for each
> individual bean.
> +   */
> +  protected void validateContext(ValidationContext<?> context) {
> +    if (context.getBean() != null) {
> +      if (!treatMapsLikeBeans && context.getBean() instanceof Map<?, ?>) {
> +        validateMapInContext(context);
> +      } else if (context.getBean() instanceof List<?>) {
> +        validateIteratableInContext(context);
> +      } else if (context.getBean() instanceof Iterable<?>) {
> +        validateNonPositionalIteratableInContext(context);
> +      } else if (context.getBean() instanceof Object[]) {
> +        validateArrayInContext(context);
> +      } else { // to One Bean (or Map like Bean)
> +        validateBeanInContext(context);
> +      }
> +    }
> +  }
> +}
>
> Modified:
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/BeanValidator.java
> URL:
> http://svn.apache.org/viewvc/incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/BeanValidator.java?rev=956871&r1=956870&r2=956871&view=diff
>
> ==============================================================================
> ---
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/BeanValidator.java
> (original)
> +++
> incubator/bval/trunk/bval-core/src/main/java/org/apache/bval/BeanValidator.java
> Tue Jun 22 12:58:28 2010
> @@ -23,9 +23,6 @@ import org.apache.bval.util.PropertyAcce
>  import java.lang.annotation.Annotation;
>  import java.lang.reflect.Method;
>  import java.util.Collection;
> -import java.util.Iterator;
> -import java.util.List;
> -import java.util.Map;
>
>  /**
>  * Description: Top-Level API-class to validate objects or object-trees.
> @@ -35,329 +32,177 @@ import java.util.Map;
>  * This class supports cyclic object graphs by keeping track of
>  * validated instances in the validation context.<br/>
>  */
> -public class BeanValidator<T extends ValidationListener> {
> -    private boolean treatMapsLikeBeans = false;
> -    private final MetaBeanFinder metaBeanFinder;
> -
> -    /**
> -     * convenience method. Use the global instance of
> MetaBeanManagerFactory.getFinder().
> -     */
> -    public BeanValidator() {
> -        this(MetaBeanManagerFactory.getFinder());
> -    }
> -
> -    public BeanValidator(MetaBeanFinder metaBeanFinder) {
> -        this.metaBeanFinder = metaBeanFinder;
> -    }
> -
> -    /**
> -     * Behavior configuration -
> -     * <pre>
> -     * parameter: treatMapsLikeBeans - true (validate maps like beans, so
> that
> -     *                             you can use Maps to validate dynamic
> classes or
> -     *                             beans for which you have the MetaBean
> but no instances)
> -     *                           - false (default), validate maps like
> collections
> -     *                             (validating the values only)
> -     * </pre>
> -     * (is still configuration to better in BeanValidationContext?)
> -     */
> -    public boolean isTreatMapsLikeBeans() {
> -        return treatMapsLikeBeans;
> -    }
> -
> -    public void setTreatMapsLikeBeans(boolean treatMapsLikeBeans) {
> -        this.treatMapsLikeBeans = treatMapsLikeBeans;
> -    }
> -
> -    /**
> -     * convenience API. validate a root object with all related objects
> -     * with its default metaBean definition.
> -     *
> -     * @return results - validation results found
> -     */
> -    public T validate(Object bean) {
> -        MetaBean metaBean =
> -              getMetaBeanFinder().findForClass(bean.getClass());
> -        return validate(bean, metaBean);
> -    }
> +public class BeanValidator<T extends ValidationListener> extends
> AbstractBeanValidator {
> +  private final MetaBeanFinder metaBeanFinder;
>
> -    /**
> -     * convenience API. validate a root object with all related objects
> -     * according to the metaBean.
> -     *
> -     * @param bean - a single bean or a collection of beans (that share
> the same metaBean!)
> -     * @return results - validation results found
> -     */
> -    public T validate(Object bean, MetaBean metaBean) {
> -        ValidationContext<T> context = createContext();
> -        context.setBean(bean, metaBean);
> +  /**
> +   * convenience method. Use the global instance of
> MetaBeanManagerFactory.getFinder().
> +   */
> +  public BeanValidator() {
> +    this(MetaBeanManagerFactory.getFinder());
> +  }
> +
> +  public BeanValidator(MetaBeanFinder metaBeanFinder) {
> +    this.metaBeanFinder = metaBeanFinder;
> +  }
> +
> +
> +  /**
> +   * convenience API. validate a root object with all related objects
> +   * with its default metaBean definition.
> +   *
> +   * @return results - validation results found
> +   */
> +  public T validate(Object bean) {
> +    MetaBean metaBean =
> +        getMetaBeanFinder().findForClass(bean.getClass());
> +    return validate(bean, metaBean);
> +  }
> +
> +  /**
> +   * convenience API. validate a root object with all related objects
> +   * according to the metaBean.
> +   *
> +   * @param bean - a single bean or a collection of beans (that share the
> same metaBean!)
> +   * @return results - validation results found
> +   */
> +  public T validate(Object bean, MetaBean metaBean) {
> +    ValidationContext<T> context = createContext();
> +    context.setBean(bean, metaBean);
> +    validateContext(context);
> +    return context.getListener();
> +  }
> +
> +  /**
> +   * validate the method parameters based on @Validate annotations.
> +   * Requirements:
> +   * Parameter, that are to be validated must be annotated with @Validate
> +   *
> +   * @param method     -  a method
> +   * @param parameters - the parameters suitable to the method
> +   * @return a validation result or null when there was nothing to
> validate
> +   * @see Validate
> +   */
> +  public T validateCall(Method method, Object[] parameters) {
> +    if (parameters.length > 0) {
> +      // shortcut (for performance!)
> +      Annotation[][] annotations = method.getParameterAnnotations();
> +      ValidationContext<T> context = null;
> +      for (int i = 0; i < parameters.length; i++) {
> +        for (Annotation anno : annotations[i]) {
> +          if (anno instanceof Validate) {
> +            if (context == null) context = createContext();
> +            if (determineMetaBean((Validate) anno, parameters[i],
> context)) {
> +              validateContext(context);
> +              break; // next parameter
> +            }
> +          }
> +        }
> +      }
> +      return context != null ? context.getListener() : null;
> +    }
> +    return null;
> +  }
> +
> +  /**
> +   * @return true when validation should happen, false to skip it
> +   */
> +  protected <VL extends ValidationListener> boolean
> determineMetaBean(Validate validate, Object parameter,
> +
>  ValidationContext<VL> context) {
> +    if (validate.value().length() == 0) {
> +      if (parameter == null) return false;
> +      Class<?> beanClass;
> +      if (parameter instanceof Collection<?>) {   // do not validate empty
> collection
> +        Collection<?> coll = ((Collection<?>) parameter);
> +        if (coll.isEmpty()) return false;
> +        beanClass = coll.iterator().next().getClass(); // get first object
> +      } else if (parameter.getClass().isArray()) {
> +        beanClass = parameter.getClass().getComponentType();
> +      } else {
> +        beanClass = parameter.getClass();
> +      }
> +      context.setBean(parameter,
> getMetaBeanFinder().findForClass(beanClass));
> +    } else {
> +      context.setBean(parameter,
> getMetaBeanFinder().findForId(validate.value()));
> +    }
> +    return true;
> +  }
> +
> +  /**
> +   * factory method -
> +   * overwrite in subclasses
> +   */
> +  protected T createResults() {
> +    return (T) new ValidationResults();
> +  }
> +
> +  /**
> +   * factory method -
> +   * overwrite in subclasses
> +   */
> +  protected ValidationContext<T> createContext() {
> +    return new BeanValidationContext<T>(createResults());
> +  }
> +
> +  /**
> +   * convenience API. validate a single property.
> +   *
> +   * @param bean         - the root object
> +   * @param metaProperty - metadata for the property
> +   * @return validation results
> +   */
> +  public T validateProperty(Object bean, MetaProperty metaProperty) {
> +    ValidationContext<T> context = createContext();
> +    context.setBean(bean);
> +    context.setMetaProperty(metaProperty);
> +    validateProperty(context);
> +    return context.getListener();
> +  }
> +
> +  /**
> +   * internal validate a bean (=not a collection of beans) and its related
> beans
> +   */
> +  protected <VL extends ValidationListener> void
> validateBeanNet(ValidationContext<VL> context) {
> +    if (context.collectValidated()) {
> +      validateBean(context);
> +      for (MetaProperty prop : context.getMetaBean().getProperties()) {
> +        validateRelatedBean(context, prop);
> +      }
> +    }
> +  }
> +
> +  protected <VL extends ValidationListener> void
> validateRelatedBean(ValidationContext<VL> context, MetaProperty prop) {
> +    AccessStrategy[] access =
> prop.getFeature(Features.Property.REF_CASCADE);
> +    if (access == null && prop.getMetaBean() != null) { // single property
> access strategy
> +      // save old values from context
> +      final Object bean = context.getBean();
> +      final MetaBean mbean = context.getMetaBean();
> +      // modify context state for relationship-target bean
> +      context.moveDown(prop, new PropertyAccess(bean.getClass(),
> prop.getName()));
> +      validateContext(context);
> +      // restore old values in context
> +      context.moveUp(bean, mbean);
> +    } else if (access != null) { // different accesses to relation
> +      // save old values from context
> +      final Object bean = context.getBean();
> +      final MetaBean mbean = context.getMetaBean();
> +      for (AccessStrategy each : access) {
> +        // modify context state for relationship-target bean
> +        context.moveDown(prop, each);
>         validateContext(context);
> -        return context.getListener();
> -    }
> -
> -    /**
> -     * validate the method parameters based on @Validate annotations.
> -     * Requirements:
> -     * Parameter, that are to be validated must be annotated with
> @Validate
> -     *
> -     * @param method     -  a method
> -     * @param parameters - the parameters suitable to the method
> -     * @return a validation result or null when there was nothing to
> validate
> -     * @see Validate
> -     */
> -    public T validateCall(Method method, Object[] parameters) {
> -        if (parameters.length > 0) {
> -            // shortcut (for performance!)
> -            Annotation[][] annotations = method.getParameterAnnotations();
> -            ValidationContext<T> context = null;
> -            for (int i = 0; i < parameters.length; i++) {
> -                for (Annotation anno : annotations[i]) {
> -                    if (anno instanceof Validate) {
> -                        if(context == null) context = createContext();
> -                        if (determineMetaBean((Validate) anno,
> parameters[i], context)) {
> -                            validateContext(context);
> -                            break; // next parameter
> -                        }
> -                    }
> -                }
> -            }
> -            return context != null ? context.getListener() : null;
> -        }
> -        return null;
> -    }
> -
> -    /** @return true when validation should happen, false to skip it */
> -    protected <VL extends ValidationListener> boolean
> determineMetaBean(Validate validate, Object parameter,
> -                                        ValidationContext<VL> context) {
> -        if (validate.value().length() == 0) {
> -            if (parameter == null) return false;
> -            Class<?> beanClass;
> -            if (parameter instanceof Collection<?>) {   // do not validate
> empty collection
> -                Collection<?> coll = ((Collection<?>) parameter);
> -                if (coll.isEmpty()) return false;
> -                beanClass = coll.iterator().next().getClass(); // get
> first object
> -            } else if (parameter.getClass().isArray()) {
> -                beanClass = parameter.getClass().getComponentType();
> -            } else {
> -                beanClass = parameter.getClass();
> -            }
> -
>  context.setBean(parameter,getMetaBeanFinder().findForClass(beanClass));
> -        } else {
> -
>  context.setBean(parameter,getMetaBeanFinder().findForId(validate.value()));
> -        }
> -        return true;
> -    }
> -
> -    /**
> -     * factory method -
> -     * overwrite in subclasses
> -     */
> -    protected T createResults() {
> -        return (T) new ValidationResults();
> -    }
> -
> -    /**
> -     * factory method -
> -     * overwrite in subclasses
> -     */
> -    protected ValidationContext<T> createContext() {
> -        return new BeanValidationContext<T>(createResults());
> -    }
> -
> -    /**
> -     * convenience API. validate a single property.
> -     *
> -     * @param bean         - the root object
> -     * @param metaProperty - metadata for the property
> -     * @return validation results
> -     */
> -    public T validateProperty(Object bean, MetaProperty metaProperty) {
> -        ValidationContext<T> context = createContext();
> -        context.setBean(bean);
> -        context.setMetaProperty(metaProperty);
> -        validateProperty(context);
> -        return context.getListener();
> -    }
> -
> -    /**
> -     * validate a single property only. performs all validations
> -     * for this property.
> -     */
> -    public <VL extends ValidationListener> void
> validateProperty(ValidationContext<VL> context) {
> -        for (Validation validation :
> context.getMetaProperty().getValidations()) {
> -            validation.validate(context);
> -        }
> -    }
> -
> -    /**
> -     * validate a complex 'bean' with related beans according to
> -     * validation rules in 'metaBean'
> -     *
> -     * @param context - the context is initialized with:
> -     *                <br>&nbsp;&nbsp;bean - the root object start
> validation at
> -     *                or a collection of root objects
> -     *                <br>&nbsp;&nbsp;metaBean - the meta information for
> the root object(s)
> -     * @return a new instance of validation results
> -     */
> -    public <VL extends ValidationListener> void
> validateContext(ValidationContext<VL> context) {
> -        if (context.getBean() != null) {
> -            if (!treatMapsLikeBeans && context.getBean() instanceof Map<?,
> ?>) {
> -                validateMapInContext(context);
> -            } else if (context.getBean() instanceof List<?>) {
> -               validateIteratableInContext(context);
> -            } else if (context.getBean() instanceof Iterable<?>) {
> -                validateNonPositionalIteratableInContext(context);
> -            } else if (context.getBean() instanceof Object[]) {
> -                validateArrayInContext(context);
> -            } else { // to One Bean (or Map like Bean)
> -                validateBeanInContext(context);
> -            }
> -        }
> -    }
> -
> -    protected <VL extends ValidationListener> void
> validateBeanInContext(ValidationContext<VL> context) {
> -        if (getDynamicMetaBean(context) != null) {
> -            context.setMetaBean(
> -
>  getDynamicMetaBean(context).resolveMetaBean(context.getBean()));
> -        }
> -        validateBeanNet(context);
> -    }
> -
> -    protected <VL extends ValidationListener> void
> validateArrayInContext(ValidationContext<VL> context) {
> -        int index = 0;
> -        DynamicMetaBean dyn = getDynamicMetaBean(context);
> -        for (Object each : ((Object[]) context.getBean())) {
> -            context.setCurrentIndex(index++);
> -            if (each == null) continue; // or throw
> IllegalArgumentException? (=> spec)
> -            if (dyn != null) {
> -                context.setBean(each, dyn.resolveMetaBean(each));
> -            } else {
> -                context.setBean(each);
> -            }
> -            validateBeanNet(context);
> -        }
> -    }
> -
> -    private <VL extends ValidationListener> DynamicMetaBean
> getDynamicMetaBean(ValidationContext<VL> context) {
> -        return context.getMetaBean() instanceof DynamicMetaBean ?
> -              (DynamicMetaBean) context.getMetaBean() : null;
> -    }
> -
> -    /** Any object implementing java.lang.Iterable is supported */
> -    protected <VL extends ValidationListener> void
> validateIteratableInContext(ValidationContext<VL> context) {
> -        Iterator<?> it = ((Iterable<?>) context.getBean()).iterator();
> -        int index = 0;
> -        // jsr303 spec: Each object provided by the iterator is validated.
> -        final DynamicMetaBean dyn = getDynamicMetaBean(context);
> -        while (it.hasNext()) { // to Many
> -            Object each = it.next();
> -            context.setCurrentIndex(index++);
> -            if (each == null)
> -                continue; // enhancement: throw IllegalArgumentException?
> (=> spec)
> -            if (dyn != null) {
> -                context.setBean(each, dyn.resolveMetaBean(each));
> -            } else {
> -                context.setBean(each);
> -            }
> -            validateBeanNet(context);
> -        }
> -    }
> -
> -    protected <VL extends ValidationListener> void
> validateNonPositionalIteratableInContext(ValidationContext<VL> context) {
> -        Iterator<?> it = ((Iterable<?>) context.getBean()).iterator();
> -        // jsr303 spec: Each object provided by the iterator is validated.
> -        context.setCurrentIndex(null);
> -        final DynamicMetaBean dyn = getDynamicMetaBean(context);
> -        while (it.hasNext()) { // to Many
> -            Object each = it.next();
> -            if (each == null)
> -                continue; // enhancement: throw IllegalArgumentException?
> (=> spec)
> -            if (dyn != null) {
> -                context.setBean(each, dyn.resolveMetaBean(each));
> -            } else {
> -                context.setBean(each);
> -            }
> -            validateBeanNet(context);
> -        }
> -    }
> -
> -    protected <VL extends ValidationListener> void
> validateMapInContext(ValidationContext<VL> context) {
> -        // jsr303 spec: For Map, the value of each Map.Entry is validated
> (key is not validated).
> -        Iterator<Map.Entry<Object, Object>> it = ((Map<Object, Object>)
> context.getBean()).entrySet().iterator();
> -        final DynamicMetaBean dyn = getDynamicMetaBean(context);
> -        while (it.hasNext()) { // to Many
> -            Map.Entry<Object, Object> entry = it.next();
> -            context.setCurrentKey(entry.getKey());
> -            if (entry.getValue() == null)
> -                continue; // enhancement: throw IllegalArgumentException?
> (=> spec)
> -            if (dyn != null) {
> -                context.setBean(entry.getValue(),
> dyn.resolveMetaBean(entry.getValue()));
> -            } else {
> -                context.setBean(entry.getValue());
> -            }
> -            validateBeanNet(context);
> -        }
> -    }
> -
> -    /** internal validate a bean (=not a collection of beans) and its
> related beans */
> -    protected <VL extends ValidationListener> void
> validateBeanNet(ValidationContext<VL> context) {
> -        if (context.collectValidated()) {
> -            validateBean(context);
> -            for (MetaProperty prop :
> context.getMetaBean().getProperties()) {
> -                validateRelatedBean(context, prop);
> -            }
> -        }
> -    }
> -
> -    protected <VL extends ValidationListener> void
> validateRelatedBean(ValidationContext<VL> context, MetaProperty prop) {
> -        AccessStrategy[] access =
> prop.getFeature(Features.Property.REF_CASCADE);
> -        if (access == null && prop.getMetaBean() != null) { // single
> property access strategy
> -            // save old values from context
> -            final Object bean = context.getBean();
> -            final MetaBean mbean = context.getMetaBean();
> -            // modify context state for relationship-target bean
> -            context.moveDown(prop, new PropertyAccess(bean.getClass(),
> prop.getName()));
> -            validateContext(context);
> -            // restore old values in context
> -            context.moveUp(bean, mbean);
> -        } else if (access != null) { // different accesses to relation
> -            // save old values from context
> -            final Object bean = context.getBean();
> -            final MetaBean mbean = context.getMetaBean();
> -            for (AccessStrategy each : access) {
> -                // modify context state for relationship-target bean
> -                context.moveDown(prop, each);
> -                validateContext(context);
> -                // restore old values in context
> -                context.moveUp(bean, mbean);
> -            }
> -        }
> -    }
> -
> -    /** validate a single bean only. no related beans will be validated */
> -    public <VL extends ValidationListener> void
> validateBean(ValidationContext<VL> context) {
> -        /**
> -         * execute all property level validations
> -         */
> -        for (MetaProperty prop : context.getMetaBean().getProperties()) {
> -            context.setMetaProperty(prop);
> -            validateProperty(context);
> -        }
> -        /**
> -         * execute all bean level validations
> -         */
> -        context.setMetaProperty(null);
> -        for (Validation validation :
> context.getMetaBean().getValidations()) {
> -            validation.validate(context);
> -        }
> -    }
> -
> -    /**
> -     * the metabean finder associated with this validator.
> -     * @see org.apache.bval.MetaBeanManagerFactory#getFinder()
> -     * @return a MetaBeanFinder
> -     */
> -    public MetaBeanFinder getMetaBeanFinder() {
> -        return metaBeanFinder;
> -    }
> +        // restore old values in context
> +        context.moveUp(bean, mbean);
> +      }
> +    }
> +  }
> +
> +  /**
> +   * the metabean finder associated with this validator.
> +   *
> +   * @return a MetaBeanFinder
> +   * @see org.apache.bval.MetaBeanManagerFactory#getFinder()
> +   */
> +  public MetaBeanFinder getMetaBeanFinder() {
> +    return metaBeanFinder;
> +  }
>  }
>
> Modified:
> incubator/bval/trunk/bval-core/src/test/java/org/apache/bval/ValidationResultsTest.java
> URL:
> http://svn.apache.org/viewvc/incubator/bval/trunk/bval-core/src/test/java/org/apache/bval/ValidationResultsTest.java?rev=956871&r1=956870&r2=956871&view=diff
>
> ==============================================================================
> ---
> incubator/bval/trunk/bval-core/src/test/java/org/apache/bval/ValidationResultsTest.java
> (original)
> +++
> incubator/bval/trunk/bval-core/src/test/java/org/apache/bval/ValidationResultsTest.java
> Tue Jun 22 12:58:28 2010
> @@ -16,13 +16,10 @@
>  */
>  package org.apache.bval;
>
> -import org.apache.bval.BeanValidationContext;
> -import org.apache.bval.ValidationResults;
> -import org.apache.bval.model.MetaProperty;
> -
>  import junit.framework.Test;
>  import junit.framework.TestCase;
>  import junit.framework.TestSuite;
> +import org.apache.bval.model.MetaProperty;
>
>  /**
>  * ValidationResults Tester.
>
> Modified:
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheValidatorConfiguration.java
> URL:
> http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheValidatorConfiguration.java?rev=956871&r1=956870&r2=956871&view=diff
>
> ==============================================================================
> ---
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheValidatorConfiguration.java
> (original)
> +++
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ApacheValidatorConfiguration.java
> Tue Jun 22 12:58:28 2010
> @@ -60,7 +60,7 @@ public interface ApacheValidatorConfigur
>
>         /**
>          * BeanValidator.treatMapsLikeBeans.
> -         * default: false
> +         * default: false
>          */
>          String TREAT_MAPS_LIKE_BEANS =
> "apache.bval.treat-maps-like-beans";
>     }
>
> Modified:
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
> URL:
> http://svn.apache.org/viewvc/incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java?rev=956871&r1=956870&r2=956871&view=diff
>
> ==============================================================================
> ---
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
> (original)
> +++
> incubator/bval/trunk/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
> Tue Jun 22 12:58:28 2010
> @@ -19,7 +19,8 @@
>  package org.apache.bval.jsr303;
>
>
> -import org.apache.bval.BeanValidator;
> +import org.apache.bval.AbstractBeanValidator;
> +import org.apache.bval.MetaBeanFinder;
>  import org.apache.bval.jsr303.groups.Group;
>  import org.apache.bval.jsr303.groups.Groups;
>  import org.apache.bval.jsr303.groups.GroupsComputer;
> @@ -41,7 +42,6 @@ import javax.validation.groups.Default;
>  import javax.validation.metadata.BeanDescriptor;
>  import java.util.ArrayList;
>  import java.util.List;
> -import java.util.Map;
>  import java.util.Set;
>
>  /**
> @@ -52,172 +52,181 @@ import java.util.Set;
>  * It is recommended to cache the instance.
>  * <br/>
>  */
> -public class ClassValidator extends BeanValidator implements Validator {
> -    protected final ApacheFactoryContext factoryContext;
> -    protected final GroupsComputer groupsComputer = new GroupsComputer();
> -
> -    public ClassValidator(ApacheFactoryContext factoryContext) {
> -        super(factoryContext.getMetaBeanFinder());
> -        this.factoryContext = factoryContext;
> -    }
> -
> -    /** @deprecated provided for backward compatibility */
> -    public ClassValidator(ApacheValidatorFactory factory) {
> -        this(factory.usingContext());
> -    }
> -
> -    /**
> -     * validate all constraints on object
> -     *
> -     * @throws javax.validation.ValidationException
> -     *          if a non recoverable error happens during the validation
> process
> -     */
> -    public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>...
> groupArray) {
> -        if (object == null) throw new IllegalArgumentException("cannot
> validate null");
> -        checkGroups(groupArray);
> -
> -        try {
> -            final GroupValidationContext<ConstraintValidationListener<T>>
> context =
> -                  createContext(factoryContext.getMetaBeanFinder()
> -                        .findForClass(object.getClass()), object,
> (Class<T>)object.getClass(), groupArray);
> -            final ConstraintValidationListener result =
> context.getListener();
> -            final Groups groups = context.getGroups();
> -            // 1. process groups
> -            for (Group current : groups.getGroups()) {
> -                context.setCurrentGroup(current);
> -                validateBeanNet(context);
> -            }
> -            // 2. process sequences
> -            for (List<Group> eachSeq : groups.getSequences()) {
> -                for (Group current : eachSeq) {
> -                    context.setCurrentGroup(current);
> -                    validateBeanNet(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 (!result.isEmpty()) break;
> -                }
> -                if (!result.isEmpty()) break;
> +public class ClassValidator extends AbstractBeanValidator implements
> Validator {
> +  protected final ApacheFactoryContext factoryContext;
> +  protected final GroupsComputer groupsComputer = new GroupsComputer();
> +
> +  public ClassValidator(ApacheFactoryContext factoryContext) {
> +//        super(factoryContext.getMetaBeanFinder());
> +    this.factoryContext = factoryContext;
> +  }
> +
> +  /**
> +   * @deprecated provided for backward compatibility
> +   */
> +  public ClassValidator(ApacheValidatorFactory factory) {
> +    this(factory.usingContext());
> +  }
> +
> +  /**
> +   * the metabean finder associated with this validator.
> +   *
> +   * @return a MetaBeanFinder
> +   * @see org.apache.bval.MetaBeanManagerFactory#getFinder()
> +   */
> +  public MetaBeanFinder getMetaBeanFinder() {
> +    return factoryContext.getMetaBeanFinder();
> +  }
> +
> +  /**
> +   * validate all constraints on object
> +   *
> +   * @throws javax.validation.ValidationException
> +   *          if a non recoverable error happens during the validation
> process
> +   */
> +  public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>...
> groupArray) {
> +    if (object == null) throw new IllegalArgumentException("cannot
> validate null");
> +    checkGroups(groupArray);
> +
> +    try {
> +      final GroupValidationContext<ConstraintValidationListener<T>>
> context =
> +          createContext(factoryContext.getMetaBeanFinder()
> +              .findForClass(object.getClass()), object, (Class<T>)
> object.getClass(), groupArray);
> +      final ConstraintValidationListener result = context.getListener();
> +      final Groups groups = context.getGroups();
> +      // 1. process groups
> +      for (Group current : groups.getGroups()) {
> +        context.setCurrentGroup(current);
> +        validateBeanNet(context);
> +      }
> +      // 2. process sequences
> +      for (List<Group> eachSeq : groups.getSequences()) {
> +        for (Group current : eachSeq) {
> +          context.setCurrentGroup(current);
> +          validateBeanNet(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 (!result.isEmpty()) break;
> +        }
> +        if (!result.isEmpty()) break;
> +      }
> +      return result.getConstaintViolations();
> +    } catch (RuntimeException ex) {
> +      throw unrecoverableValidationError(ex, object);
> +    }
> +  }
> +
> +  /**
> +   * Validates a bean and all its cascaded related beans for the currently
> +   * defined group.
> +   * <p/>
> +   * Special code is present to manage the {@link Default} group.
> +   * <p/>
> +   * TODO: More descriptive name and don't override method from
> BeanValidator.
> +   *
> +   * @param vcontext The current context of this validation call.
> +   */
> +  @Override
> +  protected void validateBeanNet(ValidationContext vcontext) {
> +
> +    GroupValidationContext<?> context = (GroupValidationContext<?>)
> vcontext;
> +
> +    // If reached a cascaded bean which is null
> +    if (context.getBean() == null) {
> +      return;
> +    }
> +
> +    // If reached a cascaded bean which has already been validated for the
> current group
> +    if (!context.collectValidated()) {
> +      return;
> +    }
> +
> +
> +    // ### First, validate the bean
> +
> +    // Default is a special case
> +    if (context.getCurrentGroup().isDefault()) {
> +
> +      List<Group> defaultGroups = expandDefaultGroup(context);
> +      final ConstraintValidationListener result =
> (ConstraintValidationListener) context.getListener();
> +
> +      // If the rootBean defines a GroupSequence
> +      if (defaultGroups.size() > 1) {
> +
> +        int numViolations = result.violationsSize();
> +
> +        // Validate the bean for each group in the sequence
> +        Group currentGroup = context.getCurrentGroup();
> +        for (Group each : defaultGroups) {
> +          context.setCurrentGroup(each);
> +          super.validateBean(context);
> +          // Spec 3.4.3 - Stop validation if errors already found
> +          if (result.violationsSize() > numViolations) {
> +            break;
> +          }
> +        }
> +        context.setCurrentGroup(currentGroup);
> +      } else {
> +
> +        // For each class in the hierarchy of classes of rootBean,
> +        // validate the constraints defined in that class according
> +        // to the GroupSequence defined in the same class
> +
> +        // Obtain the full class hierarchy
> +        List<Class<?>> classHierarchy = new ArrayList<Class<?>>();
> +        ClassHelper.fillFullClassHierarchyAsList(classHierarchy,
> context.getMetaBean().getBeanClass());
> +        Class<?> initialOwner = context.getCurrentOwner();
> +
> +        // For each owner in the hierarchy
> +        for (Class<?> owner : classHierarchy) {
> +          context.setCurrentOwner(owner);
> +
> +          int numViolations = result.violationsSize();
> +
> +          // Obtain the group sequence of the owner, and use it for the
> constraints that belong to it
> +          List<Group> ownerDefaultGroups =
> +              context.getMetaBean().getFeature("{GroupSequence:" +
> owner.getCanonicalName() + "}");
> +          for (Group each : ownerDefaultGroups) {
> +            context.setCurrentGroup(each);
> +            super.validateBean(context);
> +            // Spec 3.4.3 - Stop validation if errors already found
> +            if (result.violationsSize() > numViolations) {
> +              break;
>             }
> -            return result.getConstaintViolations();
> -        } catch (RuntimeException ex) {
> -            throw unrecoverableValidationError(ex, object);
> +          }
> +
>         }
> +        context.setCurrentOwner(initialOwner);
> +        context.setCurrentGroup(Group.DEFAULT);
> +
> +      }
> +
> +    }
> +    // if not the default group, proceed as normal
> +    else {
> +      super.validateBean(context);
>     }
>
> -    /**
> -     * Validates a bean and all its cascaded related beans for the
> currently
> -     * defined group.
> -     *
> -     * Special code is present to manage the {@link Default} group.
> -     *
> -     * TODO: More descriptive name and don't override method from
> BeanValidator.
> -     *
> -     * @param ValidationContext
> -     *            The current context of this validation call.
> -     */
> -    @Override
> -    protected void validateBeanNet(ValidationContext vcontext) {
> -
> -        GroupValidationContext<?> context =
> (GroupValidationContext<?>)vcontext;
> -
> -        // If reached a cascaded bean which is null
> -        if ( context.getBean() == null ) {
> -            return;
> -        }
> -
> -        // If reached a cascaded bean which has already been validated for
> the current group
> -        if ( !context.collectValidated() ) {
> -            return;
> -        }
> -
> -
> -        // ### First, validate the bean
> -
> -        // Default is a special case
> -        if ( context.getCurrentGroup().isDefault() ) {
> -
> -            List<Group> defaultGroups = expandDefaultGroup(context);
> -            final ConstraintValidationListener result =
> (ConstraintValidationListener) context.getListener();
> -
> -            // If the rootBean defines a GroupSequence
> -            if ( defaultGroups.size() > 1 ) {
> -
> -                int numViolations = result.violationsSize();
> -
> -                // Validate the bean for each group in the sequence
> -                Group currentGroup = context.getCurrentGroup();
> -                for (Group each : defaultGroups) {
> -                    context.setCurrentGroup(each);
> -                    super.validateBean(context);
> -                    // Spec 3.4.3 - Stop validation if errors already
> found
> -                    if ( result.violationsSize() > numViolations ) {
> -                        break;
> -                    }
> -                }
> -                context.setCurrentGroup(currentGroup);
> -            }
> -            else {
> -
> -                // For each class in the hierarchy of classes of rootBean,
> -                // validate the constraints defined in that class
> according
> -                // to the GroupSequence defined in the same class
> -
> -                // Obtain the full class hierarchy
> -                List<Class<?>> classHierarchy = new ArrayList<Class<?>>();
> -                ClassHelper.fillFullClassHierarchyAsList(classHierarchy,
> context.getMetaBean().getBeanClass());
> -                Class<?> initialOwner = context.getCurrentOwner();
> -
> -                // For each owner in the hierarchy
> -                for ( Class<?> owner : classHierarchy ) {
> -                    context.setCurrentOwner(owner);
> -
> -                    int numViolations = result.violationsSize();
> -
> -                    // Obtain the group sequence of the owner, and use it
> for the constraints that belong to it
> -                    List<Group> ownerDefaultGroups =
> context.getMetaBean().getFeature("{GroupSequence:"+owner.getCanonicalName()+"}");
> -                    for (Group each : ownerDefaultGroups) {
> -                        context.setCurrentGroup(each);
> -                        super.validateBean(context);
> -                        // Spec 3.4.3 - Stop validation if errors already
> found
> -                        if ( result.violationsSize() > numViolations ) {
> -                            break;
> -                        }
> -                    }
> -
> -                }
> -                context.setCurrentOwner(initialOwner);
> -                context.setCurrentGroup(Group.DEFAULT);
> -
> -            }
> -
> -        }
> -        // if not the default group, proceed as normal
> -        else {
> -            super.validateBean(context);
> -        }
> -
> -
> -        // ### Then, the cascaded beans (@Valid)
> -        for (MetaProperty prop : context.getMetaBean().getProperties()) {
> -            validateCascadedBean(context, prop);
> -        }
> -
> +
> +    // ### Then, the cascaded beans (@Valid)
> +    for (MetaProperty prop : context.getMetaBean().getProperties()) {
> +      validateCascadedBean(context, prop);
>     }
>
> -    /**
> -     * TODO: Currently, almost the same code as super.validateRelatedBean,
> but
> -     * as it is being called at a different time, I have explicitly added
> the
> -     * code here with a different method name.
> -     *
> -     * @param context
> -     *            The current context
> -     * @param prop
> -     *            The property to cascade from (in case it is possible).
> -     */
> -    private void validateCascadedBean(GroupValidationContext<?> context,
> MetaProperty prop) {
> -        AccessStrategy[] access =
> prop.getFeature(Features.Property.REF_CASCADE);
> +  }
> +
> +  /**
> +   * TODO: Currently, almost the same code as super.validateRelatedBean,
> but
> +   * as it is being called at a different time, I have explicitly added
> the
> +   * code here with a different method name.
> +   *
> +   * @param context The current context
> +   * @param prop    The property to cascade from (in case it is possible).
> +   */
> +  private void validateCascadedBean(GroupValidationContext<?> context,
> MetaProperty prop) {
> +    AccessStrategy[] access =
> prop.getFeature(Features.Property.REF_CASCADE);
>  //      TODO: Delete, never reached in JSR-303 validations
>  //        if (access == null && prop.getMetaBean() != null) { // single
> property access strategy
>  //            System.out.println("\n\n ### UNEXPECTED REACH ### \n\n");
> @@ -230,367 +239,331 @@ public class ClassValidator extends Bean
>  //            // restore old values in context
>  //            context.moveUp(bean, mbean);
>  //        } else
> -        if (access != null) { // different accesses to relation
> -            // save old values from context
> -            final Object bean = context.getBean();
> -            final MetaBean mbean = context.getMetaBean();
> -            for (AccessStrategy each : access) {
> -                if (isCascadable(context, prop, each)) {
> -                    // modify context state for relationship-target bean
> -                    context.moveDown(prop, each);
> -                    // Now, if the related bean is an instance of
> Map/Array/etc,
> -                    followCascadedConstraint(context);
> -                    // restore old values in context
> -                    context.moveUp(bean, mbean);
> -                }
> -            }
> -        }
> -    }
> -
> -    /**
> -     * Before accessing a related bean (marked with {@link Valid}), the
> -     * validator has to check if it is reachable and cascadable.
> -     *
> -     * @param context
> -     *            The current validation context.
> -     * @param prop
> -     *            The property of the related bean.
> -     * @param access
> -     *            The access strategy used to get the related bean value.
> -     * @return <code>true</code> if the validator can access the related
> bean,
> -     *         <code>false</code> otherwise.
> -     */
> -    private boolean isCascadable(GroupValidationContext<?> context,
> MetaProperty prop, AccessStrategy access) {
> -
> -        PathImpl beanPath = context.getPropertyPath();
> -        NodeImpl node = new NodeImpl(prop.getName());
> -        if (beanPath == null) {
> -            beanPath = PathImpl.create(null);
> -        }
> -        try {
> -            if (!context.getTraversableResolver().isReachable(
> -                    context.getBean(), node,
> -                    context.getRootMetaBean().getBeanClass(), beanPath,
> -                    access.getElementType()))
> -                return false;
> -        } catch (RuntimeException e) {
> -            throw new ValidationException("Error in
> TraversableResolver.isReachable() for " + context.getBean(), e);
> -        }
> -
> -        try {
> -            if (!context.getTraversableResolver().isCascadable(
> -                    context.getBean(), node,
> -                    context.getRootMetaBean().getBeanClass(), beanPath,
> -                    access.getElementType()))
> -                return false;
> -        } catch (RuntimeException e) {
> -            throw new ValidationException("Error
> TraversableResolver.isCascadable() for " + context.getBean(), e);
> -        }
> -
> -        return true;
> -    }
> -
> -    /**
> -     * TODO: Currently almost the same code as super.validateContext, but
> as it
> -     * is being called at a different time, I have explicitly added the
> code
> -     * here with a different method name.
> -     *
> -     * Methods defined in {@link BeanValidator} take care of setting the
> path
> -     * and current bean correctly and call
> -     * {@link #validateBeanNet(ValidationContext)} for each individual
> bean.
> -     *
> -     * @param context
> -     *            The current validation context.
> -     */
> -    private void followCascadedConstraint(GroupValidationContext<?>
> context) {
> -        if ( context.getBean() != null ) {
> -            if (context.getBean() instanceof Map<?, ?>) {
> -                validateMapInContext(context);
> -            } else if (context.getBean() instanceof List<?>) {
> -                validateIteratableInContext(context);
> -            } else if (context.getBean() instanceof Iterable<?>) {
> -                validateNonPositionalIteratableInContext(context);
> -            } else if (context.getBean() instanceof Object[]) {
> -                validateArrayInContext(context);
> -            } else { // to One Bean (or Map like Bean)
> -                validateBeanInContext(context);
> -            }
> -        }
> -    }
> -
> -
> -    /**
> -     * in case of a default group return the list of groups
> -     * for a redefined default GroupSequence
> -     *
> -     * @return null when no in default group or default group sequence not
> redefined
> -     */
> -    private List<Group> expandDefaultGroup(GroupValidationContext context)
> {
> -        if (context.getCurrentGroup().isDefault()) {
> -            // mention if metaBean redefines the default group
> -            List<Group> groupSeq =
> -
>  context.getMetaBean().getFeature(Jsr303Features.Bean.GROUP_SEQUENCE);
> -            if (groupSeq != null) {
> -
>  context.getGroups().assertDefaultGroupSequenceIsExpandable(groupSeq);
> -            }
> -            return groupSeq;
> -        } else {
> -            return null;
> -        }
> -    }
> -
> -    protected RuntimeException
> unrecoverableValidationError(RuntimeException ex,
> -                                                               Object
> object) {
> -        if (ex instanceof UnknownPropertyException) {
> -            // Convert to IllegalArgumentException
> -            return new IllegalArgumentException(ex.getMessage(), ex);
> -        }
> -        else if (ex instanceof ValidationException) {
> -            return ex; // do not wrap specific ValidationExceptions (or
> instances from subclasses)
> -        } else {
> -            return new ValidationException("error during validation of " +
> object, ex);
> -        }
> -    }
> -
> -    /**
> -     * validate all constraints on <code>propertyName</code> property of
> object
> -     *
> -     * @param propertyName - the attribute name, or nested property name
> (e.g. prop[2].subpropA.subpropB)
> -     * @throws javax.validation.ValidationException
> -     *          if a non recoverable error happens
> -     *          during the validation process
> -     */
> -    public <T> Set<ConstraintViolation<T>> validateProperty(T object,
> String propertyName,
> -                                                            Class<?>...
> groups) {
> -        if (object == null) throw new IllegalArgumentException("cannot
> validate null");
> -
> -        checkPropertyName(propertyName);
> -        checkGroups(groups);
> -
> -        try {
> -            MetaBean metaBean =
> -
>  factoryContext.getMetaBeanFinder().findForClass(object.getClass());
> -            GroupValidationContext<ConstraintValidationListener<T>>
> context =
> -                  createContext(metaBean, object,
> (Class<T>)object.getClass(), groups);
> -            ConstraintValidationListener result = context.getListener();
> -            NestedMetaProperty nestedProp = getNestedProperty(metaBean,
> object, propertyName);
> -            context.setMetaProperty(nestedProp.getMetaProperty());
> -            if (nestedProp.isNested()) {
> -                context.setFixedValue(nestedProp.getValue());
> -            } else {
> -                context.setMetaProperty(nestedProp.getMetaProperty());
> -            }
> -            if (context.getMetaProperty() == null) throw new
> IllegalArgumentException(
> -                  "Unknown property " + object.getClass().getName() + "."
> + propertyName);
> -            Groups sequence = context.getGroups();
> -            // 1. process groups
> -            for (Group current : sequence.getGroups()) {
> -                context.setCurrentGroup(current);
> -                validatePropertyInGroup(context);
> -            }
> -            // 2. process sequences
> -            for (List<Group> eachSeq : sequence.getSequences()) {
> -                for (Group current : eachSeq) {
> -                    context.setCurrentGroup(current);
> -                    validatePropertyInGroup(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 (!result.isEmpty()) break;
> -                }
> -                if (!result.isEmpty()) break;
> -            }
> -            return result.getConstaintViolations();
> -        } catch (RuntimeException ex) {
> -            throw unrecoverableValidationError(ex, object);
> -        }
> -    }
> -
> -    private void validatePropertyInGroup(GroupValidationContext context) {
> -        Group currentGroup = context.getCurrentGroup();
> -        List<Group> defaultGroups = expandDefaultGroup(context);
> -        if (defaultGroups != null) {
> -            for (Group each : defaultGroups) {
> -                context.setCurrentGroup(each);
> -                validateProperty(context);
> -                // continue validation, even if errors already found: if
> (!result.isEmpty())
> -            }
> -            context.setCurrentGroup(currentGroup); // restore
> -        } else {
> -            validateProperty(context);
> -        }
> -    }
> -
> -    /**
> -     * find the MetaProperty for the given propertyName,
> -     * which could contain a path, following the path on a given object to
> resolve
> -     * types at runtime from the instance
> -     */
> -    private NestedMetaProperty getNestedProperty(MetaBean metaBean, Object
> t,
> -                                                 String propertyName) {
> -        NestedMetaProperty nested = new NestedMetaProperty(propertyName,
> t);
> -        nested.setMetaBean(metaBean);
> -        nested.parse();
> -        return nested;
> -    }
> -
> -    /**
> -     * validate all constraints on <code>propertyName</code> property
> -     * if the property value is <code>value</code>
> -     *
> -     * @throws javax.validation.ValidationException
> -     *          if a non recoverable error happens
> -     *          during the validation process
> -     */
> -    public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
> beanType,
> -                                                         String
> propertyName, Object value,
> -                                                         Class<?>...
> groups) {
> -
> -        checkBeanType(beanType);
> -        checkPropertyName(propertyName);
> -        checkGroups(groups);
> -
> -        try {
> -            MetaBean metaBean =
> factoryContext.getMetaBeanFinder().findForClass(beanType);
> -            GroupValidationContext<ConstraintValidationListener<T>>
> context =
> -                  createContext(metaBean, null, beanType, groups);
> -            ConstraintValidationListener result = context.getListener();
> -            context.setMetaProperty(
> -                  getNestedProperty(metaBean, null,
> propertyName).getMetaProperty());
> -            context.setFixedValue(value);
> -            Groups sequence = context.getGroups();
> -            // 1. process groups
> -            for (Group current : sequence.getGroups()) {
> -                context.setCurrentGroup(current);
> -                validatePropertyInGroup(context);
> -            }
> -            // 2. process sequences
> -            for (List<Group> eachSeq : sequence.getSequences()) {
> -                for (Group current : eachSeq) {
> -                    context.setCurrentGroup(current);
> -                    validatePropertyInGroup(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 (!result.isEmpty()) break;
> -                }
> -                if (!result.isEmpty()) break;
> -            }
> -            return result.getConstaintViolations();
> -        } catch (RuntimeException ex) {
> -            throw unrecoverableValidationError(ex, value);
> -        }
> -    }
> -
> -    protected <T> GroupValidationContext<ConstraintValidationListener<T>>
> createContext(
> -          MetaBean metaBean, T object, Class<T> objectClass, Class<?>[]
> groups) {
> -        ConstraintValidationListener<T> listener = new
> ConstraintValidationListener<T>(object, objectClass);
> -        GroupValidationContextImpl<ConstraintValidationListener<T>>
> context =
> -              new GroupValidationContextImpl(listener,
> -                    this.factoryContext.getMessageInterpolator(),
> -                    this.factoryContext.getTraversableResolver(),
> metaBean);
> -        context.setBean(object, metaBean);
> -        context.setGroups(groupsComputer.computeGroups(groups));
> -        return context;
> -    }
> -
> -    /**
> -     * Return the descriptor object describing bean constraints
> -     * The returned object (and associated objects including
> ConstraintDescriptors)
> -     * are immutable.
> -     *
> -     * @throws ValidationException if a non recoverable error happens
> -     *                             during the metadata discovery or if
> some
> -     *                             constraints are invalid.
> -     */
> -    public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
> -        if (clazz == null) {
> -            throw new IllegalArgumentException("Class cannot be null");
> -        }
> -        try {
> -            MetaBean metaBean =
> factoryContext.getMetaBeanFinder().findForClass(clazz);
> -            BeanDescriptorImpl edesc =
> -
>  metaBean.getFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR);
> -            if (edesc == null) {
> -                edesc = createBeanDescriptor(metaBean);
> -                metaBean.putFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR,
> edesc);
> -            }
> -            return edesc;
> -        } catch (RuntimeException ex) {
> -            throw new ValidationException("error retrieving constraints
> for " + clazz, ex);
> -        }
> -    }
> -
> -    protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
> -        return new BeanDescriptorImpl(factoryContext, metaBean,
> metaBean.getValidations());
> -    }
> -
> -    /**
> -     * Return an object of the specified type to allow access to the
> -     * provider-specific API.  If the Bean Validation provider
> -     * implementation does not support the specified class, the
> -     * ValidationException is thrown.
> -     *
> -     * @param type the class of the object to be returned.
> -     * @return an instance of the specified class
> -     * @throws ValidationException if the provider does not
> -     *                             support the call.
> -     */
> -    public <T> T unwrap(Class<T> type) {
> -        if (type.isAssignableFrom(getClass())) {
> -            return (T) this;
> -        } else if (!type.isInterface()) {
> -            return SecureActions.newInstance(type, new
> Class[]{ApacheFactoryContext.class},
> -                  new Object[]{factoryContext});
> -        } else {
> -            try {
> -                Class<T> cls = ClassUtils.getClass(type.getName() +
> "Impl");
> -                return SecureActions.newInstance(cls,
> -                      new Class[]{ApacheFactoryContext.class}, new
> Object[]{factoryContext});
> -            } catch (ClassNotFoundException e) {
> -                throw new ValidationException("Type " + type + " not
> supported");
> -            }
> -        }
> -    }
> -
> -    /**
> -     * Checks that beanType is valid according to spec Section 4.1.1 i.
> Throws
> -     * an {@link IllegalArgumentException} if it is not.
> -     *
> -     * @param beanType
> -     *            Bean type to check.
> -     */
> -    private void checkBeanType(Class<?> beanType) {
> -        if (beanType == null) {
> -            throw new IllegalArgumentException("Bean type cannot be
> null.");
> -        }
> -    }
> -
> -    /**
> -     * Checks that the property name is valid according to spec Section
> 4.1.1 i.
> -     * Throws an {@link IllegalArgumentException} if it is not.
> -     *
> -     * @param propertyName
> -     *            Property name to check.
> -     */
> -    private void checkPropertyName(String propertyName) {
> -        if (propertyName == null || propertyName.isEmpty() ) {
> -            throw new IllegalArgumentException("Property path cannot be
> null or empty.");
> -        }
> -    }
> -
> -    /**
> -     * Checks that the groups array is valid according to spec Section
> 4.1.1 i.
> -     * Throws an {@link IllegalArgumentException} if it is not.
> -     *
> -     * @param groups
> -     *            The groups to check.
> -     */
> -    private void checkGroups(Class<?>[] groups) {
> -        if ( groups == null ) {
> -            throw new IllegalArgumentException("Groups cannot be null.");
> -        }
> +    if (access != null) { // different accesses to relation
> +      // save old values from context
> +      final Object bean = context.getBean();
> +      final MetaBean mbean = context.getMetaBean();
> +      for (AccessStrategy each : access) {
> +        if (isCascadable(context, prop, each)) {
> +          // modify context state for relationship-target bean
> +          context.moveDown(prop, each);
> +          // Now, if the related bean is an instance of Map/Array/etc,
> +          validateContext(context);
> +          // restore old values in context
> +          context.moveUp(bean, mbean);
> +        }
> +      }
> +    }
> +  }
> +
> +  /**
> +   * Before accessing a related bean (marked with {@link
> javax.validation.Valid}), the
> +   * validator has to check if it is reachable and cascadable.
> +   *
> +   * @param context The current validation context.
> +   * @param prop    The property of the related bean.
> +   * @param access  The access strategy used to get the related bean
> value.
> +   * @return <code>true</code> if the validator can access the related
> bean,
> +   *         <code>false</code> otherwise.
> +   */
> +  private boolean isCascadable(GroupValidationContext<?> context,
> MetaProperty prop, AccessStrategy access) {
> +
> +    PathImpl beanPath = context.getPropertyPath();
> +    NodeImpl node = new NodeImpl(prop.getName());
> +    if (beanPath == null) {
> +      beanPath = PathImpl.create(null);
> +    }
> +    try {
> +      if (!context.getTraversableResolver().isReachable(
> +          context.getBean(), node,
> +          context.getRootMetaBean().getBeanClass(), beanPath,
> +          access.getElementType()))
> +        return false;
> +    } catch (RuntimeException e) {
> +      throw new ValidationException("Error in
> TraversableResolver.isReachable() for " + context.getBean(), e);
> +    }
> +
> +    try {
> +      if (!context.getTraversableResolver().isCascadable(
> +          context.getBean(), node,
> +          context.getRootMetaBean().getBeanClass(), beanPath,
> +          access.getElementType()))
> +        return false;
> +    } catch (RuntimeException e) {
> +      throw new ValidationException("Error
> TraversableResolver.isCascadable() for " + context.getBean(), e);
> +    }
> +
> +    return true;
> +  }
> +
> +  /**
> +   * in case of a default group return the list of groups
> +   * for a redefined default GroupSequence
> +   *
> +   * @return null when no in default group or default group sequence not
> redefined
> +   */
> +  private List<Group> expandDefaultGroup(GroupValidationContext context) {
> +    if (context.getCurrentGroup().isDefault()) {
> +      // mention if metaBean redefines the default group
> +      List<Group> groupSeq =
> +
>  context.getMetaBean().getFeature(Jsr303Features.Bean.GROUP_SEQUENCE);
> +      if (groupSeq != null) {
> +
>  context.getGroups().assertDefaultGroupSequenceIsExpandable(groupSeq);
> +      }
> +      return groupSeq;
> +    } else {
> +      return null;
> +    }
> +  }
> +
> +  protected RuntimeException unrecoverableValidationError(RuntimeException
> ex,
> +                                                          Object object) {
> +    if (ex instanceof UnknownPropertyException) {
> +      // Convert to IllegalArgumentException
> +      return new IllegalArgumentException(ex.getMessage(), ex);
> +    } else if (ex instanceof ValidationException) {
> +      return ex; // do not wrap specific ValidationExceptions (or
> instances from subclasses)
> +    } else {
> +      return new ValidationException("error during validation of " +
> object, ex);
> +    }
> +  }
> +
> +  /**
> +   * validate all constraints on <code>propertyName</code> property of
> object
> +   *
> +   * @param propertyName - the attribute name, or nested property name
> (e.g. prop[2].subpropA.subpropB)
> +   * @throws javax.validation.ValidationException
> +   *          if a non recoverable error happens
> +   *          during the validation process
> +   */
> +  public <T> Set<ConstraintViolation<T>> validateProperty(T object, String
> propertyName,
> +                                                          Class<?>...
> groups) {
> +    if (object == null) throw new IllegalArgumentException("cannot
> validate null");
> +
> +    checkPropertyName(propertyName);
> +    checkGroups(groups);
> +
> +    try {
> +      MetaBean metaBean =
> +
>  factoryContext.getMetaBeanFinder().findForClass(object.getClass());
> +      GroupValidationContext<ConstraintValidationListener<T>> context =
> +          createContext(metaBean, object, (Class<T>) object.getClass(),
> groups);
> +      ConstraintValidationListener result = context.getListener();
> +      NestedMetaProperty nestedProp = getNestedProperty(metaBean, object,
> propertyName);
> +      context.setMetaProperty(nestedProp.getMetaProperty());
> +      if (nestedProp.isNested()) {
> +        context.setFixedValue(nestedProp.getValue());
> +      } else {
> +        context.setMetaProperty(nestedProp.getMetaProperty());
> +      }
> +      if (context.getMetaProperty() == null) throw new
> IllegalArgumentException(
> +          "Unknown property " + object.getClass().getName() + "." +
> propertyName);
> +      Groups sequence = context.getGroups();
> +      // 1. process groups
> +      for (Group current : sequence.getGroups()) {
> +        context.setCurrentGroup(current);
> +        validatePropertyInGroup(context);
> +      }
> +      // 2. process sequences
> +      for (List<Group> eachSeq : sequence.getSequences()) {
> +        for (Group current : eachSeq) {
> +          context.setCurrentGroup(current);
> +          validatePropertyInGroup(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 (!result.isEmpty()) break;
> +        }
> +        if (!result.isEmpty()) break;
> +      }
> +      return result.getConstaintViolations();
> +    } catch (RuntimeException ex) {
> +      throw unrecoverableValidationError(ex, object);
> +    }
> +  }
> +
> +  private void validatePropertyInGroup(GroupValidationContext context) {
> +    Group currentGroup = context.getCurrentGroup();
> +    List<Group> defaultGroups = expandDefaultGroup(context);
> +    if (defaultGroups != null) {
> +      for (Group each : defaultGroups) {
> +        context.setCurrentGroup(each);
> +        validateProperty(context);
> +        // continue validation, even if errors already found: if
> (!result.isEmpty())
> +      }
> +      context.setCurrentGroup(currentGroup); // restore
> +    } else {
> +      validateProperty(context);
> +    }
> +  }
> +
> +  /**
> +   * find the MetaProperty for the given propertyName,
> +   * which could contain a path, following the path on a given object to
> resolve
> +   * types at runtime from the instance
> +   */
> +  private NestedMetaProperty getNestedProperty(MetaBean metaBean, Object
> t,
> +                                               String propertyName) {
> +    NestedMetaProperty nested = new NestedMetaProperty(propertyName, t);
> +    nested.setMetaBean(metaBean);
> +    nested.parse();
> +    return nested;
> +  }
> +
> +  /**
> +   * validate all constraints on <code>propertyName</code> property
> +   * if the property value is <code>value</code>
> +   *
> +   * @throws javax.validation.ValidationException
> +   *          if a non recoverable error happens
> +   *          during the validation process
> +   */
> +  public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType,
> +                                                       String
> propertyName, Object value,
> +                                                       Class<?>... groups)
> {
> +
> +    checkBeanType(beanType);
> +    checkPropertyName(propertyName);
> +    checkGroups(groups);
> +
> +    try {
> +      MetaBean metaBean =
> factoryContext.getMetaBeanFinder().findForClass(beanType);
> +      GroupValidationContext<ConstraintValidationListener<T>> context =
> +          createContext(metaBean, null, beanType, groups);
> +      ConstraintValidationListener result = context.getListener();
> +      context.setMetaProperty(
> +          getNestedProperty(metaBean, null,
> propertyName).getMetaProperty());
> +      context.setFixedValue(value);
> +      Groups sequence = context.getGroups();
> +      // 1. process groups
> +      for (Group current : sequence.getGroups()) {
> +        context.setCurrentGroup(current);
> +        validatePropertyInGroup(context);
> +      }
> +      // 2. process sequences
> +      for (List<Group> eachSeq : sequence.getSequences()) {
> +        for (Group current : eachSeq) {
> +          context.setCurrentGroup(current);
> +          validatePropertyInGroup(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 (!result.isEmpty()) break;
> +        }
> +        if (!result.isEmpty()) break;
> +      }
> +      return result.getConstaintViolations();
> +    } catch (RuntimeException ex) {
> +      throw unrecoverableValidationError(ex, value);
> +    }
> +  }
> +
> +  protected <T> GroupValidationContext<ConstraintValidationListener<T>>
> createContext(
> +      MetaBean metaBean, T object, Class<T> objectClass, Class<?>[]
> groups) {
> +    ConstraintValidationListener<T> listener = new
> ConstraintValidationListener<T>(object, objectClass);
> +    GroupValidationContextImpl<ConstraintValidationListener<T>> context =
> +        new GroupValidationContextImpl(listener,
> +            this.factoryContext.getMessageInterpolator(),
> +            this.factoryContext.getTraversableResolver(), metaBean);
> +    context.setBean(object, metaBean);
> +    context.setGroups(groupsComputer.computeGroups(groups));
> +    return context;
> +  }
> +
> +  /**
> +   * Return the descriptor object describing bean constraints
> +   * The returned object (and associated objects including
> ConstraintDescriptors)
> +   * are immutable.
> +   *
> +   * @throws ValidationException if a non recoverable error happens
> +   *                             during the metadata discovery or if some
> +   *                             constraints are invalid.
> +   */
> +  public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
> +    if (clazz == null) {
> +      throw new IllegalArgumentException("Class cannot be null");
> +    }
> +    try {
> +      MetaBean metaBean =
> factoryContext.getMetaBeanFinder().findForClass(clazz);
> +      BeanDescriptorImpl edesc =
> +          metaBean.getFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR);
> +      if (edesc == null) {
> +        edesc = createBeanDescriptor(metaBean);
> +        metaBean.putFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR, edesc);
> +      }
> +      return edesc;
> +    } catch (RuntimeException ex) {
> +      throw new ValidationException("error retrieving constraints for " +
> clazz, ex);
> +    }
> +  }
> +
> +  protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
> +    return new BeanDescriptorImpl(factoryContext, metaBean,
> metaBean.getValidations());
> +  }
> +
> +  /**
> +   * Return an object of the specified type to allow access to the
> +   * provider-specific API.  If the Bean Validation provider
> +   * implementation does not support the specified class, the
> +   * ValidationException is thrown.
> +   *
> +   * @param type the class of the object to be returned.
> +   * @return an instance of the specified class
> +   * @throws ValidationException if the provider does not
> +   *                             support the call.
> +   */
> +  public <T> T unwrap(Class<T> type) {
> +    if (type.isAssignableFrom(getClass())) {
> +      return (T) this;
> +    } else if (!type.isInterface()) {
> +      return SecureActions.newInstance(type, new
> Class[]{ApacheFactoryContext.class},
> +          new Object[]{factoryContext});
> +    } else {
> +      try {
> +        Class<T> cls = ClassUtils.getClass(type.getName() + "Impl");
> +        return SecureActions.newInstance(cls,
> +            new Class[]{ApacheFactoryContext.class}, new
> Object[]{factoryContext});
> +      } catch (ClassNotFoundException e) {
> +        throw new ValidationException("Type " + type + " not supported");
> +      }
> +    }
> +  }
> +
> +  /**
> +   * Checks that beanType is valid according to spec Section 4.1.1 i.
> Throws
> +   * an {@link IllegalArgumentException} if it is not.
> +   *
> +   * @param beanType Bean type to check.
> +   */
> +  private void checkBeanType(Class<?> beanType) {
> +    if (beanType == null) {
> +      throw new IllegalArgumentException("Bean type cannot be null.");
> +    }
> +  }
> +
> +  /**
> +   * Checks that the property name is valid according to spec Section
> 4.1.1 i.
> +   * Throws an {@link IllegalArgumentException} if it is not.
> +   *
> +   * @param propertyName Property name to check.
> +   */
> +  private void checkPropertyName(String propertyName) {
> +    if (propertyName == null || propertyName.isEmpty()) {
> +      throw new IllegalArgumentException("Property path cannot be null or
> empty.");
> +    }
> +  }
> +
> +  /**
> +   * Checks that the groups array is valid according to spec Section 4.1.1
> i.
> +   * Throws an {@link IllegalArgumentException} if it is not.
> +   *
> +   * @param groups The groups to check.
> +   */
> +  private void checkGroups(Class<?>[] groups) {
> +    if (groups == null) {
> +      throw new IllegalArgumentException("Groups cannot be null.");
>     }
> +  }
>  }
>
> 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=956871&r1=956870&r2=956871&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 Jun 22 12:58:28 2010
> @@ -45,8 +45,8 @@ class MethodValidatorImpl extends ClassV
>    */
>   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)) {
> +    for (int i = 0; i < factories.length; i++) {
> +      if (factories[i] instanceof Jsr303MetaBeanFactory && !(factories[i]
> instanceof MethodValidatorMetaBeanFactory)) {
>         factories[i] = new MethodValidatorMetaBeanFactory(factoryContext);
>       }
>     }
>
>
>

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

Posted by Carlos Vara <ba...@gmail.com>.
I have merged some little changes and added some comments, but keeping the
inheritance makes it harder to clean the generics/casting problems. I'll
keep thinking on it as I can't find a clean solution for it atm.


On Tue, Jun 22, 2010 at 2:18 PM, Carlos Vara <ba...@gmail.com> wrote:

> Hi Roman,
>
> your solution is better than mine, I was clearing ClassValidator but had
> left BeanValidator almost untouched. Since your solution also cleans
> BeanValidator I think it's better to keep it.
>
> Today I will get your revision and merge my non-conflicting changes
> (javadocs, some little changes in the validating of iterables, etc.).
>
> Regards,
> Carlos
>
> On Tue, Jun 22, 2010 at 2:13 PM, Roman Stumm <ro...@gmx.de> wrote:
>
>> Hello Carlos,
>>
>> I am sorry. I did not mean to cause confusion here. I am finished with
>> this (I did 2 commits). Alternatively you can drop my last 2 commits and use
>> your code, if you think your solution in simpler.
>>
>> Regards,
>>  Roman
>>
>
>

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

Posted by Carlos Vara <ba...@gmail.com>.
Hi Roman,

your solution is better than mine, I was clearing ClassValidator but had
left BeanValidator almost untouched. Since your solution also cleans
BeanValidator I think it's better to keep it.

Today I will get your revision and merge my non-conflicting changes
(javadocs, some little changes in the validating of iterables, etc.).

Regards,
Carlos

On Tue, Jun 22, 2010 at 2:13 PM, Roman Stumm <ro...@gmx.de> wrote:

> Hello Carlos,
>
> I am sorry. I did not mean to cause confusion here. I am finished with this
> (I did 2 commits). Alternatively you can drop my last 2 commits and use your
> code, if you think your solution in simpler.
>
> Regards,
>  Roman
>

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

Posted by Roman Stumm <ro...@gmx.de>.
Hello Carlos,

I am sorry. I did not mean to cause confusion here. I am finished with 
this (I did 2 commits). Alternatively you can drop my last 2 commits and 
use your code, if you think your solution in simpler.

Regards,
  Roman