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

Reply via email to