Address issue 6066 where RequestFactoryEditorDriver doesn't collect composite paths.
http://gwt-code-reviews.appspot.com/1363801
Patch by: t.broyer
Review by: bobv


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9839 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/client/impl/PathCollector.java b/user/src/com/google/gwt/requestfactory/client/impl/PathCollector.java
index e654e41..01a5fdf 100644
--- a/user/src/com/google/gwt/requestfactory/client/impl/PathCollector.java
+++ b/user/src/com/google/gwt/requestfactory/client/impl/PathCollector.java
@@ -41,8 +41,21 @@
 
   public <T> boolean visit(EditorContext<T> ctx) {
     String path = ctx.getAbsolutePath();
-    if (path.length() > 0 && !ValueCodex.canDecode(ctx.getEditedType())) {
-      paths.add(path);
+    if (path.length() > 0) {
+      if (ValueCodex.canDecode(ctx.getEditedType())) {
+        /*
+         * If there's an @Path("foo.bar.valueField") annotation, we want to
+         * collect the containing "foo.bar" path.
+         */
+        int dotPosition = path.lastIndexOf('.');
+        if (dotPosition > 0) {
+          String parentPath = path.substring(0, dotPosition);
+          paths.add(parentPath);
+        }
+      } else {
+        // Always collect @Path("foo.bar.baz") field, when baz isn't a value
+        paths.add(path);
+      }
     }
     if (ctx.asCompositeEditor() != null) {
       ctx.traverseSyntheticCompositeEditor(this);
diff --git a/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java b/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
index f03fab9..42ed8ec 100644
--- a/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
+++ b/user/test/com/google/gwt/requestfactory/client/ui/EditorTest.java
@@ -61,8 +61,12 @@
     }
   }
 
-  static class SimpleFooBarOnlyEditor implements Editor<SimpleFooProxy> {
-    SimpleBarEditor barField = new SimpleBarEditor();
+  static class SimpleFooBarNameOnlyEditor implements Editor<SimpleFooProxy> {
+    /**
+     * Test nested path access.
+     */
+    @Path("barField.userName")
+    final SimpleEditor<String> barName = SimpleEditor.of();
   }
 
   interface SimpleFooDriver extends
@@ -81,10 +85,10 @@
     @Path("barField.userName")
     final SimpleEditor<String> barName = SimpleEditor.of();
 
-    final ListEditor<SimpleFooProxy, SimpleFooBarOnlyEditor> selfOneToManyField = ListEditor.of(new EditorSource<SimpleFooBarOnlyEditor>() {
+    final ListEditor<SimpleFooProxy, SimpleFooBarNameOnlyEditor> selfOneToManyField = ListEditor.of(new EditorSource<SimpleFooBarNameOnlyEditor>() {
       @Override
-      public SimpleFooBarOnlyEditor create(int index) {
-        return new SimpleFooBarOnlyEditor();
+      public SimpleFooBarNameOnlyEditor create(int index) {
+        return new SimpleFooBarNameOnlyEditor();
       }
     });
 
@@ -128,8 +132,8 @@
     final SimpleFooDriver driver = GWT.create(SimpleFooDriver.class);
     driver.initialize(req, editor);
     final String[] paths = driver.getPaths();
-    assertEquals(Arrays.asList("selfOneToManyField",
-        "selfOneToManyField.barField", "barField"), Arrays.asList(paths));
+    assertEquals(Arrays.asList("barField", "selfOneToManyField",
+        "selfOneToManyField.barField"), Arrays.asList(paths));
 
     req.simpleFooRequest().findSimpleFooById(1L).with(paths).fire(
         new Receiver<SimpleFooProxy>() {
@@ -155,7 +159,9 @@
             editor.userName.setValue("EditorFooTest");
             // When there are duplicate paths, last declared editor wins
             editor.barEditor().userName.setValue("EditorBarTest");
-            editor.barName.setValue("ignored");
+            editor.barName.setValue("ignored 1");
+            editor.selfOneToManyField.getEditors().get(0).barName.setValue(
+                "ignored 2");
             driver.flush().fire();
           }
         });
@@ -222,8 +228,8 @@
     driver.initialize(req, editor);
 
     String[] paths = driver.getPaths();
-    assertEquals(Arrays.asList("selfOneToManyField",
-        "selfOneToManyField.barField", "barField"), Arrays.asList(paths));
+    assertEquals(Arrays.asList("barField", "selfOneToManyField",
+        "selfOneToManyField.barField"), Arrays.asList(paths));
 
     req.simpleFooRequest().findSimpleFooById(1L).with(paths).fire(
         new Receiver<SimpleFooProxy>() {