Revision: 9321
Author: [email protected]
Date: Tue Nov 30 13:47:49 2010
Log: Public: Handle fields marked @Valid

Review at http://gwt-code-reviews.appspot.com/1142801

Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=9321

Added:
/trunk/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java
Modified:
/trunk/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java
 /trunk/samples/validationtck/src/org/hibernate/jsr303/tck/Jsr303Tck.gwt.xml
/trunk/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java /trunk/user/src/com/google/gwt/validation/client/impl/ConstraintViolationImpl.java
 /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java
 /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java
/trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java /trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java
 /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java
 /trunk/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java

=======================================
--- /dev/null
+++ /trunk/samples/validation/src/com/google/gwt/sample/validation/shared/Address.java Tue Nov 30 13:47:49 2010
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed 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 com.google.gwt.sample.validation.shared;
+
+import com.google.gwt.user.client.rpc.IsSerializable;
+
+import javax.validation.constraints.NotNull;
+
+/**
+ * Sample address for validation
+ */
+public class Address implements IsSerializable {
+
+  @NotNull
+  public String street;
+
+}
=======================================
--- /trunk/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java Wed Nov 17 04:26:36 2010 +++ /trunk/samples/validation/src/com/google/gwt/sample/validation/shared/Person.java Tue Nov 30 13:47:49 2010
@@ -17,6 +17,7 @@

 import com.google.gwt.user.client.rpc.IsSerializable;

+import javax.validation.Valid;
 import javax.validation.constraints.Max;
 import javax.validation.constraints.NotNull;
 import javax.validation.constraints.Size;
@@ -27,6 +28,9 @@
 @ServerConstraint(groups = ServerGroup.class)
 public class Person implements IsSerializable {

+  @Valid
+  private Address address;
+
   @NotNull
   @Size(min = 4)
   private String name;
@@ -34,6 +38,10 @@
   @Max(999999999)
   private long ssn;

+  public Address getAddress() {
+    return address;
+  }
+
   public String getName() {
     return name;
   }
@@ -41,6 +49,10 @@
   public long getSsn() {
     return ssn;
   }
+
+  public void setAddress(Address address) {
+    this.address = address;
+  }

   public void setName(String name) {
     this.name = name;
=======================================
--- /trunk/samples/validationtck/src/org/hibernate/jsr303/tck/Jsr303Tck.gwt.xml Fri Nov 19 17:25:09 2010 +++ /trunk/samples/validationtck/src/org/hibernate/jsr303/tck/Jsr303Tck.gwt.xml Tue Nov 30 13:47:49 2010
@@ -16,6 +16,8 @@
     <exclude name="tests/constraints/builtinconstraints/" />
     <exclude name="tests/messageinterpolation/" />
     <exclude name="tests/xmlconfiguration/" />
+    <exclude name="tests/validation/UnknownProviderBootstrapTest.java"/>
+    <exclude name="tests/validation/ValidationTest.java"/>
     <exclude name="util/StandaloneContainersImpl.java" />
   </source>
   <super-source path="super" />
=======================================
--- /trunk/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java Fri Oct 8 06:15:38 2010 +++ /trunk/user/src/com/google/gwt/validation/client/impl/ConstraintDescriptorImpl.java Tue Nov 30 13:47:49 2010
@@ -175,4 +175,12 @@
   public boolean isReportAsSingleViolation() {
     return reportAsSingleViolation;
   }
-}
+
+  /**
+ * For debugging only. Do not rely on the format. It can change at any time.
+   */
+  @Override
+  public String toString() {
+    return annotation + " " + attributes;
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/validation/client/impl/ConstraintViolationImpl.java Fri Sep 3 12:24:52 2010 +++ /trunk/user/src/com/google/gwt/validation/client/impl/ConstraintViolationImpl.java Tue Nov 30 13:47:49 2010
@@ -162,4 +162,15 @@
   public Class<T> getRootBeanClass() {
     return rootBeanClass;
   }
-}
+
+  /**
+ * For debugging only. Do not rely on the format. It can change at any time.
+   */
+  @Override
+  public String toString() {
+    return "message= " + message //
+        + ", path= " + propertyPath //
+        + ", invalidValue=" + invalidValue //
+        + " , desc=" + constraintDescriptor;
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java Wed Oct 6 06:53:06 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/AbstractCreator.java Tue Nov 30 13:47:49 2010
@@ -64,6 +64,10 @@

protected abstract void compose(ClassSourceFileComposerFactory composerFactory);

+  protected BeanHelper createBeanHelper(Class<?> clazz) {
+    return BeanHelper.createBeanHelper(clazz, logger, context);
+  }
+
   protected final String getPackage() {
     JPackage serviceIntfPkg = validatorType.getPackage();
String packageName = serviceIntfPkg == null ? "" : serviceIntfPkg.getName();
@@ -73,6 +77,22 @@
   protected abstract void writeClassBody(SourceWriter sourceWriter)
       throws UnableToCompleteException;

+  protected void writeValidatorInstance(SourceWriter sw, BeanHelper bean) {
+    BeanHelper.writeInterface(context, logger, bean);
+    // private final MyBeanValidator myBeanValidator =
+ sw.print("private final " + bean.getFullyQualifiedValidatorName() + " ");
+    sw.print(bean.getValidatorInstanceName());
+    sw.println(" = ");
+    sw.indent();
+    sw.indent();
+
+    // GWT.create(MyBeanValidator
+    sw.println("GWT.create(" + bean.getFullyQualifiedValidatorName()
+        + ".class);");
+    sw.outdent();
+    sw.outdent();
+  }
+
   private String getQualifiedName() {
     String packageName = getPackage();
     return (packageName == "" ? "" : packageName + ".") + getSimpleName();
=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java Mon Nov 15 10:52:58 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/BeanHelper.java Tue Nov 30 13:47:49 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ *
* Licensed 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
@@ -15,8 +15,20 @@
  */
 package com.google.gwt.validation.rebind;

+import com.google.gwt.core.ext.GeneratorContext;
+import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.typeinfo.JClassType;
-
+import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
+import com.google.gwt.user.rebind.SourceWriter;
+import com.google.gwt.validation.client.impl.GwtSpecificValidator;
+
+import java.io.PrintWriter;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.validation.Validation;
+import javax.validation.Validator;
 import javax.validation.metadata.BeanDescriptor;

 /**
@@ -24,12 +36,77 @@
  * validated.
  */
 final class BeanHelper {
+
+ private static final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();
+
+  // stash the map in a ThreadLocal, since each GWT module lives in its own
+  // thread in DevMode
+ private static final ThreadLocal<Map<JClassType, BeanHelper>> threadLocalHelperMap =
+      new ThreadLocal<Map<JClassType, BeanHelper>>() {
+    @Override
+    protected synchronized Map<JClassType, BeanHelper> initialValue() {
+      return new HashMap<JClassType, BeanHelper>();
+    }
+  };
+
+  protected static BeanHelper createBeanHelper(Class<?> clazz,
+      TreeLogger logger, GeneratorContext context) {
+    JClassType beanType = context.getTypeOracle().findType(
+        clazz.getCanonicalName());
+    BeanHelper helper = getBeanHelper(beanType);
+    if (helper == null) {
+      helper = new BeanHelper(beanType,
+          serverSideValidor.getConstraintsForClass(clazz));
+      addBeanHelper(helper);
+      writeInterface(context, logger, helper);
+    }
+    return helper;
+  }
+
+  protected static boolean isClassConstrained(Class<?> clazz) {
+ return serverSideValidor.getConstraintsForClass(clazz).isBeanConstrained();
+  }
+
+  static BeanHelper getBeanHelper(JClassType beanType) {
+    return getBeanHelpers().get(beanType);
+  }
+
+  /**
+ * Write an Empty Interface implementing {...@link GwtSpecificValidator} with
+   * Generic parameter of the bean type.
+   */
+  static void writeInterface(GeneratorContext context, TreeLogger logger,
+      BeanHelper bean) {
+    PrintWriter pw = context.tryCreate(logger, bean.getPackage(),
+        bean.getValidatorName());
+    if (pw != null) {
+      TreeLogger interfaceLogger = logger.branch(TreeLogger.TRACE,
+ "Creating the interface for " + bean.getFullyQualifiedValidatorName());
+
+ ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
+          bean.getPackage(), bean.getValidatorName());
+ factory.addImplementedInterface(GwtSpecificValidator.class.getCanonicalName()
+          + " <" + bean.getTypeCanonicalName() + ">");
+      factory.makeInterface();
+      SourceWriter sw = factory.createSourceWriter(context, pw);
+      sw.commit(interfaceLogger);
+      pw.close();
+    }
+  }
+
+  private static synchronized void addBeanHelper(BeanHelper helper) {
+    threadLocalHelperMap.get().put(helper.getJClass(), helper);
+  }
+
+  private static Map<JClassType, BeanHelper> getBeanHelpers() {
+    return Collections.unmodifiableMap(threadLocalHelperMap.get());
+  }

   private final BeanDescriptor beanDescriptor;

   private final JClassType jClass;
-  public BeanHelper(JClassType jClass,
-      BeanDescriptor beanDescriptor) {
+
+  private BeanHelper(JClassType jClass, BeanDescriptor beanDescriptor) {
     super();
     this.beanDescriptor = beanDescriptor;
     this.jClass = jClass;
@@ -54,6 +131,10 @@
   public String getFullyQualifiedValidatorName() {
     return getPackage() + "." + getValidatorName();
   }
+
+  public JClassType getJClass() {
+    return jClass;
+  }

   public String getPackage() {
     return jClass.getPackage().getName();
@@ -77,7 +158,7 @@
   }

   private String makeJavaSafe(String in) {
-      return in.replaceAll("\\.", "_");
-    }
+    return in.replaceAll("\\.", "_");
+  }

 }
=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java Tue Nov 16 11:22:38 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java Tue Nov 30 13:47:49 2010
@@ -1,12 +1,12 @@
 /*
  * Copyright 2010 Google Inc.
- *
+ *
* Licensed 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
@@ -24,6 +24,7 @@
 import com.google.gwt.core.ext.typeinfo.NotFoundException;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.jjs.ast.JProgram;
+import com.google.gwt.thirdparty.guava.common.collect.Sets;
 import com.google.gwt.thirdparty.guava.common.primitives.Primitives;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
@@ -43,7 +44,6 @@
 import javax.validation.ConstraintValidator;
 import javax.validation.ConstraintViolation;
 import javax.validation.Payload;
-import javax.validation.Validator;
 import javax.validation.metadata.ConstraintDescriptor;
 import javax.validation.metadata.PropertyDescriptor;

@@ -52,89 +52,118 @@
  * <p>
  * This class is not thread safe.
  */
-
 public class GwtSpecificValidatorCreator extends AbstractCreator {

   /**
- * Returns the literal value of an object that is suitable for inclusion in
-     * Java Source code.
-     *
-     * <p>
-     * Supports all types that {...@link Annotation) value can have.
-     *
-     *
- * @throws IllegalArgumentException if the type of the object does not have a java literal form.
-     */
- public static String asLiteral(Object value) throws IllegalArgumentException {
-      Class<?> clazz = value.getClass();
-      JProgram jProgram = new JProgram();
-
-      if (clazz.isArray()) {
-        StringBuilder sb = new StringBuilder();
-        Object[] array = (Object[]) value;
-
- sb.append("new " + clazz.getComponentType().getCanonicalName() + "[] ");
-        sb.append("{");
-        boolean first = true;
-        for (Object object : array) {
-          if (first) {
-            first = false;
-          } else {
-            sb.append(",");
-          }
-          sb.append(asLiteral(object));
-        }
-        sb.append("}");
-        return sb.toString();
-      }
-
-      if (value instanceof Class) {
- return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
-      }
-      if (value instanceof Double) {
- return jProgram.getLiteralDouble(((Double) value).doubleValue()).toSource();
-      }
-      if (value instanceof Integer) {
- return jProgram.getLiteralInt(((Integer) value).intValue()).toSource();
-      }
-      if (value instanceof Long) {
- return jProgram.getLiteralLong(((Long) value).intValue()).toSource();
-      }
-      if (value instanceof String) {
- return '"' + ((String) value).toString().replace("\"", "\\\"") + '"';
-      }
-    // TODO(nchalko) handle the rest of the literal types
-      throw new IllegalArgumentException(value.getClass()
-          + " is can not be represented as a Java Literal.");
-    }
+ * Returns the literal value of an object that is suitable for inclusion in
+   * Java Source code.
+   *
+   * <p>
+   * Supports all types that {...@link Annotation) value can have.
+   *
+   *
+ * @throws IllegalArgumentException if the type of the object does not have a java literal form.
+   */
+ public static String asLiteral(Object value) throws IllegalArgumentException {
+    Class<?> clazz = value.getClass();
+    JProgram jProgram = new JProgram();
+
+    if (clazz.isArray()) {
+      StringBuilder sb = new StringBuilder();
+      Object[] array = (Object[]) value;
+
+ sb.append("new " + clazz.getComponentType().getCanonicalName() + "[] ");
+      sb.append("{");
+      boolean first = true;
+      for (Object object : array) {
+        if (first) {
+          first = false;
+        } else {
+          sb.append(",");
+        }
+        sb.append(asLiteral(object));
+      }
+      sb.append("}");
+      return sb.toString();
+    }
+
+    if (value instanceof Class) {
+      return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
+    }
+    if (value instanceof Double) {
+ return jProgram.getLiteralDouble(((Double) value).doubleValue()).toSource();
+    }
+    if (value instanceof Integer) {
+ return jProgram.getLiteralInt(((Integer) value).intValue()).toSource();
+    }
+    if (value instanceof Long) {
+      return jProgram.getLiteralLong(((Long) value).intValue()).toSource();
+    }
+    if (value instanceof String) {
+      return '"' + ((String) value).toString().replace("\"", "\\\"") + '"';
+    }
+    // TODO(nchalko) handle the rest of the literal types
+    throw new IllegalArgumentException(value.getClass()
+        + " is can not be represented as a Java Literal.");
+  }
+
   private BeanHelper beanHelper;
+  private Set<BeanHelper> beansToValidate = Sets.newHashSet();
   private final JClassType beanType;
+
   private final TypeOracle oracle;

-  private final Validator serverSideValidator;
-
   public GwtSpecificValidatorCreator(JClassType validatorType,
       JClassType beanType, BeanHelper beanHelper, TreeLogger logger,
-      GeneratorContext context, Validator serverSideValidator) {
+      GeneratorContext context) {
     super(context, logger, validatorType);
     this.oracle = context.getTypeOracle();
     this.beanType = beanType;
     this.beanHelper = beanHelper;
-    this.serverSideValidator = serverSideValidator;
   }

-  protected <T> T[] asArray(Collection<?> collection, T[] array) {
+  @Override
+  protected void compose(ClassSourceFileComposerFactory composerFactory) {
+    addImports(composerFactory, GWT.class, GwtBeanDescriptor.class,
+        GwtValidationContext.class, Set.class, HashSet.class,
+        ConstraintViolation.class, Annotation.class);
+ composerFactory.setSuperclass(AbstractGwtSpecificValidator.class.getCanonicalName()
+        + "<" + beanType.getQualifiedSourceName() + ">");
+    composerFactory.addImplementedInterface(validatorType.getName());
+  }
+
+  @Override
+  protected void writeClassBody(SourceWriter sw)
+      throws UnableToCompleteException {
+    writeFields(sw);
+    sw.println();
+    writeValidate(sw);
+    sw.println();
+    writeValidateProperty(sw);
+    sw.println();
+    writeValidateValue(sw);
+    sw.println();
+    writeGetDescriptor(sw);
+    sw.println();
+    writePropertyValidators(sw);
+    sw.println();
+ // Write the Validator instance variables last after we have collected the
+    // ones we need in beansToValidate
+    writeValidatorInstances(sw);
+  }
+
+  private <T> T[] asArray(Collection<?> collection, T[] array) {
     if (collection == null) {
       return null;
     }
     return collection.toArray(array);
   }

-  protected String asGetter(PropertyDescriptor p) {
+  private String asGetter(PropertyDescriptor p) {
     return "get" + capitalizeFirstLetter(p.getPropertyName());
   }

-  protected String capitalizeFirstLetter(String propertyName) {
+  private String capitalizeFirstLetter(String propertyName) {
     if (propertyName == null) {
       return null;
     }
@@ -148,22 +177,12 @@
     return cap;
   }

-  @Override
-  protected void compose(ClassSourceFileComposerFactory composerFactory) {
-    addImports(composerFactory, GWT.class, GwtBeanDescriptor.class,
-        GwtValidationContext.class, Set.class, HashSet.class,
-        ConstraintViolation.class, Annotation.class);
- composerFactory.setSuperclass(AbstractGwtSpecificValidator.class.getCanonicalName()
-        + "<" + beanType.getQualifiedSourceName() + ">");
-    composerFactory.addImplementedInterface(validatorType.getName());
-  }
-
-  protected String constraintDescriptorVar(String name, int count) {
+  private String constraintDescriptorVar(String name, int count) {
     String s = name + "_c" + count;
     return s;
   }

- protected Class<? extends ConstraintValidator<? extends Annotation, ?>> getValidatorForType( + private Class<? extends ConstraintValidator<? extends Annotation, ?>> getValidatorForType( ConstraintDescriptor<? extends Annotation> constraint, Class<?> clazz) {
     // TODO(nchalko) implement per spec
Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass = constraint.getConstraintValidatorClasses().get(
@@ -171,23 +190,37 @@
     return validatorClass;
   }

-  @Override
-  protected void writeClassBody(SourceWriter sw)
-      throws UnableToCompleteException {
-    writeFields(sw);
-    sw.println();
-    writeValidate(sw);
-    sw.println();
-    writeValidateProperty(sw);
-    sw.println();
-    writeValidateValue(sw);
-    sw.println();
-    writeGetDescriptor(sw);
-    sw.println();
-    writePropertyValidtors(sw);
+  /**
+   * @param beanHelper2
+   * @param p
+   * @return
+   */
+  private boolean hasGetter(PropertyDescriptor p) {
+    JType[] paramTypes = new JType[]{};
+    try {
+      beanType.getMethod(asGetter(p), paramTypes);
+      return true;
+    } catch (NotFoundException e) {
+      return false;
+    }
   }

-  protected void writeConstraintDescriptor(SourceWriter sw,
+  private String validateMethodName(PropertyDescriptor p) {
+    return "validateProperty_" + p.getPropertyName();
+  }
+
+  private void writeCallValidator(SourceWriter sw, Class<?> type) {
+    if (BeanHelper.isClassConstrained(type)) {
+      BeanHelper helper = createBeanHelper(type);
+      beansToValidate.add(helper);
+      // voilations.addAll(myValidator.validate(context,object,groups));
+      sw.print("violations.addAll(");
+      sw.print(helper.getValidatorInstanceName());
+      sw.println(".validate(context, object, groups));");
+    }
+  }
+
+  private void writeConstraintDescriptor(SourceWriter sw,
       ConstraintDescriptor<? extends Annotation> constraint,
       String constraintDescripotorVar) throws UnableToCompleteException {
Class<? extends Annotation> annotationType = constraint.getAnnotation().annotationType();
@@ -277,45 +310,6 @@
     sw.outdent();
     sw.println();
   }
-
-  protected void writeValidateInterfaces(SourceWriter sw, Class<?> clazz) {
-    for (Class<?> type : clazz.getInterfaces()) {
- if (serverSideValidator.getConstraintsForClass(type).isBeanConstrained()) {
-        // MyInterface_GwtSpecificValidator validator =
-        // GWT.create(MyInterface_GwtSpecificValidator);
-        // TODO (nchalko) validate interface. This Requires the
-        // MyInterface_GwtSpecficValidator
-        // interface to already be generated.
-        sw.print("//TODO(nchalko) GWT.create(");
-        sw.print(type.getCanonicalName());
-        sw.println("_GwtSpecificValidator);");
-
-        // voilations.add(validator.validate(context,this,groups));
-      }
-
-      writeValidateInterfaces(sw, type);
-    }
-  }
-
-/**
- * @param beanHelper2
- * @param p
- * @return
- */
-private boolean hasGetter(PropertyDescriptor p) {
-  JType[] paramTypes = new JType[]{};
-  try {
-    beanType.getMethod(asGetter(p), paramTypes);
-    return true;
-  } catch (NotFoundException e) {
-    return false;
-  }
-
-}
-
-  private String validateMethodName(PropertyDescriptor p) {
-    return "validateProperty_" + p.getPropertyName();
-  }

   /**
    * @param sourceWriter
@@ -335,6 +329,9 @@
         writeConstraintDescriptor(sw, constraint,
             constraintDescriptorVar(p.getPropertyName(), count));
       }
+      if (p.isCascaded()) {
+        beansToValidate.add(createBeanHelper(p.getElementClass()));
+      }
     }

     // Create a variable for each constraint of this class.
@@ -415,10 +412,7 @@
sw.println("Set<ConstraintViolation<T>> violations = new HashSet<ConstraintViolation<T>>();");
   }

-  /**
-   * @param sw
-   */
-  private void writePropertyValidtors(SourceWriter sw) {
+  private void writePropertyValidators(SourceWriter sw) {
for (PropertyDescriptor p : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
       writeValidatePropertyMethod(sw, p);
       sw.println();
@@ -444,7 +438,6 @@
       // /// For each group

       // TODO(nchalko) handle the sequence in the AbstractValidator
-      // Let the GwtSpecificValidators only take a single group.

       // See JSR 303 section 3.5
       // all reachable fields
@@ -488,26 +481,16 @@

       // validate all super classes and interfaces

-      Class<?> superClass = clazz.getSuperclass();
       writeValidateInterfaces(sw, clazz);
+      Class<?> superClass = clazz.getSuperclass();
       while (superClass != null) {
- if (serverSideValidator.getConstraintsForClass(superClass).isBeanConstrained()) {
-          // MySuper_GwtSpecificValidator validator =
-          // GWT.create(MySuper_GwtSpecificValidator);
-          sw.print("//  GWT.create(");
-          sw.print(superClass.getCanonicalName());
-          sw.println("_GwtSpecificValidator);");
-        }
+        writeCallValidator(sw, superClass);
         writeValidateInterfaces(sw, superClass);
         superClass = superClass.getSuperclass();
       }

       // all reachable and cascadable associations

-      // TODO(nchalko) validationg the object graph will require top level
-      // interfaces for the classes
-      // that already generated
-
       beanType.getFields();
     }
     // return violations;
@@ -516,6 +499,13 @@
     sw.outdent();
     sw.println("}");
   }
+
+  private void writeValidateInterfaces(SourceWriter sw, Class<?> clazz) {
+    for (Class<?> type : clazz.getInterfaces()) {
+      writeCallValidator(sw, type);
+      writeValidateInterfaces(sw, type);
+    }
+  }

   private void writeValidateProperty(SourceWriter sw) {
     // public <T> Set<ConstraintViolation<T>> validate(
@@ -582,6 +572,8 @@
     sw.print("violations, ");
     sw.print("object, ");
     sw.print("object.");
+
+    // TODO(nchalko) use the field if the field is what is annotated.
     if (hasGetter(p)) {
       sw.print(asGetter(p) + "()");
     } else {
@@ -608,6 +600,24 @@
     sw.println(" value,");
     sw.println("Class<?>... groups) {");
     sw.outdent();
+
+    if (p.isCascaded()) {
+      BeanHelper helper = createBeanHelper(p.getElementClass());
+
+      // if(value != null) {
+      sw.println("if(value != null) {");
+      sw.indent();
+
+ // violations.addAll(myGwtValidator.validate(context, value, groups));
+      sw.print("violations.addAll(");
+      sw.print(helper.getValidatorInstanceName());
+      sw.println(".validate(context, value, groups));");
+
+      // }
+      sw.outdent();
+      sw.println("}");
+    }
+
     int count = 0;
for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
       count++; // index starts at 1
@@ -696,4 +706,12 @@
     sw.outdent();
     sw.println("}");
   }
-}
+
+  private void writeValidatorInstances(SourceWriter sw) {
+    sw.println("// The validator instance variables are written last ");
+    sw.println("// after we have identified all the ones we need.");
+    for (BeanHelper helper : beansToValidate) {
+      writeValidatorInstance(sw, helper);
+    }
+  }
+}
=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java Wed Oct 6 06:53:06 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorGenerator.java Tue Nov 30 13:47:49 2010
@@ -24,9 +24,6 @@
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.validation.client.impl.GwtSpecificValidator;

-import javax.validation.Validation;
-import javax.validation.Validator;
-
 /**
* Generates a {...@link com.google.gwt.validation.client.GwtSpecificValidator}.
  * <p>
@@ -34,7 +31,6 @@
  */
 public class GwtSpecificValidatorGenerator extends Generator {

- private final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();

   @Override
   public String generate(TreeLogger logger, GeneratorContext context,
@@ -53,7 +49,7 @@
JClassType gwtSpecificInterface = getGwtSpecificValidator(logger, validator); JClassType beanType = getBeanType(logger, validator, gwtSpecificInterface);

-    BeanHelper beanHelper = ValidatorCreator.getBeanHelper(beanType);
+    BeanHelper beanHelper = BeanHelper.getBeanHelper(beanType);

     if (beanHelper == null) {
logger.log(TreeLogger.ERROR, "Unable to find BeanHelper for " + beanType
@@ -64,7 +60,7 @@
     }

AbstractCreator creator = new GwtSpecificValidatorCreator(validatorType,
-        beanType, beanHelper, logger, context, serverSideValidor);
+        beanType, beanHelper, logger, context);
     return creator.create();
   }

=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java Mon Nov 22 09:21:28 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/ValidatorCreator.java Tue Nov 30 13:47:49 2010
@@ -19,8 +19,6 @@
 import com.google.gwt.core.ext.GeneratorContext;
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.typeinfo.JClassType;
-import com.google.gwt.core.ext.typeinfo.TypeOracle;
-import com.google.gwt.user.rebind.AbstractSourceCreator;
 import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
 import com.google.gwt.user.rebind.SourceWriter;
 import com.google.gwt.validation.client.GwtValidation;
@@ -29,42 +27,21 @@
 import com.google.gwt.validation.client.impl.GwtSpecificValidator;
 import com.google.gwt.validation.client.impl.GwtValidationContext;

-import java.io.PrintWriter;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;

 import javax.validation.ConstraintViolation;
-import javax.validation.Validation;
-import javax.validation.Validator;
 import javax.validation.metadata.BeanDescriptor;

 /**
  * Class that creates the validator for the given input class.
  */
 public class ValidatorCreator extends AbstractCreator {
-
-  // stash the map in a ThreadLocal, since each GWT module lives in its own
-  // thread in DevMode
- private static final ThreadLocal<Map<JClassType, BeanHelper>> threadLocalHelperMap = new ThreadLocal<Map<JClassType, BeanHelper>>() {
-    @Override
-    protected synchronized Map<JClassType, BeanHelper> initialValue() {
-      return new HashMap<JClassType, BeanHelper>();
-    }
-  };
-
-  public static BeanHelper getBeanHelper(JClassType beanType) {
-    return getBeanHelpers().get(beanType);
-  }
-
-  public static Map<JClassType, BeanHelper> getBeanHelpers() {
-    return Collections.unmodifiableMap(threadLocalHelperMap.get());
-  }

private final Map<JClassType, BeanHelper> beansToValidate = new HashMap<JClassType, BeanHelper>();
   private final GwtValidation gwtValidation;
- private final Validator serverSideValidor = Validation.buildDefaultValidatorFactory().getValidator();
+

   public ValidatorCreator(JClassType validatorType, //
       GwtValidation gwtValidation, //
@@ -72,15 +49,11 @@
       GeneratorContext context) {
     super(context, logger, validatorType);
     this.gwtValidation = gwtValidation;
-    TypeOracle oracle = context.getTypeOracle();

     for (Class<?> clazz : gwtValidation.value()) {
-      JClassType jClass = oracle.findType(clazz.getCanonicalName());
-      BeanHelper helper = new BeanHelper(jClass,
-          serverSideValidor.getConstraintsForClass(clazz));
-      beansToValidate.put(jClass, helper);
-    }
-    threadLocalHelperMap.get().putAll(beansToValidate);
+      BeanHelper helper = createBeanHelper(clazz);
+      beansToValidate.put(helper.getJClass(), helper);
+    }
   }

   @Override
@@ -163,32 +136,6 @@
     sourceWriter.println("if (object.getClass().equals("
         + bean.getTypeCanonicalName() + ".class)) {");
   }
-
-  /**
- * Write an Empty Interface implementing {...@link GwtSpecificValidator} with
-   * Generic parameter of the bean type.
-   *
-   * @param bean
-   */
-  private void writeInterface(BeanHelper bean) {
-    PrintWriter pw = context.tryCreate(logger, bean.getPackage(),
-        bean.getValidatorName());
-    if (pw != null) {
-      TreeLogger interfaceLogger = AbstractSourceCreator.branch(
-          logger,
-          "Creating the interface for "
-              + bean.getFullyQualifiedValidatorName());
-
- ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(
-          bean.getPackage(), bean.getValidatorName());
- factory.addImplementedInterface(GwtSpecificValidator.class.getCanonicalName()
-          + " <" + bean.getTypeCanonicalName() + ">");
-      factory.makeInterface();
-      SourceWriter sw2 = factory.createSourceWriter(context, pw);
-      sw2.commit(interfaceLogger);
-      pw.close();
-    }
-  }

   private void writeThrowIllegalArgumnet(SourceWriter sourceWriter,
       String getClassName) {
@@ -213,19 +160,7 @@

   private void writeTypeSupport(SourceWriter sw) {
     for (BeanHelper bean : beansToValidate.values()) {
-      writeInterface(bean);
-      // private final MyBeanValidator myBeanValidator =
- sw.print("private final " + bean.getFullyQualifiedValidatorName() + " ");
-      sw.print(bean.getValidatorInstanceName());
-      sw.println(" = ");
-      sw.indent();
-      sw.indent();
-
-      // GWT.create(MyBeanValidator
-      sw.println("GWT.create(" + bean.getFullyQualifiedValidatorName()
-          + ".class);");
-      sw.outdent();
-      sw.outdent();
+      writeValidatorInstance(sw, bean);
     }
   }

=======================================
--- /trunk/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java Wed Sep 8 07:45:57 2010 +++ /trunk/user/src/com/google/gwt/validation/rebind/ValidatorGenerator.java Tue Nov 30 13:47:49 2010
@@ -63,7 +63,7 @@
     TreeLogger validatorLogger = logger.branch(TreeLogger.DEBUG,
         "Generating Validator for  '" + validator.getQualifiedSourceName()
             + "'", null);
-    ValidatorCreator creator = new ValidatorCreator(validatorType,
+    AbstractCreator creator = new ValidatorCreator(validatorType,
         gwtValidation,
         validatorLogger,
         context);

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to