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 {
}