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