Revision: 9607
Author: gwt.mirror...@gmail.com
Date: Tue Jan 25 08:47:13 2011
Log: Allow Editor framework to handle primitive types.
Issue 5864.
Patch by: bobv
Review by: rjrjr

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

http://code.google.com/p/google-web-toolkit/source/detail?r=9607

Modified:
 /trunk/user/src/com/google/gwt/editor/rebind/model/EditorModel.java
 /trunk/user/test/com/google/gwt/editor/client/Person.java
 /trunk/user/test/com/google/gwt/editor/client/PersonEditor.java
 /trunk/user/test/com/google/gwt/editor/client/SimpleBeanEditorTest.java
 /trunk/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java

=======================================
--- /trunk/user/src/com/google/gwt/editor/rebind/model/EditorModel.java Fri Jan 14 08:57:14 2011 +++ /trunk/user/src/com/google/gwt/editor/rebind/model/EditorModel.java Tue Jan 25 08:47:13 2011
@@ -180,6 +180,8 @@

   private final TreeLogger logger;

+  private final TypeOracle oracle;
+
   private final EditorModel parentModel;

   private boolean poisoned;
@@ -212,7 +214,7 @@
       die(mustExtendMessage(driverType));
     }

-    TypeOracle oracle = intf.getOracle();
+    oracle = intf.getOracle();
     editorIntf = oracle.findType(Editor.class.getName()).isGenericType();
     assert editorIntf != null : "No Editor type";
isEditorIntf = oracle.findType(IsEditor.class.getName()).isGenericType();
@@ -250,6 +252,7 @@
     this.editorSoFar = subEditor;
     this.isEditorIntf = parent.isEditorIntf;
     this.leafValueEditorIntf = parent.leafValueEditorIntf;
+    this.oracle = parent.oracle;
     this.parentModel = parent;
     this.proxyType = proxyType;
     this.typeData = parent.typeData;
@@ -467,6 +470,7 @@
       if (parts[i].length() == 0) {
         continue;
       }
+      boolean lastPart = i == j - 1;
       String getterName = camelCase("get", parts[i]);

for (JClassType search : lookingAt.getFlattenedSupertypeHierarchy()) {
@@ -475,12 +479,19 @@
           for (JMethod maybeSetter : search.getOverloads(camelCase("set",
               parts[i]))) {
             if (maybeSetter.getReturnType().equals(JPrimitiveType.VOID)
-                && maybeSetter.getParameters().length == 1
- && maybeSetter.getParameters()[0].getType().isClassOrInterface() != null - && maybeSetter.getParameters()[0].getType().isClassOrInterface().isAssignableFrom(
-                    propertyType)) {
-              setterName = maybeSetter.getName();
-              break;
+                && maybeSetter.getParameters().length == 1) {
+ JType setterParamType = maybeSetter.getParameters()[0].getType();
+              // Handle the case of setFoo(int) vs. Editor<Integer>
+              if (setterParamType.isPrimitive() != null) {
+                // Replace the int with Integer
+ setterParamType = oracle.findType(setterParamType.isPrimitive().getQualifiedBoxedSourceName());
+              }
+ boolean matches = setterParamType.isClassOrInterface().isAssignableFrom(
+                  propertyType);
+              if (matches) {
+                setterName = maybeSetter.getName();
+                break;
+              }
             }
           }
         }
@@ -489,7 +500,7 @@
         if (getter != null) {
           JType returnType = getter.getReturnType();
           lookingAt = returnType.isClassOrInterface();
-          if (lookingAt == null) {
+          if (!lastPart && lookingAt == null) {
             poison(foundPrimitiveMessage(returnType,
                 interstitialGetters.toString(), path));
             return;
=======================================
--- /trunk/user/test/com/google/gwt/editor/client/Person.java Mon Sep 13 09:30:34 2010 +++ /trunk/user/test/com/google/gwt/editor/client/Person.java Tue Jan 25 08:47:13 2011
@@ -19,13 +19,18 @@
  * Simple data object used by multiple tests.
  */
 public class Person {
-  String name;
   Address address;
   Person manager;
+  String name;
+  long localTime;

   public Address getAddress() {
     return address;
   }
+
+  public long getLocalTime() {
+    return localTime;
+  }

   public Person getManager() {
     return manager;
@@ -38,6 +43,10 @@
   public void setAddress(Address address) {
     this.address = address;
   }
+
+  public void setLocalTime(long localTime) {
+    this.localTime = localTime;
+  }

   public void setManager(Person manager) {
     this.manager = manager;
=======================================
--- /trunk/user/test/com/google/gwt/editor/client/PersonEditor.java Wed Sep 15 02:26:39 2010 +++ /trunk/user/test/com/google/gwt/editor/client/PersonEditor.java Tue Jan 25 08:47:13 2011
@@ -22,6 +22,7 @@
  */
 class PersonEditor implements Editor<Person> {
   public AddressEditor addressEditor = new AddressEditor();
+ public SimpleEditor<Long> localTime = SimpleEditor.of(System.currentTimeMillis()); public SimpleEditor<String> name = SimpleEditor.of(SimpleBeanEditorTest.UNINITIALIZED);
   @Path("manager.name")
public SimpleEditor<String> managerName = SimpleEditor.of(SimpleBeanEditorTest.UNINITIALIZED);
=======================================
--- /trunk/user/test/com/google/gwt/editor/client/SimpleBeanEditorTest.java Thu Jan 20 05:44:43 2011 +++ /trunk/user/test/com/google/gwt/editor/client/SimpleBeanEditorTest.java Tue Jan 25 08:47:13 2011
@@ -267,6 +267,8 @@

   static final String UNINITIALIZED = "uninitialized";

+  long now;
+
   @Override
   public String getModuleName() {
     return "com.google.gwt.editor.Editor";
@@ -277,17 +279,20 @@
     PersonEditor editor = new PersonEditor();
     driver.initialize(editor);
     driver.edit(person);
+    assertEquals(now, editor.localTime.getValue().longValue());
     assertEquals("Alice", editor.name.getValue());
     assertEquals("City", editor.addressEditor.city.getValue());
     assertEquals("Street", editor.addressEditor.street.getValue());
     assertEquals("Bill", editor.managerName.getValue());

+    editor.localTime.setValue(now + 1);
     editor.name.setValue("Charles");
     editor.addressEditor.city.setValue("Wootville");
     editor.addressEditor.street.setValue("12345");
     editor.managerName.setValue("David");

     driver.flush();
+    assertEquals(now + 1, person.localTime);
     assertEquals("Charles", person.name);
     assertEquals("Wootville", person.address.city);
     assertEquals("12345", person.address.street);
@@ -354,7 +359,7 @@
     // Use the delegate to toggle the state
     editor.delegate.setDirty(true);
     assertTrue(driver.isDirty());
-
+
     // Use the delegate to clear the state
     editor.delegate.setDirty(false);
     assertFalse(driver.isDirty());
@@ -370,23 +375,25 @@

   public void testDirtyWithOptionalEditor() {
     AddressEditor addressEditor = new AddressEditor();
- PersonEditorWithOptionalAddressEditor editor = new PersonEditorWithOptionalAddressEditor(addressEditor); + PersonEditorWithOptionalAddressEditor editor = new PersonEditorWithOptionalAddressEditor(
+        addressEditor);
PersonEditorWithOptionalAddressDriver driver = GWT.create(PersonEditorWithOptionalAddressDriver.class);
     driver.initialize(editor);
     driver.edit(person);
-
+
     // Freshly-initialized should not be dirty
     assertFalse(driver.isDirty());
-
+
     // Change the instance being edited
     Address a = new Address();
     editor.address.setValue(a);
     assertTrue(driver.isDirty());
-
+
     // Check restoration works
     editor.address.setValue(personAddress);
     assertFalse(driver.isDirty());
   }
+
   /**
    * Test the use of the IsEditor interface that allows a view object to
    * encapsulate its Editor.
@@ -677,6 +684,7 @@
     person.address = personAddress;
     person.name = "Alice";
     person.manager = manager;
+    person.localTime = now = System.currentTimeMillis();
   }

   private <T extends Editor<Person>> void testLeafAddressEditor(
=======================================
--- /trunk/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java Tue Jan 18 08:32:58 2011 +++ /trunk/user/test/com/google/gwt/editor/rebind/model/EditorModelTest.java Tue Jan 25 08:47:13 2011
@@ -18,6 +18,7 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.UnableToCompleteException;
 import com.google.gwt.core.ext.typeinfo.JClassType;
+import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
 import com.google.gwt.core.ext.typeinfo.TypeOracle;
 import com.google.gwt.dev.javac.CompilationState;
 import com.google.gwt.dev.javac.CompilationStateBuilder;
@@ -185,7 +186,7 @@
         types.findType("t.CompositeEditorDriver"), rfedType);

     EditorData[] data = m.getEditorData();
-    assertEquals(6, data.length);
+    assertEquals(7, data.length);

     String[] paths = new String[data.length];
     String[] expressions = new String[data.length];
@@ -194,17 +195,19 @@
       expressions[i] = data[i].getExpression();
     }
     assertEquals(Arrays.asList("address", "address.city", "address.street",
-        "person", "person.name", "person.readonly"), Arrays.asList(paths));
+        "person", "person.lastModified", "person.name", "person.readonly"),
+        Arrays.asList(paths));
     // address is a property, person is a method in CompositeEditor
     assertEquals(Arrays.asList("address", "address.city", "address.street",
-        "person()", "person().name", "person().readonly"),
-        Arrays.asList(expressions));
+        "person()", "person().lastModified", "person().name",
+        "person().readonly"), Arrays.asList(expressions));
     assertTrue(data[0].isDelegateRequired());
assertFalse(data[0].isLeafValueEditor() || data[0].isValueAwareEditor());
     assertTrue(data[3].isDelegateRequired());
assertFalse(data[3].isLeafValueEditor() || data[3].isValueAwareEditor());
-    checkPersonName(data[4]);
-    checkPersonReadonly(data[5]);
+    checkPersonLastModified(data[4]);
+    checkPersonName(data[5]);
+    checkPersonReadonly(data[6]);
   }

   public void testCyclicDriver() {
@@ -254,12 +257,14 @@
     EditorModel m = new EditorModel(logger,
         types.findType("t.PersonEditorDriver"), rfedType);
     EditorData[] fields = m.getEditorData();
-    assertEquals(2, fields.length);
-
+    assertEquals(3, fields.length);
+
+    // lastModified
+    checkPersonLastModified(fields[0]);
     // name
-    checkPersonName(fields[0]);
+    checkPersonName(fields[1]);
     // readonly
-    checkPersonReadonly(fields[1]);
+    checkPersonReadonly(fields[2]);
   }

   public void testFlatData() throws UnableToCompleteException {
@@ -275,9 +280,10 @@
     assertEquals("person", composite[1].getPropertyName());

EditorData[] person = m.getEditorData(types.findType("t.PersonEditor"));
-    assertEquals(2, person.length);
-    assertEquals("name", person[0].getPropertyName());
-    assertEquals("readonly", person[1].getPropertyName());
+    assertEquals(3, person.length);
+    assertEquals("lastModified", person[0].getPropertyName());
+    assertEquals("name", person[1].getPropertyName());
+    assertEquals("readonly", person[2].getPropertyName());

EditorData[] address = m.getEditorData(types.findType("t.AddressEditor"));
     assertEquals("city", address[0].getPropertyName());
@@ -401,6 +407,9 @@
     builder.expectError(
EditorModel.tooManyInterfacesMessage(types.findType("t.TooManyInterfacesEditorDriver")),
         null);
+ builder.expectError(EditorModel.foundPrimitiveMessage(JPrimitiveType.LONG,
+        "", "lastModified.foo"), null);
+    builder.expectError(EditorModel.poisonedMessage(), null);
     UnitTestTreeLogger testLogger = builder.createLogger();

     try {
@@ -419,6 +428,13 @@
       fail("Should have thrown exception");
     } catch (UnableToCompleteException expected) {
     }
+    try {
+      new EditorModel(testLogger,
+          types.findType("t.PersonEditorWithBadPrimitiveAccessDriver"),
+          rfedType);
+      fail("Should have thrown exception");
+    } catch (UnableToCompleteException expected) {
+    }
     testLogger.assertCorrectLogEntries();
   }

@@ -447,7 +463,18 @@
     EditorModel m = new EditorModel(logger,
types.findType("t.PersonEditorWithAliasedSubEditorsDriver"), rfedType);
     EditorData[] fields = m.getEditorData();
-    assertEquals(6, fields.length);
+    assertEquals(8, fields.length);
+  }
+
+  private void checkPersonLastModified(EditorData editorField) {
+    assertNotNull(editorField);
+    assertEquals(types.findType(SimpleEditor.class.getName()),
+        editorField.getEditorType().isParameterized().getBaseType());
+    assertTrue(editorField.isLeafValueEditor());
+    assertFalse(editorField.isDelegateRequired());
+    assertFalse(editorField.isValueAwareEditor());
+    assertEquals(".getLastModified()", editorField.getGetterExpression());
+    assertEquals("setLastModified", editorField.getSetterName());
   }

   private void checkPersonName(EditorData editorField) {
@@ -639,8 +666,10 @@
         code.append("interface PersonProxy extends EntityProxy {\n");
         code.append("AddressProxy getAddress();\n");
         code.append("String getName();\n");
-        code.append("void setName(String name);\n");
+        code.append("long getLastModified();\n");
         code.append("String getReadonly();\n");
+        code.append("void setName(String name);\n");
+        code.append("void setLastModified(long value);\n");
         code.append("}");
         return code;
       }
@@ -652,6 +681,7 @@
         code.append("import " + Editor.class.getName() + ";\n");
         code.append("import " + SimpleEditor.class.getName() + ";\n");
code.append("class PersonEditor implements Editor<PersonProxy> {\n");
+        code.append("SimpleEditor<Long> lastModified;\n");
         code.append("public SimpleEditor<String> name;\n");
         code.append("SimpleEditor<String> readonly;\n");
         code.append("public static SimpleEditor ignoredStatic;\n");
@@ -685,6 +715,30 @@
         code.append("}");
         return code;
       }
+    }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccess") {
+      @Override
+      protected CharSequence getContent() {
+        StringBuilder code = new StringBuilder();
+        code.append("package t;\n");
+        code.append("import " + Editor.class.getName() + ";\n");
+        code.append("import " + SimpleEditor.class.getName() + ";\n");
+ code.append("class PersonEditorWithBadPrimitiveAccess implements Editor<PersonProxy> {\n"); + code.append("@Path(\"lastModified.foo\") SimpleEditor<String> bad;\n");
+        code.append("}");
+        return code;
+      }
+    }, new MockJavaResource("t.PersonEditorWithBadPrimitiveAccessDriver") {
+      @Override
+      protected CharSequence getContent() {
+        StringBuilder code = new StringBuilder();
+        code.append("package t;\n");
+        code.append("import " + RequestFactoryEditorDriver.class.getName()
+            + ";\n");
+ code.append("interface PersonEditorWithBadPrimitiveAccessDriver extends" + + " RequestFactoryEditorDriver<PersonProxy, t.PersonEditorWithBadPrimitiveAccess> {\n");
+        code.append("}");
+        return code;
+      }
     }, new MockJavaResource("t.PersonEditorUsingMethods") {
       @Override
       protected CharSequence getContent() {

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

Reply via email to