Author: mbenson
Date: Wed Jun 15 23:01:21 2011
New Revision: 1136237

URL: http://svn.apache.org/viewvc?rev=1136237&view=rev
Log:
cascading property validations should work for indexed/keyed properties based 
on their runtime type regardless of whether constraint information exists for 
their parent objects/classes

Modified:
    
incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/provider/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
    
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

Modified: 
incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/provider/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
URL: 
http://svn.apache.org/viewvc/incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/provider/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java?rev=1136237&r1=1136236&r2=1136237&view=diff
==============================================================================
--- 
incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/provider/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
 (original)
+++ 
incubator/bval/sandbox/lang3-work/bval-jsr303-dynamic/provider/src/main/java/org/apache/bval/jsr303/dynamic/DynamicMetaGraphManagerImpl.java
 Wed Jun 15 23:01:21 2011
@@ -38,6 +38,7 @@ import javax.validation.Path;
 import javax.validation.Valid;
 import javax.validation.ValidationException;
 
+import org.apache.bval.DynamicMetaBean;
 import org.apache.bval.MetaBeanFinder;
 import org.apache.bval.jsr303.AnnotationProcessor;
 import org.apache.bval.jsr303.AppendValidationToMeta;
@@ -547,10 +548,21 @@ final class DynamicMetaGraphManagerImpl 
                     rootBean = null;
                     rootMetaBean = initial;
                 } else {
-                    rootMetaBean = validationState.getRootMetaBean();
+                    rootBean = validationState.getRootBean();
+                    MetaBean _rootMetaBean = validationState.getRootMetaBean();
+                    if (_rootMetaBean instanceof DynamicMetaBean) {
+                        // DynamicMetaBean indirectly points here, so consult 
the parent MetaBeanFinder directly:
+                        Class<?> rootType = rootBean == null ? 
_rootMetaBean.getBeanClass() : rootBean.getClass();
+                        rootMetaBean = metaBeanFinder.findForClass(rootType);
+                    } else {
+                        rootMetaBean = _rootMetaBean;
+                    }
                     path = validationState.getPropertyPath();
                     initial = path.isRootPath() ? rootMetaBean : 
metaBeanFinder.findForClass(type);
-                    rootBean = validationState.getRootBean();
+                }
+                if (rootMetaBean == null) {
+                    throw new IllegalStateException(String.format("Cannot 
determine metaBean root from path %s to %s",
+                        path, type));
                 }
                 try {
                     Iterable<Pair<? extends PathImpl, Class<?>>> typedPaths =

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=1136237&r1=1136236&r2=1136237&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
 Wed Jun 15 23:01:21 2011
@@ -705,16 +705,23 @@ public class ClassValidator implements C
         checkGroups(groups);
 
         try {
-            MetaBean objectMetaBean = 
factoryContext.getMetaBeanFinder().findForClass(beanType);
-
-            GroupValidationContext<T> context = createContext(objectMetaBean, 
object, beanType, groups);
+            final MetaBean initialMetaBean = new 
DynamicMetaBean(getMetaBeanFinder());
+            initialMetaBean.setBeanClass(beanType);
+            GroupValidationContext<T> context = createContext(initialMetaBean, 
object, beanType, groups);
             ValidationContextTraversal contextTraversal = 
createValidationContextTraversal(context);
             PathNavigation.navigate(propertyName, contextTraversal);
 
+            if (context.getMetaBean() == null || context.getMetaBean() 
instanceof DynamicMetaBean) {
+                throw new IllegalStateException(String.format("Failed to 
resolve '%s' against %s", propertyName,
+                    beanType));
+            }
             MetaProperty prop = context.getMetaProperty();
             boolean fixed = false;
             if (value != VALIDATE_PROPERTY) {
                 assert !context.getPropertyPath().isRootPath();
+                if (prop == null && value != null) {
+                    
context.setMetaBean(getMetaBeanFinder().findForClass(value.getClass()));
+                }
                 if (!cascade) {
                     //TCK doesn't care what type a property is if there are no 
constraints to validate:
                     FeaturesCapable meta = prop == null ? 
context.getMetaBean() : prop;

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=1136237&r1=1136236&r2=1136237&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
 Wed Jun 15 23:01:21 2011
@@ -20,8 +20,12 @@ package org.apache.bval.jsr303;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Set;
 
 import javax.validation.ConstraintViolation;
@@ -451,6 +455,167 @@ public class ValidationTest extends Test
         Assert.assertEquals(1, iv.size());
     }
 
+    public void testValidateCascadingKeyedElement() throws 
InvocationTargetException, NoSuchMethodException,
+        IllegalAccessException {
+        final String propPath = "[foo]";
+
+        CascadingPropertyValidator v = 
validator.unwrap(CascadingPropertyValidator.class);
+        final Address adr = new Address();
+        @SuppressWarnings("serial")
+        Object map = new HashMap<String, Address>() {
+            {
+                put("foo", adr);
+            }
+        };
+        Country country = new Country();
+        adr.setCity("dark");
+        adr.setCountry(country);
+        Set<ConstraintViolation<Object>> iv = v.validateProperty(map, 
propPath);
+        Assert.assertEquals(1, iv.size()); // null address line 1 (no cascade)
+
+        country.setISO2Code("too_long");
+        iv = v.validateProperty(map, propPath, true);
+        Assert.assertEquals(3, iv.size()); // null address line 1 + null
+        // country.name + too long
+        // country.iso2code
+
+        country.setISO2Code("23");
+        iv = v.validateProperty(map, 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");
+
+        Set<?> iv2 = v.validateValue(map.getClass(), propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country
+
+        value.setCountry(new Country());
+        iv2 = v.validateValue(map.getClass(), propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country.name
+
+        value.getCountry().setName("NWO");
+        iv2 = v.validateValue(map.getClass(), propPath, value, true);
+        Assert.assertEquals(0, iv2.size());
+    }
+
+    @SuppressWarnings("unchecked")
+    public void testValidateCascadingKeyedGenericElement() throws 
InvocationTargetException, NoSuchMethodException,
+        IllegalAccessException {
+        final String propPath = "[foo]";
+
+        CascadingPropertyValidator v = 
validator.unwrap(CascadingPropertyValidator.class);
+        final Address adr = new Address();
+        Object map = new HashMap<String, Address>();
+        ((Map<String, Address>) map).put("foo", adr);
+        Country country = new Country();
+        adr.setCity("dark");
+        adr.setCountry(country);
+        Set<?> iv = v.validateProperty(map, propPath);
+        Assert.assertEquals(1, iv.size()); // null address line 1 (no cascade)
+
+        country.setISO2Code("too_long");
+        iv = v.validateProperty(map, propPath, true);
+        Assert.assertEquals(3, iv.size()); // null address line 1 + null
+        // country.name + too long
+        // country.iso2code
+
+        country.setISO2Code("23");
+        iv = v.validateProperty(map, 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");
+
+        Set<?> iv2 = v.validateValue(Map.class, propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country
+
+        value.setCountry(new Country());
+        iv2 = v.validateValue(Map.class, propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country.name
+
+        value.getCountry().setName("NWO");
+        iv2 = v.validateValue(Map.class, propPath, value, true);
+        Assert.assertEquals(0, iv2.size());
+    }
+
+    public void testValidateCascadingIndexedElement() throws 
InvocationTargetException, NoSuchMethodException,
+        IllegalAccessException {
+        final String propPath = "[0]";
+        CascadingPropertyValidator v = 
validator.unwrap(CascadingPropertyValidator.class);
+        Address value = new Address();
+        value.setCity("whatever");
+        value.setAddressline1("1 address line");
+        Set<ConstraintViolation<Address[]>> iv;
+        Address[] array = { value };
+        iv = v.validateProperty(array, propPath, true);
+        Assert.assertEquals(1, iv.size()); // null country
+
+        value.setCountry(new Country());
+        iv = v.validateProperty(array, propPath, true);
+        Assert.assertEquals(1, iv.size()); // null country.name
+
+        value.getCountry().setName("NWO");
+        iv = v.validateProperty(array, propPath, true);
+        Assert.assertEquals(0, iv.size());
+
+        value = new Address();
+        value.setCity("whatever");
+        value.setAddressline1("1 address line");
+        Set<?> iv2;
+        iv2 = v.validateValue(array.getClass(), propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country
+
+        value.setCountry(new Country());
+        iv2 = v.validateValue(array.getClass(), propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country.name
+
+        value.getCountry().setName("NWO");
+        iv2 = v.validateValue(array.getClass(), propPath, value, true);
+        Assert.assertEquals(0, iv2.size());
+    }
+
+    public void testValidateCascadingIndexedGenericElement() throws 
InvocationTargetException, NoSuchMethodException,
+    IllegalAccessException {
+        final String propPath = "[0]";
+        CascadingPropertyValidator v = 
validator.unwrap(CascadingPropertyValidator.class);
+        Address value = new Address();
+        value.setCity("whatever");
+        value.setAddressline1("1 address line");
+        Set<?> iv;
+        Object list = Collections.singletonList(value);
+        iv = v.validateProperty(list, propPath, true);
+        Assert.assertEquals(1, iv.size()); // null country
+        
+        value.setCountry(new Country());
+        iv = v.validateProperty(list, propPath, true);
+        Assert.assertEquals(1, iv.size()); // null country.name
+        
+        value.getCountry().setName("NWO");
+        iv = v.validateProperty(list, propPath, true);
+        Assert.assertEquals(0, iv.size());
+        
+        value = new Address();
+        value.setCity("whatever");
+        value.setAddressline1("1 address line");
+        Set<?> iv2;
+        iv2 = v.validateValue(List.class, propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country
+        
+        value.setCountry(new Country());
+        iv2 = v.validateValue(List.class, propPath, value, true);
+        Assert.assertEquals(1, iv2.size()); // null country.name
+        
+        value.getCountry().setName("NWO");
+        iv2 = v.validateValue(List.class, propPath, value, true);
+        Assert.assertEquals(0, iv2.size());
+    }
+    
     public interface Foo {
     }
 


Reply via email to