incubator-bval-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mben...@apache.org
Subject svn commit: r993503 - in /incubator/bval/sandbox/lang3-work/bval-jsr303/src: main/java/ main/java/org/apache/bval/jsr303/ test/java/org/apache/bval/jsr303/
Date Tue, 07 Sep 2010 19:47:07 GMT
Author: mbenson
Date: Tue Sep  7 19:47:07 2010
New Revision: 993503

URL: http://svn.apache.org/viewvc?rev=993503&view=rev
Log:
add CascadingPropertyValidator interface to allow cascading property/value validations; make
ClassValidator implement this new interface, and test it

Added:
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java
  (with props)
Modified:
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/   (props changed)
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/ClassValidator.java
    incubator/bval/sandbox/lang3-work/bval-jsr303/src/test/java/org/apache/bval/jsr303/ValidationTest.java

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Sep  7 19:47:07 2010
@@ -1 +1 @@
-/incubator/bval/trunk/bval-jsr303/src/main/java:992330-992353,992401,992406,992412,992510
+/incubator/bval/trunk/bval-jsr303/src/main/java:992330-992353,992401,992406,992412,992510,992648,993404-993438

Added: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java
URL: http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java?rev=993503&view=auto
==============================================================================
--- incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java
(added)
+++ incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java
Tue Sep  7 19:47:07 2010
@@ -0,0 +1,69 @@
+/**
+ *  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.jsr303;
+
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Valid;
+import javax.validation.Validator;
+
+/**
+ * Per the bean validation spec, {@link Valid} is not honored by the
+ * {@link #validateProperty(Object, String, Class...)} and
+ * {@link #validateValue(Class, String, Object, Class...)} methods. The
+ * {@link CascadingPropertyValidator} interface thus defines a {@link Validator} that
+ * provides corresponding methods that <em>may</em> honor {@link Valid}.
+ * It should be noted that {@link Validator#validateProperty(Object, String, Class...)}
+ * and {@link Validator#validateValue(Class, String, Object, Class...)} are assumed
+ * semantically equivalent to calling the {@link CascadingPropertyValidator}-defined
+ * methods with <code>cascade == false</code>.
+ * 
+ * @version $Rev$ $Date$
+ */
+public interface CascadingPropertyValidator extends Validator {
+
+    /**
+     * Validates all constraints placed on <code>object</code>'s
+     * <code>propertyName</code> property, with optional validation cascading.
+     * 
+     * @param <T>
+     * @param object
+     * @param propertyName
+     * @param cascade
+     * @param groups
+     * @return the resulting {@link Set} of {@link ConstraintViolation}s.
+     */
+    <T extends Object> java.util.Set<javax.validation.ConstraintViolation<T>>
validateProperty(T object,
+        String propertyName, boolean cascade, java.lang.Class<?>... groups);
+
+    /**
+     * Validates all constraints placed on <code>object</code>'s
+     * <code>propertyName</code> property, with optional validation cascading,
+     * given a hypothetical property <code>value</code>.
+     * 
+     * @param <T>
+     * @param beanType
+     * @param propertyName
+     * @param value
+     * @param cascade
+     * @param groups
+     * @return the resulting {@link Set} of {@link ConstraintViolation}s.
+     */
+    <T extends Object> java.util.Set<javax.validation.ConstraintViolation<T>>
validateValue(
+        java.lang.Class<T> beanType, String propertyName, Object value, boolean cascade,
java.lang.Class<?>... groups);
+}

Propchange: incubator/bval/sandbox/lang3-work/bval-jsr303/src/main/java/org/apache/bval/jsr303/CascadingPropertyValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

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=993503&r1=993502&r2=993503&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
Tue Sep  7 19:47:07 2010
@@ -24,7 +24,6 @@ import java.util.List;
 import java.util.Set;
 import javax.validation.ConstraintViolation;
 import javax.validation.ValidationException;
-import javax.validation.Validator;
 import javax.validation.groups.Default;
 import javax.validation.metadata.BeanDescriptor;
 import org.apache.bval.MetaBeanFinder;
@@ -54,9 +53,9 @@ import org.apache.commons.lang3.ClassUti
  * API class
  * 
  * @author Roman Stumm
- * @author Carlos Vara <br/>
+ * @author Carlos Vara
  */
-public class ClassValidator implements Validator {
+public class ClassValidator implements CascadingPropertyValidator {
     /**
      * {@link ApacheFactoryContext} used
      */
@@ -66,8 +65,7 @@ public class ClassValidator implements V
      */
     protected final GroupsComputer groupsComputer = new GroupsComputer();
 
-    private final NestedPathNavigator nestedPathNavigator =
-        new NestedPathNavigator();
+    private final NestedPathNavigator nestedPathNavigator = new NestedPathNavigator();
 
     /**
      * Create a new ClassValidator instance.
@@ -120,8 +118,7 @@ public class ClassValidator implements V
      */
     // @Override - not allowed in 1.5 for Interface methods
     @SuppressWarnings("unchecked")
-    public <T> Set<ConstraintViolation<T>> validate(T object,
-        Class<?>... groups) {
+    public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>...
groups) {
         if (object == null)
             throw new IllegalArgumentException("cannot validate null");
         checkGroups(groups);
@@ -129,13 +126,10 @@ public class ClassValidator implements V
         try {
 
             Class<T> objectClass = (Class<T>) object.getClass();
-            MetaBean objectMetaBean =
-                factoryContext.getMetaBeanFinder().findForClass(objectClass);
+            MetaBean objectMetaBean = factoryContext.getMetaBeanFinder().findForClass(objectClass);
 
-            final GroupValidationContext<T> context =
-                createContext(objectMetaBean, object, objectClass, groups);
-            final ConstraintValidationListener<T> result =
-                context.getListener();
+            final GroupValidationContext<T> context = createContext(objectMetaBean,
object, objectClass, groups);
+            final ConstraintValidationListener<T> result = context.getListener();
             final Groups sequence = context.getGroups();
 
             // 1. process groups
@@ -189,9 +183,17 @@ public class ClassValidator implements V
      *             process
      */
     // @Override - not allowed in 1.5 for Interface methods
-    @SuppressWarnings("unchecked")
-    public <T> Set<ConstraintViolation<T>> validateProperty(T object,
-        String propertyName, Class<?>... groups) {
+    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String
propertyName, Class<?>... groups) {
+        return validateProperty(object, propertyName, false, groups);
+
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String
propertyName, boolean cascade,
+        Class<?>... groups) {
+
         if (object == null)
             throw new IllegalArgumentException("cannot validate null");
 
@@ -199,13 +201,11 @@ public class ClassValidator implements V
         checkGroups(groups);
 
         try {
-
+            @SuppressWarnings("unchecked")
             Class<T> objectClass = (Class<T>) object.getClass();
-            MetaBean objectMetaBean =
-                factoryContext.getMetaBeanFinder().findForClass(objectClass);
+            MetaBean objectMetaBean = factoryContext.getMetaBeanFinder().findForClass(objectClass);
 
-            GroupValidationContext<T> context =
-                createContext(objectMetaBean, object, objectClass, groups);
+            GroupValidationContext<T> context = createContext(objectMetaBean, object,
objectClass, groups);
             ConstraintValidationListener<T> result = context.getListener();
             nestedPathNavigator.navigate(context, propertyName);
             Groups sequence = context.getGroups();
@@ -213,14 +213,22 @@ public class ClassValidator implements V
             // 1. process groups
             for (Group current : sequence.getGroups()) {
                 context.setCurrentGroup(current);
-                validatePropertyInGroup(context);
+                if (cascade) {
+                    validateBeanNet(context);
+                } else {
+                    validatePropertyInGroup(context);
+                }
             }
 
             // 2. process sequences
             for (List<Group> eachSeq : sequence.getSequences()) {
                 for (Group current : eachSeq) {
                     context.setCurrentGroup(current);
-                    validatePropertyInGroup(context);
+                    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
@@ -268,33 +276,50 @@ public class ClassValidator implements V
      *             process
      */
     // @Override - not allowed in 1.5 for Interface methods
-    public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
beanType,
-        String propertyName, Object value, Class<?>... groups) {
+    public <T> Set<ConstraintViolation<T>> validateValue(Class<T>
beanType, String propertyName, Object value,
+        Class<?>... groups) {
+        return validateValue(beanType, propertyName, value, false, groups);
+    }
 
+    /**
+     * {@inheritDoc}
+     */
+    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);
+            MetaBean metaBean = factoryContext.getMetaBeanFinder().findForClass(beanType);
+            GroupValidationContext<T> context = createContext(metaBean, null, beanType,
groups);
             ConstraintValidationListener<T> result = context.getListener();
             nestedPathNavigator.navigate(context, propertyName);
-            context.setFixedValue(value);
+            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);
-                validatePropertyInGroup(context);
+                if (cascade) {
+                    validateBeanNet(context);
+                } else {
+                    validatePropertyInGroup(context);
+                }
             }
             // 2. process sequences
             for (List<Group> eachSeq : sequence.getSequences()) {
                 for (Group current : eachSeq) {
                     context.setCurrentGroup(current);
-                    validatePropertyInGroup(context);
+                    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
@@ -333,18 +358,15 @@ public class ClassValidator implements V
             throw new IllegalArgumentException("Class cannot be null");
         }
         try {
-            MetaBean metaBean =
-                factoryContext.getMetaBeanFinder().findForClass(clazz);
-            BeanDescriptorImpl edesc =
-                metaBean.getFeature(Jsr303Features.Bean.BEAN_DESCRIPTOR);
+            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);
+            throw new ValidationException("error retrieving constraints for " + clazz, ex);
         }
     }
 
@@ -368,20 +390,16 @@ public class ClassValidator implements V
             @SuppressWarnings("unchecked")
             final T result = (T) this;
             return result;
-        } else if (!(type.isInterface() || Modifier.isAbstract(type
-            .getModifiers()))) {
-            return SecureActions.newInstance(type,
-                new Class[] { ApacheFactoryContext.class },
+        } else if (!(type.isInterface() || Modifier.isAbstract(type.getModifiers()))) {
+            return SecureActions.newInstance(type, new Class[] { ApacheFactoryContext.class
},
                 new Object[] { factoryContext });
         } else {
             try {
                 Class<?> cls = ClassUtils.getClass(type.getName() + "Impl");
                 if (type.isAssignableFrom(cls)) {
                     @SuppressWarnings("unchecked")
-                    final Class<? extends T> implClass =
-                        (Class<? extends T>) cls;
-                    return SecureActions.newInstance(implClass,
-                        new Class[] { ApacheFactoryContext.class },
+                    final Class<? extends T> implClass = (Class<? extends T>)
cls;
+                    return SecureActions.newInstance(implClass, new Class[] { ApacheFactoryContext.class
},
                         new Object[] { factoryContext });
                 }
             } catch (ClassNotFoundException e) {
@@ -422,8 +440,7 @@ public class ClassValidator implements V
         if (context.getCurrentGroup().isDefault()) {
 
             List<Group> defaultGroups = expandDefaultGroup(context);
-            final ConstraintValidationListener<?> result =
-                (ConstraintValidationListener<?>) context.getListener();
+            final ConstraintValidationListener<?> result = (ConstraintValidationListener<?>)
context.getListener();
 
             // If the rootBean defines a GroupSequence
             if (defaultGroups.size() > 1) {
@@ -449,8 +466,7 @@ public class ClassValidator implements V
 
                 // Obtain the full class hierarchy
                 List<Class<?>> classHierarchy = new ArrayList<Class<?>>();
-                ClassHelper.fillFullClassHierarchyAsList(classHierarchy,
-                    context.getMetaBean().getBeanClass());
+                ClassHelper.fillFullClassHierarchyAsList(classHierarchy, context.getMetaBean().getBeanClass());
                 Class<?> initialOwner = context.getCurrentOwner();
 
                 // For each owner in the hierarchy
@@ -462,8 +478,7 @@ public class ClassValidator implements V
                     // 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() + "}");
+                        context.getMetaBean().getFeature("{GroupSequence:" + owner.getCanonicalName()
+ "}");
                     for (Group each : ownerDefaultGroups) {
                         context.setCurrentGroup(each);
                         ValidationHelper.validateBean(context);
@@ -501,10 +516,8 @@ public class ClassValidator implements V
      * @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);
+    private void validateCascadedBean(GroupValidationContext<?> context, MetaProperty
prop) {
+        AccessStrategy[] access = prop.getFeature(Features.Property.REF_CASCADE);
         if (access != null) { // different accesses to relation
             // save old values from context
             final Object bean = context.getBean();
@@ -514,9 +527,8 @@ public class ClassValidator implements V
                     // modify context state for relationship-target bean
                     context.moveDown(prop, each);
                     // Now, if the related bean is an instance of Map/Array/etc,
-                    ValidationHelper.validateContext(context,
-                        new Jsr303ValidationCallback(context),
-                        treatMapsLikeBeans);
+                    ValidationHelper
+                        .validateContext(context, new Jsr303ValidationCallback(context),
treatMapsLikeBeans);
                     // restore old values in context
                     context.moveUp(bean, mbean);
                 }
@@ -538,8 +550,7 @@ public class ClassValidator implements V
      * @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) {
+    private boolean isCascadable(GroupValidationContext<?> context, MetaProperty prop,
AccessStrategy access) {
 
         PathImpl beanPath = context.getPropertyPath();
         NodeImpl node = new NodeImpl(prop.getName());
@@ -547,27 +558,19 @@ public class ClassValidator implements V
             beanPath = PathImpl.create(null);
         }
         try {
-            if (!context.getTraversableResolver().isReachable(
-                context.getBean(), node,
-                context.getRootMetaBean().getBeanClass(), beanPath,
-                access.getElementType()))
+            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);
+            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()))
+            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);
+            throw new ValidationException("Error TraversableResolver.isCascadable() for "
+ context.getBean(), e);
         }
 
         return true;
@@ -583,12 +586,9 @@ public class ClassValidator implements V
     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);
+            List<Group> groupSeq = context.getMetaBean().getFeature(Jsr303Features.Bean.GROUP_SEQUENCE);
             if (groupSeq != null) {
-                context.getGroups().assertDefaultGroupSequenceIsExpandable(
-                    groupSeq);
+                context.getGroups().assertDefaultGroupSequenceIsExpandable(groupSeq);
             }
             return groupSeq;
         } else {
@@ -603,8 +603,7 @@ public class ClassValidator implements V
      * @param object
      * @return a {@link RuntimeException} of the appropriate type
      */
-    protected static RuntimeException unrecoverableValidationError(
-        RuntimeException ex, Object object) {
+    protected static RuntimeException unrecoverableValidationError(RuntimeException ex, Object
object) {
         if (ex instanceof UnknownPropertyException) {
             // Convert to IllegalArgumentException
             return new IllegalArgumentException(ex.getMessage(), ex);
@@ -612,24 +611,38 @@ public class ClassValidator implements V
             return ex; // do not wrap specific ValidationExceptions (or
             // instances from subclasses)
         } else {
-            return new ValidationException("error during validation of "
-                + object, ex);
+            return new ValidationException("error during validation of " + object, ex);
         }
     }
 
-    private void validatePropertyInGroup(GroupValidationContext<?> context) {
+    private void validatePropertyInGroup(final GroupValidationContext<?> context) {
+        final Runnable helper;
+        if (context.getMetaProperty() == null) {
+            helper = new Runnable() {
+                
+                public void run() {
+                    ValidationHelper.validateBean(context);
+                }
+            };
+        } else {
+            helper = new Runnable() {
+                
+                public void run() {
+                    ValidationHelper.validateProperty(context);
+                }
+            };
+        }
         Group currentGroup = context.getCurrentGroup();
         List<Group> defaultGroups = expandDefaultGroup(context);
         if (defaultGroups != null) {
             for (Group each : defaultGroups) {
                 context.setCurrentGroup(each);
-                ValidationHelper.validateProperty(context);
-                // continue validation, even if errors already found: if
-                // (!result.isEmpty())
+                helper.run();
+                // continue validation, even if errors already found
             }
             context.setCurrentGroup(currentGroup); // restore
         } else {
-            ValidationHelper.validateProperty(context);
+            helper.run();
         }
     }
 
@@ -643,14 +656,12 @@ public class ClassValidator implements V
      * @param groups
      * @return {@link GroupValidationContext} instance
      */
-    protected <T> GroupValidationContext<T> createContext(MetaBean metaBean,
-        T object, Class<T> objectClass, Class<?>[] groups) {
-        ConstraintValidationListener<T> listener =
-            new ConstraintValidationListener<T>(object, objectClass);
+    protected <T> GroupValidationContext<T> createContext(MetaBean metaBean,
T object, Class<T> objectClass,
+        Class<?>[] groups) {
+        ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object,
objectClass);
         GroupValidationContextImpl<T> context =
-            new GroupValidationContextImpl<T>(listener, this.factoryContext
-                .getMessageInterpolator(), this.factoryContext
-                .getTraversableResolver(), metaBean);
+            new GroupValidationContextImpl<T>(listener, this.factoryContext.getMessageInterpolator(),
+                this.factoryContext.getTraversableResolver(), metaBean);
         context.setBean(object, metaBean);
         context.setGroups(groupsComputer.computeGroups(groups));
         return context;
@@ -663,8 +674,7 @@ public class ClassValidator implements V
      * @return {@link BeanDescriptorImpl} instance
      */
     protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
-        return new BeanDescriptorImpl(factoryContext, metaBean, metaBean
-            .getValidations());
+        return new BeanDescriptorImpl(factoryContext, metaBean, metaBean.getValidations());
     }
 
     private boolean treatMapsLikeBeans = false;
@@ -712,8 +722,7 @@ public class ClassValidator implements V
      */
     private void checkPropertyName(String propertyName) {
         if (propertyName == null || propertyName.trim().length() == 0) {
-            throw new IllegalArgumentException(
-                "Property path cannot be null or empty.");
+            throw new IllegalArgumentException("Property path cannot be null or empty.");
         }
     }
 
@@ -735,8 +744,7 @@ public class ClassValidator implements V
      * {@link ClassValidator#validateBeanNet(GroupValidationContext)} with the
      * current context set.
      */
-    protected class Jsr303ValidationCallback implements
-        ValidationHelper.ValidateCallback {
+    protected class Jsr303ValidationCallback implements ValidationHelper.ValidateCallback
{
 
         private final GroupValidationContext<?> context;
 

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=993503&r1=993502&r2=993503&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
Tue Sep  7 19:47:07 2010
@@ -332,6 +332,49 @@ public class ValidationTest extends Test
         Assert.assertEquals(0, iv.size());
     }
 
+    public void testValidateCascadingNestedPropertyPath() throws InvocationTargetException,
NoSuchMethodException,
+        IllegalAccessException {
+        final String propPath = "addresses[0]";
+
+        CascadingPropertyValidator v = getValidator().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(1, iv.size()); // null address line 1 (no cascade)
+
+        country.setISO2Code("too_long");
+        iv = v.validateProperty(author, propPath, true);
+        Assert.assertEquals(3, iv.size()); // null address line 1 + null
+        // country.name + too long
+        // country.iso2code
+
+        country.setISO2Code("23");
+        iv = v.validateProperty(author, propPath, true);
+        Assert.assertEquals(2, iv.size()); // null address line 1 + null
+        // country.name, country.iso2code
+        // fixed
+
+        Address value = new Address();
+        value.setCity("whatever");
+        value.setAddressline1("1 address line");
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(1, iv.size()); // null country
+
+        value.setCountry(new Country());
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(1, iv.size()); // null country.name
+
+        value.getCountry().setName("NWO");
+        iv = v.validateValue(Author.class, propPath, value, true);
+        Assert.assertEquals(0, iv.size());
+    }
+
     public void testMetadataAPI() {
         Validator bookValidator = getValidator();
         BeanDescriptor bookBeanDescriptor =



Mime
View raw message