Handle more literal types for anntation values, including Enums.

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

Review by: rchandia@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9937 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
index 5f52eba..851d0c2 100644
--- a/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
+++ b/user/src/com/google/gwt/validation/rebind/GwtSpecificValidatorCreator.java
@@ -110,58 +110,69 @@
   }
 
   /**
-     * 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();
+   * 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;
+    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("new " + clazz.getComponentType().getCanonicalName() + "[] ");
+      sb.append("{");
+      boolean first = true;
+      for (Object object : array) {
+        if (first) {
+          first = false;
+        } else {
+          sb.append(",");
         }
-        sb.append("}");
-        return sb.toString();
+        sb.append(asLiteral(object));
       }
-
-      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 '"' + Generator.escape((String) value) + '"';
-      }
-      // TODO(nchalko) handle the rest of the literal types
-      throw new IllegalArgumentException(value.getClass()
-          + " is can not be represented as a Java Literal.");
+      sb.append("}");
+      return sb.toString();
     }
 
+    if (value instanceof Boolean) {
+      return jProgram.getLiteralBoolean(((Boolean) value).booleanValue())
+          .toSource();
+    } else if (value instanceof Byte) {
+      return jProgram.getLiteralInt(((Byte) value).byteValue()).toSource();
+    } else if (value instanceof Character) {
+      return jProgram.getLiteralChar(((Character) value).charValue())
+          .toSource();
+    } else if (value instanceof Class<?>) {
+      return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
+    } else if (value instanceof Double) {
+      return jProgram.getLiteralDouble(((Double) value).doubleValue())
+          .toSource();
+    } else if (value instanceof Enum) {
+      return value.getClass().getCanonicalName() + "."
+          + ((Enum<?>) value).name();
+    } else if (value instanceof Float) {
+      return jProgram.getLiteralFloat(((Float) value).floatValue()).toSource();
+    } else if (value instanceof Integer) {
+      return jProgram.getLiteralInt(((Integer) value).intValue()).toSource();
+    } else if (value instanceof Long) {
+      return jProgram.getLiteralLong(((Long) value).intValue()).toSource();
+    } else if (value instanceof String) {
+      return '"' + Generator.escape((String) value) + '"';
+    } else {
+      // TODO(nchalko) handle Annotation types
+      throw new IllegalArgumentException(value.getClass()
+          + " can not be represented as a Java Literal.");
+    }
+  }
+
   public static String capitalizeFirstLetter(String propertyName) {
     if (propertyName == null) {
       return null;
diff --git a/user/test/com/google/gwt/validation/ConstraintsGwtSuite.java b/user/test/com/google/gwt/validation/ConstraintsGwtSuite.java
index 2930f06..ae52679 100644
--- a/user/test/com/google/gwt/validation/ConstraintsGwtSuite.java
+++ b/user/test/com/google/gwt/validation/ConstraintsGwtSuite.java
@@ -17,6 +17,7 @@
 
 import com.google.gwt.junit.tools.GWTTestSuite;
 import com.google.gwt.validation.client.constraints.GwtCompileTest;
+import com.google.gwt.validation.client.constraints.PatternValidatorGwtTest;
 
 import junit.framework.Test;
 
@@ -28,6 +29,7 @@
     GWTTestSuite suite = new GWTTestSuite(
         "Validation Constraint tests that require GWT");
     suite.addTestSuite(GwtCompileTest.class);
+    suite.addTestSuite(PatternValidatorGwtTest.class);
     return suite;
   }
 
diff --git a/user/test/com/google/gwt/validation/ValidationTest.gwt.xml b/user/test/com/google/gwt/validation/ValidationTest.gwt.xml
index d088c8f..357d3ed 100644
--- a/user/test/com/google/gwt/validation/ValidationTest.gwt.xml
+++ b/user/test/com/google/gwt/validation/ValidationTest.gwt.xml
@@ -18,6 +18,8 @@
 <module>
   <inherits name="com.google.gwt.user.User" />
   <inherits name="org.hibernate.validator.HibernateValidator" />
-  <source path="client">
-  </source>
+  <source path="client"/>
+  <replace-with class="com.google.gwt.validation.client.TestValidatorFactory">
+    <when-type-is class="javax.validation.ValidatorFactory"/>
+  </replace-with>
 </module>
\ No newline at end of file
diff --git a/user/test/com/google/gwt/validation/client/TestValidatorFactory.java b/user/test/com/google/gwt/validation/client/TestValidatorFactory.java
new file mode 100644
index 0000000..832df05
--- /dev/null
+++ b/user/test/com/google/gwt/validation/client/TestValidatorFactory.java
@@ -0,0 +1,44 @@
+/*
+ * 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.validation.client;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.validation.client.constraints.PatternValidatorGwtTest.Flagged;
+import com.google.gwt.validation.client.impl.AbstractGwtValidator;
+
+import javax.validation.Validator;
+
+/**
+ * Factory to create the Validator specified by {@link GwtValidator}.
+ * 
+ * GWT.create instances of this class
+ */
+public class TestValidatorFactory extends AbstractGwtValidatorFactory {
+
+  /**
+   * Validator Interface annotated with the list of classes to validate on the
+   * client.
+   */
+  @GwtValidation(
+value = {Flagged.class})
+  public interface GwtValidator extends Validator {
+  }
+
+  @Override
+  public AbstractGwtValidator createValidator() {
+    return GWT.create(GwtValidator.class);
+  }
+}
diff --git a/user/test/com/google/gwt/validation/client/ValidationClientGwtTestCase.java b/user/test/com/google/gwt/validation/client/ValidationClientGwtTestCase.java
index eb2d781..cb8cf1d 100644
--- a/user/test/com/google/gwt/validation/client/ValidationClientGwtTestCase.java
+++ b/user/test/com/google/gwt/validation/client/ValidationClientGwtTestCase.java
@@ -17,13 +17,24 @@
 
 import com.google.gwt.junit.client.GWTTestCase;
 
+import javax.validation.Validation;
+import javax.validation.Validator;
+
 /**
  * Base {@link GWTTestCase} for Validation Client tests.
  */
 public abstract class ValidationClientGwtTestCase extends GWTTestCase {
 
+  protected Validator validator;
+
   @Override
   public final String getModuleName() {
     return "com.google.gwt.validation.ValidationTest";
   }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    super.gwtSetUp();
+    validator = Validation.buildDefaultValidatorFactory().getValidator();
+  }
 }
\ No newline at end of file
diff --git a/user/test/com/google/gwt/validation/client/constraints/PatternValidatorGwtTest.java b/user/test/com/google/gwt/validation/client/constraints/PatternValidatorGwtTest.java
new file mode 100644
index 0000000..757fc91
--- /dev/null
+++ b/user/test/com/google/gwt/validation/client/constraints/PatternValidatorGwtTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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.validation.client.constraints;
+
+import com.google.gwt.validation.client.ValidationClientGwtTestCase;
+
+import java.util.Set;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.constraints.Pattern;
+import javax.validation.constraints.Pattern.Flag;
+
+/**
+ * Tests for {@link PatternValidator}.
+ */
+public class PatternValidatorGwtTest extends ValidationClientGwtTestCase {
+
+  /**
+   * Test object that uses {@link Pattern.Flag}.
+   */
+  public static class Flagged {
+
+    @Pattern(regexp = "g..d", flags = Flag.CASE_INSENSITIVE)
+    public String name;
+  }
+
+  private Flagged flagged;
+
+  public void testAssertIsValid_goad() {
+    assertValueValid("goad", true);
+  }
+
+  public void testAssertIsValid_good() {
+    assertValueValid("good", true);
+  }
+
+  public void testAssertIsValid_GOOD() {
+    assertValueValid("GOOD", true);
+  }
+
+  public void testAssertIsValid_goood() {
+    assertValueValid("goood", false);
+  }
+
+  public void testAssertIsValid_not_good() {
+    assertValueValid("this is not good", false);
+  }
+
+  @Override
+  protected void gwtSetUp() throws Exception {
+    super.gwtSetUp();
+    flagged = new Flagged();
+  }
+
+  private void assertValueValid(String value, boolean expected) {
+    flagged.name = value;
+    Set<ConstraintViolation<Flagged>> violations = validator.validate(flagged);
+    assertEquals(value + " is valid", expected, violations.isEmpty());
+  }
+}
diff --git a/user/test/com/google/gwt/validation/rebind/GwtSpecificValidatorCreatorTest.java b/user/test/com/google/gwt/validation/rebind/GwtSpecificValidatorCreatorTest.java
index 7f735d4..aa9399b 100644
--- a/user/test/com/google/gwt/validation/rebind/GwtSpecificValidatorCreatorTest.java
+++ b/user/test/com/google/gwt/validation/rebind/GwtSpecificValidatorCreatorTest.java
@@ -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
@@ -36,13 +36,54 @@
  */
 public class GwtSpecificValidatorCreatorTest extends TestCase {
 
+  private static enum Foo {
+    BAR, BAS
+  }
+
   private static Set<Class<? extends ConstraintValidator<? extends Annotation, ?>>> copyOf(
       Class<? extends ConstraintValidator<? extends Annotation, ?>>... classes) {
     return ImmutableSet.copyOf(classes);
   }
 
-  ImmutableList<Class<? extends ConstraintValidator<Size, ?>>> sizeValidators = ImmutableList.<Class<? extends ConstraintValidator<Size, ?>>> of(
-      SizeValidatorForCollection.class, SizeValidatorForString.class);
+  ImmutableList<Class<? extends ConstraintValidator<Size, ?>>> sizeValidators = ImmutableList
+      .<Class<? extends ConstraintValidator<Size, ?>>> of(
+          SizeValidatorForCollection.class, SizeValidatorForString.class);
+
+  public void testAsLiteral_0b11010() {
+    assertLiteral("26", (byte) 26);
+  }
+
+  public void testAsLiteral_1() {
+    assertLiteral("1", 1);
+  }
+
+  public void testAsLiteral_1_1d() {
+    assertLiteral("1.1", 1.1d);
+  }
+
+  public void testAsLiteral_1_1f() {
+    assertLiteral("1.1f", 1.1f);
+  }
+
+  public void testAsLiteral_1L() {
+    assertLiteral("1L", 1L);
+  }
+
+  public void testAsLiteral_a() {
+    assertLiteral("'a'", 'a');
+  }
+
+  public void testAsLiteral_Enum() {
+    assertLiteral(Foo.class.getCanonicalName() + "." + Foo.BAS.name(), Foo.BAS);
+  }
+
+  public void testAsLiteral_Foo() {
+    assertLiteral("\"Foo\"", "Foo");
+  }
+
+  public void testAsLiteral_true() {
+    assertLiteral("true", true);
+  }
 
   @SuppressWarnings("unchecked")
   public void testGetValidatorForType_collection() throws Exception {
@@ -58,4 +99,11 @@
         target, sizeValidators);
     assertEquals(copyOf(SizeValidatorForString.class), actual);
   }
+
+  private void assertLiteral(String expected, Object value) {
+    String actual = GwtSpecificValidatorCreator.asLiteral(value);
+    assertEquals("asLiteral(" + value.getClass().getSimpleName() + " " + value
+        + ")", expected, actual);
+  }
+
 }