Revision: 10560
Author:   [email protected]
Date:     Tue Aug 23 10:48:49 2011
Log: Implements * globbing for RequestFactory with(), the simpler half of
the proposal in
http://code.google.com/p/google-web-toolkit/issues/detail?id=6697

Also fixes bugs exposed in using null members in collections

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

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

Modified:
 /trunk/user/src/com/google/web/bindery/requestfactory/server/Resolver.java
/trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryPolymorphicTest.java /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java /trunk/user/test/com/google/web/bindery/requestfactory/server/SimpleFoo.java /trunk/user/test/com/google/web/bindery/requestfactory/shared/SimpleFooRequest.java

=======================================
--- /trunk/user/src/com/google/web/bindery/requestfactory/server/Resolver.java Fri Jun 17 03:15:41 2011 +++ /trunk/user/src/com/google/web/bindery/requestfactory/server/Resolver.java Tue Aug 23 10:48:49 2011
@@ -198,6 +198,11 @@
      * not been previously resolved for the next batch of work.
      */
public void addPaths(String prefix, Collection<String> requestedPaths) {
+      if (clientObject == null) {
+        // No point trying to follow paths past a null value
+        return;
+      }
+
       // Identity comparison intentional
       if (toResolve == EMPTY) {
         toResolve = new TreeSet<String>();
@@ -207,6 +212,8 @@
       for (String path : requestedPaths) {
         if (path.startsWith(prefix)) {
           toResolve.add(path.substring(prefixLength));
+        } else if (path.startsWith("*.")) {
+          toResolve.add(path.substring("*.".length()));
         }
       }
       toResolve.removeAll(resolved);
@@ -310,7 +317,14 @@
    * references.
    */
static boolean matchesPropertyRef(Set<String> propertyRefs, String newPrefix) {
-    return propertyRefs.contains(newPrefix.replaceAll("\\[\\d+\\]", ""));
+    /*
+     * Match all fields for a wildcard
+     *
+ * Also, remove list index suffixes. Not actually used, was in anticipation
+     * of OGNL type schemes. That said, Editor will slip in such things.
+     */
+    return propertyRefs.contains("*")
+        || propertyRefs.contains(newPrefix.replaceAll("\\[\\d+\\]", ""));
   }

   /**
@@ -567,7 +581,7 @@
    */
private Resolution resolveClientValue(Object domainValue, Type clientType) {
     if (domainValue == null) {
-      return null;
+      return new Resolution(null);
     }

     boolean anyType = clientType == null;
=======================================
--- /trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java Fri Jul 1 09:12:59 2011 +++ /trunk/user/src/com/google/web/bindery/requestfactory/shared/impl/ProxySerializerImpl.java Tue Aug 23 10:48:49 2011
@@ -93,6 +93,10 @@
   }

   public String serialize(BaseProxy rootObject) {
+    if (rootObject == null) {
+      return "null";
+    }
+
final AutoBean<? extends BaseProxy> root = AutoBeanUtils.getAutoBean(rootObject);
     if (root == null) {
       // Unexpected, some kind of foreign implementation of the BaseProxy?
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryPolymorphicTest.java Fri Jun 10 11:06:22 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryPolymorphicTest.java Tue Aug 23 10:48:49 2011
@@ -55,6 +55,8 @@

     protected int id = idCount++;

+    private A nextA;
+
     public String getA() {
       return a;
     }
@@ -62,6 +64,13 @@
     public int getId() {
       return id;
     }
+
+    public A getNextA() {
+      if (nextA == null) {
+        nextA = new A();
+      }
+      return nextA;
+    }

     public int getVersion() {
       return 0;
@@ -77,6 +86,8 @@
    */
   @ProxyFor(A.class)
   public interface AProxy extends EntityProxy, HasA {
+    AProxy getNextA();
+
     // Mix in getA() from HasA
     void setA(String value);
   }
@@ -146,9 +157,19 @@

     private String c = "c";

+    private C nextC;
+
     public String getC() {
       return c;
     }
+
+    public C getNextC() {
+      if (nextC == null) {
+        nextC = new C();
+      }
+
+      return nextC;
+    }

     public void setC(String value) {
       c = value;
@@ -161,6 +182,8 @@
   public interface C1Proxy extends B1Proxy {
     String getC();

+    C1Proxy getNextC();
+
     void setC(String value);
   }

@@ -606,6 +629,50 @@
   public String getModuleName() {
     return "com.google.web.bindery.requestfactory.gwt.RequestFactorySuite";
   }
+
+  public void testChain() {
+    delayTestFinish(TEST_DELAY);
+    Context ctx = factory.ctx();
+    ctx.CasA().with("nextA.nextA").fire(new Receiver<AProxy>() {
+      @Override
+      public void onSuccess(AProxy response) {
+ new CastAndCheckReceiver(AProxy.class).onSuccess(response.getNextA().getNextA());
+        assertNull(response.getNextA().getNextA().getNextA());
+        assertNull(((C1Proxy) response).getNextC());
+        finishTest();
+      }
+    });
+  }
+
+  public void testChainWithExtras() {
+    delayTestFinish(TEST_DELAY);
+    Context ctx = factory.ctx();
+    ctx.CasA().with("nextC.nextC").fire(new Receiver<AProxy>() {
+      @Override
+      public void onSuccess(AProxy response) {
+        assertNull(response.getNextA());
+        C1Proxy cast = (C1Proxy) response;
+ new CastAndCheckReceiver(C1Proxy.class).onSuccess(cast.getNextC().getNextC());
+        assertNull(cast.getNextC().getNextC().getNextC());
+        finishTest();
+      }
+    });
+  }
+
+  public void testChainWithWildcards() {
+    delayTestFinish(TEST_DELAY);
+    Context ctx = factory.ctx();
+    ctx.CasA().with("*.*").fire(new Receiver<AProxy>() {
+      @Override
+      public void onSuccess(AProxy response) {
+ new CastAndCheckReceiver(AProxy.class).onSuccess(response.getNextA().getNextA());
+        C1Proxy cast = (C1Proxy) response;
+ new CastAndCheckReceiver(C1Proxy.class).onSuccess(cast.getNextC().getNextC());
+        assertNull(cast.getNextC().getNextC().getNextC());
+        finishTest();
+      }
+    });
+  }

   public void testCreation() {
     delayTestFinish(TEST_DELAY);
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java Fri Aug 5 09:53:30 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/gwt/client/RequestFactoryTest.java Tue Aug 23 10:48:49 2011
@@ -700,6 +700,23 @@
           }
         });
   }
+
+  public void testForwardReferenceWildcardDecode() {
+    delayTestFinish(DELAY_TEST_FINISH);
+ simpleFooRequest().getTripletReference().with("selfOneToManyField.*.fooField")
+        .fire(new Receiver<SimpleFooProxy>() {
+          @Override
+          public void onSuccess(SimpleFooProxy response) {
+            response = checkSerialization(response);
+            assertNotNull(response.getSelfOneToManyField().get(0));
+ assertNotNull(response.getSelfOneToManyField().get(0).getSelfOneToManyField()); + assertNotNull(response.getSelfOneToManyField().get(0).getSelfOneToManyField().get(0)); + assertNotNull(response.getSelfOneToManyField().get(0).getSelfOneToManyField().get(0)
+                .getFooField());
+            finishTestAndReset();
+          }
+        });
+  }

   public void testGetEventBus() {
     assertEquals(eventBus, req.getEventBus());
@@ -979,6 +996,19 @@
     delayTestFinish(DELAY_TEST_FINISH);
     simpleFooRequest().returnNullSimpleFoo().fire(new NullReceiver());
   }
+
+  public void testNullEntityFieldResult() {
+    delayTestFinish(DELAY_TEST_FINISH);
+ simpleFooRequest().getSimpleFooWithNullRelationship().with("fooField.fooField.fooField").fire(
+        new Receiver<SimpleFooProxy>() {
+          @Override
+          public void onSuccess(SimpleFooProxy v) {
+            checkSerialization(v);
+            assertNull(v.getFooField());
+            finishTestAndReset();
+          }
+        });
+  }

   /**
    * Test that a null value can be sent in a request.
@@ -1084,6 +1114,63 @@
       }
     });
   }
+
+  public void testNullValueInEntityListResponse() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    final Request<SimpleFooProxy> fooReq =
+ req.simpleFooRequest().getNullInEntityList().with("selfOneToManyField");
+    fooReq.fire(new Receiver<SimpleFooProxy>() {
+      @Override
+      public void onSuccess(SimpleFooProxy v) {
+        List<SimpleFooProxy> manyFoos = v.getSelfOneToManyField();
+        assertEquals(3, manyFoos.size());
+
+        assertNotNull(manyFoos.get(0));
+        assertNull(manyFoos.get(1));
+        assertNotNull(manyFoos.get(2));
+
+        finishTestAndReset();
+      }
+    });
+  }
+
+  public void testNullValueInEntityListResponseWithWildcard() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    final Request<SimpleFooProxy> fooReq =
+ req.simpleFooRequest().getNullInEntityList().with("selfOneToManyField.*.fooField");
+    fooReq.fire(new Receiver<SimpleFooProxy>() {
+      @Override
+      public void onSuccess(SimpleFooProxy foo0) {
+        List<SimpleFooProxy> manyFoos = foo0.getSelfOneToManyField();
+        assertEquals(3, manyFoos.size());
+
+        assertSame(foo0, manyFoos.get(0).getSelfOneToManyField().get(0));
+        assertNull(manyFoos.get(1));
+        assertSame(foo0, manyFoos.get(2).getSelfOneToManyField().get(0));
+        assertSame(foo0, manyFoos.get(2).getFooField().getFooField());
+
+        finishTestAndReset();
+      }
+    });
+  }
+
+  public void testNullValueInEntityListResponseWithLongResolvePaths() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    final Request<SimpleFooProxy> fooReq =
+ req.simpleFooRequest().getNullInEntityList().with("selfOneToManyField.selfOneToManyField.selfOneToManyField");
+    fooReq.fire(new Receiver<SimpleFooProxy>() {
+      @Override
+      public void onSuccess(SimpleFooProxy v) {
+        assertEquals(3, v.getSelfOneToManyField().size());
+
+        assertNotNull(v.getSelfOneToManyField().get(0));
+        assertNull(v.getSelfOneToManyField().get(1));
+        assertNotNull(v.getSelfOneToManyField().get(2));
+
+        finishTestAndReset();
+      }
+    });
+  }

   /**
    * Test that a null value can be sent within a list of objects.
@@ -2044,6 +2131,31 @@
           }
         });
   }
+
+  public void testPropertyRefsOnWildcardChain() {
+    delayTestFinish(DELAY_TEST_FINISH);
+    final Request<SimpleFooProxy> fooReq =
+      req.simpleFooRequest().getLongChain().with("fooField.*.*.fooField");
+    fooReq.fire(new Receiver<SimpleFooProxy>() {
+      @Override
+      public void onSuccess(SimpleFooProxy foo0) {
+        assertNull(foo0.getSelfOneToManyField()); // didn't ask for it
+
+        SimpleFooProxy foo1 = foo0.getFooField(); // "fooField
+        SimpleFooProxy foo2 = foo1.getFooField(); //          .*
+        SimpleFooProxy foo3 = foo2.getFooField(); //            .*
+ SimpleFooProxy foo4 = foo3.getFooField(); // .fooField"
+        SimpleFooProxy foo5 = foo4.getFooField();
+
+        assertNotNull(foo1);
+        assertNotNull(foo2);
+        assertNotNull(foo3);
+        assertNotNull(foo4);
+        assertNull(foo5);
+        finishTestAndReset();
+      }
+    });
+  }

   public void testPropertyRefsOnSameObjectReturnedTwice() {
     delayTestFinish(DELAY_TEST_FINISH);
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/server/SimpleFoo.java Fri Jun 17 03:15:41 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/server/SimpleFoo.java Tue Aug 23 10:48:49 2011
@@ -124,6 +124,53 @@
     foo3.persist();
     return Arrays.asList(foo1, foo2, foo3);
   }
+
+  public static SimpleFoo getLongChain() {
+    SimpleFoo foo0 = new SimpleFoo();
+    SimpleFoo foo1 = new SimpleFoo();
+    SimpleFoo foo2 = new SimpleFoo();
+    SimpleFoo foo3 = new SimpleFoo();
+    SimpleFoo foo4 = new SimpleFoo();
+    SimpleFoo foo5 = new SimpleFoo();
+
+    foo0.setSelfOneToManyField(Arrays.asList(foo1, foo2));
+    foo0.setFooField(foo1);
+    foo1.setFooField(foo2);
+    foo2.setFooField(foo3);
+    foo3.setFooField(foo4);
+    foo4.setFooField(foo5);
+    foo5.setFooField(foo5);
+
+    foo0.persist();
+    foo1.persist();
+    foo2.persist();
+    foo3.persist();
+    foo4.persist();
+    foo5.persist();
+
+    return foo0;
+  }
+
+  public static SimpleFoo getNullInEntityList() {
+    SimpleFoo foo0 = new SimpleFoo();
+    SimpleFoo foo1 = new SimpleFoo();
+    SimpleFoo foo2 = new SimpleFoo();
+    SimpleFoo foo2FooField = new SimpleFoo();
+
+    foo0.setSelfOneToManyField(Arrays.asList(foo1, null, foo2));
+
+    foo1.setSelfOneToManyField(Arrays.asList(foo0));
+
+    foo2.setSelfOneToManyField(Arrays.asList(foo0));
+    foo2.setFooField(foo2FooField);
+    foo2FooField.setFooField(foo0);
+
+    foo0.persist();
+    foo1.persist();
+    foo2.persist();
+    foo2FooField.persist();
+    return foo0;
+  }

   public static List<Integer> getNumberList() {
     ArrayList<Integer> list = new ArrayList<Integer>();
@@ -140,6 +187,12 @@
     list.add(3);
     return list;
   }
+
+  public static SimpleFoo getSimpleFooWithNullRelationship() {
+    SimpleFoo foo = new SimpleFoo();
+    foo.persist();
+    return foo;
+  }

   /**
    * This tests that the server detects and disallows the use of persisted
=======================================
--- /trunk/user/test/com/google/web/bindery/requestfactory/shared/SimpleFooRequest.java Fri Jun 17 03:15:41 2011 +++ /trunk/user/test/com/google/web/bindery/requestfactory/shared/SimpleFooRequest.java Tue Aug 23 10:48:49 2011
@@ -49,10 +49,16 @@

   Request<List<SimpleFooProxy>> getFlattenedTripletReference();

-  Request<List<Integer>> getNumberList();
-
+  Request<SimpleFooProxy> getLongChain();
+
+  Request<SimpleFooProxy> getNullInEntityList();
+
+  Request<List<Integer>> getNumberList();
+
   Request<Set<Integer>> getNumberSet();

+  Request<SimpleFooProxy> getSimpleFooWithNullRelationship();
+
   Request<SimpleFooProxy> getSimpleFooWithNullVersion();

   Request<SimpleFooProxy> getSimpleFooWithSubPropertyCollection();

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

Reply via email to