incubator-bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r1031829 - in /incubator/bval/sandbox/lang3-work: bval-jsr303/src/main/java/org/apache/bval/jsr303/ bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ bval-jsr303/src/test/java/org/apache/bval/jsr303/ bval-jsr303d/src/main/java/org/apac...
Date Fri, 05 Nov 2010 21:46:55 GMT
Author: mbenson
Date: Fri Nov  5 21:46:55 2010
New Revision: 1031829

URL: http://svn.apache.org/viewvc?rev=1031829&view=rev
Log:
cascading property validations was actually validating entire owning bean

Modified:
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ValidationContextTraversal.java
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java
    incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java?rev=1031829&r1=1031828&r2=1031829&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
(original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
Fri Nov  5 21:46:55 2010
@@ -26,6 +26,8 @@ import javax.validation.ConstraintViolat
 import javax.validation.ValidationException;
 import javax.validation.groups.Default;
 import javax.validation.metadata.BeanDescriptor;
+
+import org.apache.bval.DynamicMetaBean;
 import org.apache.bval.MetaBeanFinder;
 import org.apache.bval.jsr303.groups.Group;
 import org.apache.bval.jsr303.groups.Groups;
@@ -42,12 +44,12 @@ import org.apache.bval.model.MetaPropert
 import org.apache.bval.util.AccessStrategy;
 import org.apache.bval.util.ValidationHelper;
 import org.apache.commons.lang3.ClassUtils;
+import org.apache.commons.lang3.ObjectUtils;
 
 // TODO: centralize treatMapsLikeBeans
 
 /**
- * Objects of this class are able to validate bean instances (and the associated
- * object graphs).
+ * Objects of this class are able to validate bean instances (and the associated object graphs).
  * <p>
  * Implementation is thread-safe.
  * <p>
@@ -57,6 +59,12 @@ import org.apache.commons.lang3.ClassUti
  * @author Carlos Vara
  */
 public class ClassValidator implements CascadingPropertyValidator {
+    private static final Object VALIDATE_PROPERTY = new Object() {
+        public String toString() {
+            return "VALIDATE_PROPERTY";
+        }
+    };
+
     /**
      * {@link ApacheFactoryContext} used
      */
@@ -105,16 +113,14 @@ public class ClassValidator implements C
      * @param object
      *            object to validate
      * @param groups
-     *            group or list of groups targeted for validation (default to
-     *            {@link javax.validation.groups.Default})
+     *            group or list of groups targeted for validation (default to {@link javax.validation.groups.Default})
      * 
      * @return constraint violations or an empty Set if none
      * 
      * @throws IllegalArgumentException
      *             if object is null or if null is passed to the varargs groups
      * @throws ValidationException
-     *             if a non recoverable error happens during the validation
-     *             process
+     *             if a non recoverable error happens during the validation process
      */
     // @Override - not allowed in 1.5 for Interface methods
     @SuppressWarnings("unchecked")
@@ -160,27 +166,24 @@ public class ClassValidator implements C
     }
 
     /**
-     * {@inheritDoc} Validates all constraints placed on the property of
-     * <code>object</code> named <code>propertyName</code>.
+     * {@inheritDoc} Validates all constraints placed on the property of <code>object</code>
named
+     * <code>propertyName</code>.
      * 
      * @param object
      *            object to validate
      * @param propertyName
-     *            property to validate (ie field and getter constraints). Nested
-     *            properties may be referenced (e.g. prop[2].subpropA.subpropB)
+     *            property to validate (ie field and getter constraints). Nested properties
may be referenced (e.g.
+     *            prop[2].subpropA.subpropB)
      * @param groups
-     *            group or list of groups targeted for validation (default to
-     *            {@link javax.validation.groups.Default})
+     *            group or list of groups targeted for validation (default to {@link javax.validation.groups.Default})
      * 
      * @return constraint violations or an empty Set if none
      * 
      * @throws IllegalArgumentException
-     *             if <code>object</code> is null, if <code>propertyName</code>
-     *             null, empty or not a valid object property or if null is
-     *             passed to the varargs groups
+     *             if <code>object</code> is null, if <code>propertyName</code>
null, empty or not a valid object
+     *             property or if null is passed to the varargs groups
      * @throws ValidationException
-     *             if a non recoverable error happens during the validation
-     *             process
+     *             if a non recoverable error happens during the validation process
      */
     // @Override - not allowed in 1.5 for Interface methods
     public <T> Set<ConstraintViolation<T>> validateProperty(T object, String
propertyName, Class<?>... groups) {
@@ -197,62 +200,17 @@ public class ClassValidator implements C
         if (object == null)
             throw new IllegalArgumentException("cannot validate null");
 
-        checkPropertyName(propertyName);
-        checkGroups(groups);
-
-        try {
-            @SuppressWarnings("unchecked")
-            Class<T> objectClass = (Class<T>) object.getClass();
-            MetaBean objectMetaBean = factoryContext.getMetaBeanFinder().findForClass(objectClass);
-
-            GroupValidationContext<T> context = createContext(objectMetaBean, object,
objectClass, groups);
-            ConstraintValidationListener<T> result = context.getListener();
-            navigateContextToPath(context, propertyName);
-            Groups sequence = context.getGroups();
-
-            // 1. process groups
-            for (Group current : sequence.getGroups()) {
-                context.setCurrentGroup(current);
-                if (cascade) {
-                    validateBeanNet(context);
-                } else {
-                    validatePropertyInGroup(context);
-                }
-            }
-
-            // 2. process sequences
-            for (List<Group> eachSeq : sequence.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    if (cascade) {
-                        validateBeanNet(context);
-                    } else {
-                        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.getConstraintViolations();
-        } catch (RuntimeException ex) {
-            throw unrecoverableValidationError(ex, object);
-        }
+        @SuppressWarnings("unchecked")
+        Set<ConstraintViolation<T>> result =
+            validateValueImpl((Class<T>) object.getClass(), object, propertyName, VALIDATE_PROPERTY,
cascade, groups);
+        return result;
     }
 
     /**
-     * {@inheritDoc} Validates all constraints placed on the property named
-     * <code>propertyName</code> of the class <code>beanType</code>
would the
-     * property value be <code>value</code>
+     * {@inheritDoc} Validates all constraints placed on the property named <code>propertyName</code>
of the class
+     * <code>beanType</code> would the property value be <code>value</code>
      * <p/>
-     * <code>ConstraintViolation</code> objects return null for
-     * {@link ConstraintViolation#getRootBean()} and
+     * <code>ConstraintViolation</code> objects return null for {@link ConstraintViolation#getRootBean()}
and
      * {@link ConstraintViolation#getLeafBean()}
      * 
      * @param beanType
@@ -262,18 +220,15 @@ public class ClassValidator implements C
      * @param value
      *            property value to validate
      * @param groups
-     *            group or list of groups targeted for validation (default to
-     *            {@link javax.validation.groups.Default})
+     *            group or list of groups targeted for validation (default to {@link javax.validation.groups.Default})
      * 
      * @return constraint violations or an empty Set if none
      * 
      * @throws IllegalArgumentException
-     *             if <code>beanType</code> is null, if
-     *             <code>propertyName</code> null, empty or not a valid object
+     *             if <code>beanType</code> is null, if <code>propertyName</code>
null, empty or not a valid object
      *             property or if null is passed to the varargs groups
      * @throws ValidationException
-     *             if a non recoverable error happens during the validation
-     *             process
+     *             if a non recoverable error happens during the validation process
      */
     // @Override - not allowed in 1.5 for Interface methods
     public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
beanType, String propertyName, Object value,
@@ -286,60 +241,12 @@ public class ClassValidator implements C
      */
     public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
beanType, String propertyName, Object value,
         boolean cascade, Class<?>... groups) {
-        checkBeanType(beanType);
-        checkPropertyName(propertyName);
-        checkGroups(groups);
-
-        try {
-            MetaBean metaBean = factoryContext.getMetaBeanFinder().findForClass(beanType);
-            GroupValidationContext<T> context = createContext(metaBean, null, beanType,
groups);
-            ConstraintValidationListener<T> result = context.getListener();
-            navigateContextToPath(context, propertyName);
-            if (context.getMetaProperty() == null) {
-                context.setBean(value);
-            } else {
-                context.setFixedValue(value);
-            }
-            Groups sequence = context.getGroups();
-
-            // 1. process groups
-            for (Group current : sequence.getGroups()) {
-                context.setCurrentGroup(current);
-                if (cascade) {
-                    validateBeanNet(context);
-                } else {
-                    validatePropertyInGroup(context);
-                }
-            }
-            // 2. process sequences
-            for (List<Group> eachSeq : sequence.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-                    if (cascade) {
-                        validateBeanNet(context);
-                    } else {
-                        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.getConstraintViolations();
-        } catch (RuntimeException ex) {
-            throw unrecoverableValidationError(ex, value);
-        }
+        return validateValueImpl(checkBeanType(beanType), null, propertyName, value, cascade,
groups);
     }
 
     /**
-     * {@inheritDoc} Return the descriptor object describing bean constraints.
-     * The returned object (and associated objects including
-     * <code>ConstraintDescriptor<code>s) are immutable.
+     * {@inheritDoc} Return the descriptor object describing bean constraints. The returned
object (and associated
+     * objects including <code>ConstraintDescriptor<code>s) are immutable.
      * 
      * @param clazz
      *            class or interface type evaluated
@@ -349,8 +256,7 @@ public class ClassValidator implements C
      * @throws IllegalArgumentException
      *             if clazz is null
      * @throws ValidationException
-     *             if a non recoverable error happens during the metadata
-     *             discovery or if some constraints are invalid.
+     *             if a non recoverable error happens during the metadata discovery or if
some constraints are invalid.
      */
     // @Override - not allowed in 1.5 for Interface methods
     public BeanDescriptor getConstraintsForClass(Class<?> clazz) {
@@ -371,9 +277,8 @@ public class ClassValidator implements C
     }
 
     /**
-     * {@inheritDoc} Return an instance of the specified type allowing access to
-     * provider-specific APIs. If the Bean Validation provider implementation
-     * does not support the specified class, <code>ValidationException</code>
is
+     * {@inheritDoc} Return an instance of the specified type allowing access to provider-specific
APIs. If the Bean
+     * Validation provider implementation does not support the specified class, <code>ValidationException</code>
is
      * thrown.
      * 
      * @param type
@@ -412,8 +317,7 @@ public class ClassValidator implements C
     // -------------------------------------------------------------------
 
     /**
-     * Validates a bean and all its cascaded related beans for the currently
-     * defined group.
+     * 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.
      * 
@@ -443,7 +347,7 @@ public class ClassValidator implements C
             final ConstraintValidationListener<?> result = (ConstraintValidationListener<?>)
context.getListener();
 
             // If the rootBean defines a GroupSequence
-            if (defaultGroups.size() > 1) {
+            if (defaultGroups != null && defaultGroups.size() > 1) {
 
                 int numViolations = result.violationsSize();
 
@@ -508,8 +412,7 @@ public class ClassValidator implements C
     }
 
     /**
-     * Checks if the the meta property <code>prop</code> defines a cascaded
-     * bean, and in case it does, validates it.
+     * Checks if the the meta property <code>prop</code> defines a cascaded bean,
and in case it does, validates it.
      * 
      * @param context
      *            The current validation context.
@@ -537,8 +440,7 @@ public class ClassValidator implements C
     }
 
     /**
-     * Before accessing a related bean (marked with
-     * {@link javax.validation.Valid}), the validator has to check if it is
+     * Before accessing a related bean (marked with {@link javax.validation.Valid}), the
validator has to check if it is
      * reachable and cascadable.
      * 
      * @param context
@@ -547,8 +449,7 @@ public class ClassValidator implements C
      *            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.
+     * @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) {
 
@@ -577,11 +478,9 @@ public class ClassValidator implements C
     }
 
     /**
-     * in case of a default group return the list of groups for a redefined
-     * default GroupSequence
+     * 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
+     * @return null when no in default group or default group sequence not redefined
      */
     private List<Group> expandDefaultGroup(GroupValidationContext<?> context)
{
         if (context.getCurrentGroup().isDefault()) {
@@ -712,21 +611,22 @@ public class ClassValidator implements C
     }
 
     /**
-     * Checks that beanType is valid according to spec Section 4.1.1 i. Throws
-     * an {@link IllegalArgumentException} if it is not.
+     * 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) {
+    private <T> Class<T> checkBeanType(Class<T> beanType) {
         if (beanType == null) {
             throw new IllegalArgumentException("Bean type cannot be null.");
         }
+        return beanType;
     }
 
     /**
-     * Checks that the property name is valid according to spec Section 4.1.1 i.
-     * Throws an {@link IllegalArgumentException} if it is not.
+     * 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.
@@ -738,8 +638,8 @@ public class ClassValidator implements C
     }
 
     /**
-     * Checks that the groups array is valid according to spec Section 4.1.1 i.
-     * Throws an {@link IllegalArgumentException} if it is not.
+     * 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.
@@ -751,9 +651,8 @@ public class ClassValidator implements C
     }
 
     /**
-     * Dispatches a call from {@link #validate()} to
-     * {@link ClassValidator#validateBeanNet(GroupValidationContext)} with the
-     * current context set.
+     * Dispatches a call from {@link #validate()} to {@link ClassValidator#validateBeanNet(GroupValidationContext)}
with
+     * the current context set.
      */
     protected class Jsr303ValidationCallback implements ValidationHelper.ValidateCallback
{
 
@@ -770,11 +669,118 @@ public class ClassValidator implements C
     }
 
     /**
-     * Navigate the specified {@link GroupValidationContext} to <code>propertyPath</code>.
+     * Create a {@link ValidationContextTraversal} instance for this {@link ClassValidator}.
+     * 
      * @param validationContext
-     * @param propertyPath
+     * @return {@link ValidationContextTraversal}
+     */
+    protected ValidationContextTraversal createValidationContextTraversal(GroupValidationContext<?>
validationContext) {
+        return new ValidationContextTraversal(validationContext);
+    }
+
+    /**
+     * Implement {@link #validateProperty(Object, String, boolean, Class...)} and
+     * {@link #validateValue(Class, String, Object, boolean, Class...)}.
+     * 
+     * @param <T>
+     * @param beanType
+     * @param object
+     * @param propertyName
+     * @param value
+     * @param cascade
+     * @param groups
+     * @return {@link ConstraintViolation} {@link Set}
      */
-    protected <T> void navigateContextToPath(GroupValidationContext<T> validationContext,
String propertyPath) {
-        PathNavigation.navigate(propertyPath, new ValidationContextTraversal(validationContext));
+    private <T> Set<ConstraintViolation<T>> validateValueImpl(Class<T>
beanType, T object, String propertyName,
+        Object value, boolean cascade, Class<?>... groups) {
+
+        assert (object == null) ^ (value == VALIDATE_PROPERTY);
+        checkPropertyName(propertyName);
+        checkGroups(groups);
+
+        try {
+            MetaBean objectMetaBean = factoryContext.getMetaBeanFinder().findForClass(beanType);
+
+            GroupValidationContext<T> context = createContext(objectMetaBean, object,
beanType, groups);
+            ValidationContextTraversal contextTraversal = createValidationContextTraversal(context);
+            PathNavigation.navigate(propertyName, contextTraversal);
+
+            MetaProperty prop = context.getMetaProperty();
+            boolean fixed = false;
+            if (value != VALIDATE_PROPERTY) {
+                if (prop == null) {
+                    context.setBean(value);
+                } else {
+                    context.setFixedValue(value);
+                    fixed = true;
+                }
+            }
+            Object bean = context.getBean();
+
+            ConstraintValidationListener<T> result = context.getListener();
+            Groups sequence = context.getGroups();
+
+            // 1. process groups
+
+            for (Group current : sequence.getGroups()) {
+                context.setCurrentGroup(current);
+
+                if (!cascade || prop != null) {
+                    validatePropertyInGroup(context);
+                }
+                if (cascade) {
+                    contextTraversal.moveDownIfNecessary();
+                    if (context.getMetaBean() instanceof DynamicMetaBean) {
+                        context.setMetaBean(context.getMetaBean().resolveMetaBean(
+                            ObjectUtils.defaultIfNull(context.getBean(), contextTraversal.getRawType())));
+                    }
+                    validateBeanNet(context);
+                    if (prop != null) {
+                        context.moveUp(bean, prop.getParentMetaBean());
+                        if (fixed) {
+                            context.setFixedValue(value);
+                        }
+                    }
+                }
+            }
+
+            // 2. process sequences
+
+            int groupViolations = result.getConstraintViolations().size();
+
+            outer: for (List<Group> eachSeq : sequence.getSequences()) {
+                for (Group current : eachSeq) {
+                    context.setCurrentGroup(current);
+
+                    if (!cascade || prop != null) {
+                        validatePropertyInGroup(context);
+                    }
+                    if (cascade) {
+                        contextTraversal.moveDownIfNecessary();
+                        if (context.getMetaBean() instanceof DynamicMetaBean) {
+                            context.setMetaBean(context.getMetaBean().resolveMetaBean(
+                                ObjectUtils.defaultIfNull(context.getBean(), contextTraversal.getRawType())));
+                        }
+                        validateBeanNet(context);
+                        if (prop != null) {
+                            context.moveUp(bean, prop.getParentMetaBean());
+                            if (fixed) {
+                                context.setFixedValue(value);
+                            }
+                        }
+                    }
+                    /**
+                     * 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.getConstraintViolations().size() > groupViolations)
+                        break outer;
+                }
+            }
+            return result.getConstraintViolations();
+        } catch (RuntimeException ex) {
+            throw unrecoverableValidationError(ex, ObjectUtils.defaultIfNull(object, value));
+        }
     }
+
 }

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ValidationContextTraversal.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ValidationContextTraversal.java?rev=1031829&r1=1031828&r2=1031829&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ValidationContextTraversal.java
(original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/util/ValidationContextTraversal.java
Fri Nov  5 21:46:55 2010
@@ -57,7 +57,7 @@ public class ValidationContextTraversal 
         }
     }
 
-    private ValidationContext<?> validationContext;
+    private final ValidationContext<?> validationContext;
     private Type type;
     private Class<?> rawType;
 
@@ -68,6 +68,13 @@ public class ValidationContextTraversal 
      */
     public ValidationContextTraversal(ValidationContext<?> validationContext) {
         this.validationContext = validationContext;
+        init();
+    }
+
+    /**
+     * Initialize from {@link ValidationContext}.
+     */
+    public void init() {
         this.rawType = validationContext.getMetaBean().getBeanClass();
         this.type = this.rawType;
     }
@@ -127,7 +134,7 @@ public class ValidationContextTraversal 
      * 
      * @param validationContext
      */
-    protected void moveDownIfNecessary() {
+    public void moveDownIfNecessary() {
         MetaProperty mp = validationContext.getMetaProperty();
         if (mp != null) {
             if (mp.getMetaBean() == null) {
@@ -156,4 +163,18 @@ public class ValidationContextTraversal 
         throw new UnsupportedOperationException("Cannot navigate a ValidationContext to []");
     }
 
+    /**
+     * @return the type
+     */
+    public Type getType() {
+        return type;
+    }
+    
+    /**
+     * @return the rawType
+     */
+    public Class<?> getRawType() {
+        return rawType;
+    }
+
 }
\ No newline at end of file

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java?rev=1031829&r1=1031828&r2=1031829&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java
(original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java
Fri Nov  5 21:46:55 2010
@@ -339,7 +339,7 @@ public class ValidationTest extends Test
         Assert.assertEquals(0, iv.size());
     }
 
-    public void testValidateCascadingNestedPropertyPath() throws InvocationTargetException,
NoSuchMethodException,
+    public void testValidateCascadingNestedBean() throws InvocationTargetException, NoSuchMethodException,
         IllegalAccessException {
         final String propPath = "addresses[0]";
 
@@ -382,6 +382,46 @@ public class ValidationTest extends Test
         Assert.assertEquals(0, iv.size());
     }
 
+    public void testValidateCascadingNestedProperty() throws InvocationTargetException, NoSuchMethodException,
+        IllegalAccessException {
+        final String propPath = "addresses[0].country";
+
+        CascadingPropertyValidator v = validator.unwrap(CascadingPropertyValidator.class);
+        Author author = new Author();
+        author.setAddresses(new ArrayList<Address>());
+        Address adr = new Address();
+        author.getAddresses().add(adr);
+        Country country = new Country();
+        adr.setCity("dark");
+        adr.setCountry(country);
+
+        Set<ConstraintViolation<Author>> iv = v.validateProperty(author, propPath);
+        Assert.assertEquals(0, iv.size());
+
+        country.setISO2Code("too_long");
+        iv = v.validateProperty(author, propPath, true);
+        Assert.assertEquals(2, iv.size());
+        // country.name + too long
+        // country.iso2code
+
+        country.setISO2Code("23");
+        iv = v.validateProperty(author, propPath, true);
+        Assert.assertEquals(1, iv.size());
+        // country.name, country.iso2code
+
+        Country value = null;
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(1, iv.size()); // null country
+
+        value = new Country();
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(1, iv.size()); // null country.name
+
+        value.setName("NWO");
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(0, iv.size());
+    }
+
     public void testMetadataAPI() {
         BeanDescriptor bookBeanDescriptor = validator.getConstraintsForClass(Book.class);
 

Modified: incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java?rev=1031829&r1=1031828&r2=1031829&view=diff
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java
(original)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303d/src/main/java/org/apache/bval/jsr303/dynamic/DynamicClassValidator.java
Fri Nov  5 21:46:55 2010
@@ -158,7 +158,7 @@ public class DynamicClassValidator exten
                 GroupValidationContext<?> validationContext = createContext(metaBean,
null, metaBean.getBeanClass());
 
                 try {
-                    navigateContextToPath(validationContext, propertyName);
+                    PathNavigation.navigate(propertyName, createValidationContextTraversal(validationContext));
                 } catch (ValidationException e) {
                     return null;
                 }
@@ -254,7 +254,8 @@ public class DynamicClassValidator exten
      * {@inheritDoc}
      */
     @Override
-    protected <T> void navigateContextToPath(GroupValidationContext<T> validationContext,
String propertyPath) {
-        PathNavigation.navigate(propertyPath, new DynamicValidationContextTraversal(validationContext));
+    protected ValidationContextTraversal createValidationContextTraversal(GroupValidationContext<?>
validationContext) {
+        return new DynamicValidationContextTraversal(validationContext);
     }
+
 }



Mime
View raw message