Revision: 9792
Author: [email protected]
Date: Wed Mar 2 06:32:23 2011
Log: To prevent infinite loops, the Bean Validation implementation must
ignore
the cascading operation if the associated object instance has already been
validated in the current navigation path (starting from the root object).
[JSR 303 TCK Result] 108 of 257 (42.02%) Pass with 22 Failures and 9 Errors.
Review at http://gwt-code-reviews.appspot.com/1367802
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=9792
Modified:
/trunk/user/src/com/google/gwt/validation/client/impl/GwtValidationContext.java
/trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
/trunk/user/test/org/hibernate/jsr303/tck/tests/constraints/groups/GroupGwtTest.java
/trunk/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/GraphNavigationGwtTest.java
=======================================
---
/trunk/user/src/com/google/gwt/validation/client/impl/GwtValidationContext.java
Mon Feb 7 07:41:58 2011
+++
/trunk/user/src/com/google/gwt/validation/client/impl/GwtValidationContext.java
Wed Mar 2 06:32:23 2011
@@ -16,6 +16,8 @@
package com.google.gwt.validation.client.impl;
import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Set;
import javax.validation.MessageInterpolator;
import javax.validation.metadata.BeanDescriptor;
@@ -24,7 +26,11 @@
/**
* Context for a {@link com.google.gwt.validation.client.GwtValidation}.
*
+ * <p>
+ * NOTE: This class is not thread safe.
+ *
* @param <T> the type of the root bean.
+ *
*/
public class GwtValidationContext<T> {
@@ -35,14 +41,36 @@
private final AbstractGwtValidator validator;
/**
- *
+ * The set of validated object.
+ * <p>
+ * This set is shared with and updated by children contexts created by
+ * {@link #append(String)}, {@link #appendIndex(String, int)} and
+ * {@link #appendKey(String, String)}.
*/
+ private final Set<Object> validatedObjects;
+
public GwtValidationContext(T rootBean, BeanDescriptor beanDescriptor,
MessageInterpolator messageInterpolator, AbstractGwtValidator
validator) {
+ this(rootBean, beanDescriptor, messageInterpolator, validator,
+ new HashSet<Object>());
+ }
+
+ private GwtValidationContext(T rootBean, BeanDescriptor beanDescriptor,
+ MessageInterpolator messageInterpolator, AbstractGwtValidator
validator,
+ Set<Object> validatedObjects) {
this.rootBean = rootBean;
this.beanDescriptor = beanDescriptor;
this.messageInterpolator = messageInterpolator;
this.validator = validator;
+ this.validatedObjects = validatedObjects;
+ }
+
+ public final void addValidatedObject(Object o) {
+ validatedObjects.add(o);
+ }
+
+ public final boolean alreadyValidated(Object o) {
+ return validatedObjects.contains(o);
}
/**
@@ -53,7 +81,7 @@
*/
public GwtValidationContext<T> append(String name) {
GwtValidationContext<T> temp = new GwtValidationContext<T>(rootBean,
- beanDescriptor, messageInterpolator, validator);
+ beanDescriptor, messageInterpolator, validator, validatedObjects);
temp.path = path.append(name);
return temp;
}
@@ -66,7 +94,7 @@
*/
public GwtValidationContext<T> appendIndex(String name, int index) {
GwtValidationContext<T> temp = new GwtValidationContext<T>(rootBean,
- beanDescriptor, messageInterpolator, validator);
+ beanDescriptor, messageInterpolator, validator, validatedObjects);
temp.path = path.appendIndex(name, index);
return temp;
}
@@ -79,7 +107,7 @@
*/
public GwtValidationContext<T> appendKey(String name, String key) {
GwtValidationContext<T> temp = new GwtValidationContext<T>(rootBean,
- beanDescriptor, messageInterpolator, validator);
+ beanDescriptor, messageInterpolator, validator, validatedObjects);
temp.path = path.appendKey(name, key);
return temp;
}
=======================================
---
/trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
Wed Mar 2 06:09:17 2011
+++
/trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
Wed Mar 2 06:32:23 2011
@@ -222,7 +222,7 @@
/**
* Gets the best {@link ConstraintValidator}.
- *
+ *
* <p>
* The ConstraintValidator chosen to validate a declared type
* {@code targetType} is the one where the type supported by the
@@ -230,11 +230,11 @@
* no other ConstraintValidator whose supported type is a supertype of
* {@code type} and not a supertype of the chosen ConstraintValidator
* supported type.
- *
+ *
* @param constraint the constraint to find ConstraintValidators for.
* @param targetType The type to find a ConstraintValidator for.
* @return ConstraintValidator
- *
+ *
* @throws UnexpectedTypeException if there is not exactly one maximally
* specific constraint validator for targetType.
*/
@@ -932,6 +932,9 @@
writeNewViolations(sw);
+ // context.addValidatedObject(object);
+ sw.println("context.addValidatedObject(object);");
+
// /// For each group
// TODO(nchalko) handle the sequence in the AbstractValidator
@@ -988,6 +991,7 @@
writeCatchUnexpectedException(sw,
"\"Error validating " + beanHelper.getTypeCanonicalName() + "\"");
+ // }
sw.outdent();
sw.println("}");
}
@@ -1118,11 +1122,11 @@
sw.println("int i = 0;");
// for (Object instance : value) {
- sw.print("for(Object instance : value) {");
+ sw.println("for(Object instance : value) {");
sw.indent();
- // if(instance != null ) {
- sw.println(" if(instance != null ) {");
+ // if(instance != null && !context.alreadyValidated(instance)) {
+ sw.println(" if(instance != null
&& !context.alreadyValidated(instance)) {");
sw.indent();
// violations.addAll(
@@ -1160,11 +1164,12 @@
// for (Entry<?, Type> entry : value.entrySet()) {
sw.print("for(");
sw.print(Entry.class.getCanonicalName());
- sw.print("<?, ?> entry : value.entrySet()) {");
+ sw.println("<?, ?> entry : value.entrySet()) {");
sw.indent();
- // if(entry.getValue() != null ) {
- sw.println(" if(entry.getValue() != null ) {");
+ // if(entry.getValue() != null &&
+ // !context.alreadyValidated(entry.getValue())) {
+ sw.println(" if(entry.getValue() != null
&& !context.alreadyValidated(entry.getValue())) {");
sw.indent();
// violations.addAll(
@@ -1363,10 +1368,19 @@
}
} else {
createBeanHelper(elementClass);
+
+ // if (!context.alreadyValidated(value)) {
+ sw.println(" if (!context.alreadyValidated(value)) {");
+ sw.indent();
+
// violations.addAll(myContext.getValidator().validate(context,
value,
// groups));
sw.print("violations.addAll(");
sw.println("myContext.getValidator().validate(myContext, value,
groups));");
+
+ // }
+ sw.outdent();
+ sw.println("}");
}
// }
=======================================
---
/trunk/user/test/org/hibernate/jsr303/tck/tests/constraints/groups/GroupGwtTest.java
Tue Jan 11 14:19:47 2011
+++
/trunk/user/test/org/hibernate/jsr303/tck/tests/constraints/groups/GroupGwtTest.java
Wed Mar 2 06:32:23 2011
@@ -42,7 +42,6 @@
delegate.testCyclicGroupSequence();
}
- @Failing(issue = 5801)
public void testGroups() {
delegate.testGroups();
}
=======================================
---
/trunk/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/GraphNavigationGwtTest.java
Mon Feb 28 07:12:19 2011
+++
/trunk/user/test/org/hibernate/jsr303/tck/tests/validation/graphnavigation/GraphNavigationGwtTest.java
Wed Mar 2 06:32:23 2011
@@ -53,9 +53,7 @@
delegate.testGraphNavigationDeterminism();
}
- @Failing(issue = 5946)
public void testNoEndlessLoop() {
- fail("Fail early so othe tests pass");
delegate.testNoEndlessLoop();
}
@@ -63,7 +61,6 @@
delegate.testNullReferencesGetIgnored();
}
- @Failing(issue = 5946)
public void testTypeOfContainedValueIsDeterminedAtRuntime() {
delegate.testTypeOfContainedValueIsDeterminedAtRuntime();
}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors