Reviewers: tbroyer, jasonhall, Jeff Larsen,

Description:
Properly encode request parameters that use Collections when in JSON-RPC
mode.


Please review this at http://gwt-code-reviews.appspot.com/1618806/

Affected files:
M user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java


Index: user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java
===================================================================
--- user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java (revision 10804) +++ user/src/com/google/web/bindery/requestfactory/shared/impl/AbstractRequestContext.java (working copy)
@@ -263,10 +263,38 @@
     }

     Splittable encode(Object obj) {
-      Splittable value;
       if (obj == null) {
         return Splittable.NULL;
- } else if (obj.getClass().isEnum() && getAutoBeanFactory() instanceof EnumMap) {
+      } else if (obj instanceof Collection) {
+        return collectionEncode(obj);
+      }
+      return nonCollectionEncode(obj);
+    }
+
+    private Splittable collectionEncode(Object obj) {
+      assert (obj instanceof Collection);
+      StringBuffer sb = new StringBuffer();
+      Iterator<?> it = ((Collection<?>) obj).iterator();
+      sb.append("[");
+      if (it.hasNext()) {
+        sb.append(nonCollectionEncode(it.next()));
+        while (it.hasNext()) {
+          sb.append(",");
+          sb.append(nonCollectionEncode(it.next()));
+        }
+      }
+      sb.append("]");
+
+      return StringQuoter.split(sb.toString());
+    }
+
+    private Splittable nonCollectionEncode(Object obj) {
+      if (obj instanceof Collection) {
+        throw new RuntimeException(
+ "Unable to encode request as JSON payload; Request methods must have parameters of the form List<T> or Set<T>, where T is a scalar (non-collection) type.");
+      }
+      Splittable value;
+ if (obj.getClass().isEnum() && getAutoBeanFactory() instanceof EnumMap) { value = ValueCodex.encode(((EnumMap) getAutoBeanFactory()).getToken((Enum<?>) obj));
       } else if (ValueCodex.canDecode(obj.getClass())) {
         value = ValueCodex.encode(obj);
@@ -325,8 +353,8 @@
       if (response.getGeneralFailure() != null) {
         ServerFailureMessage failure = response.getGeneralFailure();
         ServerFailure fail =
- new ServerFailure(failure.getMessage(), failure.getExceptionType(), failure
-                .getStackTrace(), failure.isFatal());
+ new ServerFailure(failure.getMessage(), failure.getExceptionType(),
+                failure.getStackTrace(), failure.isFatal());

         fail(receiver, fail);
         return;
@@ -431,7 +459,7 @@
     public Path getPropertyPath() {
       return new Path() {
         public Iterator<Node> iterator() {
-          return Collections.<Node> emptyList().iterator();
+          return Collections.<Node>emptyList().iterator();
         }

         @Override
@@ -463,8 +491,8 @@
   }

private static final WriteOperation[] DELETE_ONLY = {WriteOperation.DELETE};
-  private static final WriteOperation[] PERSIST_AND_UPDATE = {
-      WriteOperation.PERSIST, WriteOperation.UPDATE};
+ private static final WriteOperation[] PERSIST_AND_UPDATE = {WriteOperation.PERSIST,
+      WriteOperation.UPDATE};
private static final WriteOperation[] UPDATE_ONLY = {WriteOperation.UPDATE};
   private static int payloadId = 100;

@@ -667,12 +695,12 @@
    * @param clazz The proxy type
    * @param id The id to be assigned to the new proxy
* @param useAppendedContexts if {@code true} use the AutoBeanFactory types
-   *          associated with any contexts that have been passed into
- * {@link #append(RequestContext)}. If {@code false}, this method
-   *          will only create proxy types reachable from the implemented
-   *          RequestContext interface.
+   *        associated with any contexts that have been passed into
+ * {@link #append(RequestContext)}. If {@code false}, this method will
+   *        only create proxy types reachable from the implemented
+   *        RequestContext interface.
    * @throws IllegalArgumentException if the requested proxy type cannot be
-   *           created
+   *         created
    */
protected <T extends BaseProxy> AutoBean<T> createProxy(Class<T> clazz, SimpleProxyId<T> id,
       boolean useAppendedContexts) {
@@ -949,7 +977,7 @@
SimpleProxyId<Q> toReturn = (SimpleProxyId<Q>) state.syntheticIds.get(syntheticId);
     if (toReturn == null) {
       toReturn =
- state.requestFactory.allocateId(state.requestFactory.<Q> getTypeFromToken(typeToken)); + state.requestFactory.allocateId(state.requestFactory.<Q>getTypeFromToken(typeToken));
       state.syntheticIds.put(syntheticId, toReturn);
     }
     return toReturn;
@@ -1011,7 +1039,7 @@
           CollectionPropertyContext ctx) {
         // javac generics bug
         value =
- AutoBeanUtils.<Collection<?>, Collection<?>> getAutoBean((Collection<?>) values + AutoBeanUtils.<Collection<?>, Collection<?>>getAutoBean((Collection<?>) values
                 .get(propertyName));
         if (value != null) {
           Collection<Object> collection;


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

Reply via email to