Use identity semantics when canonicalizing JsonSplittable instances.
This is necessary to support Android, where the org.json arrays appear to have value-based equality.
http://code.google.com/p/google-web-toolkit/issues/detail?id=6390
Patch by: bobv
Review by: rjrjr
Review at http://gwt-code-reviews.appspot.com/1451805
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10252 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/web/bindery/autobean/vm/impl/JsonSplittable.java b/user/src/com/google/web/bindery/autobean/vm/impl/JsonSplittable.java
index 8fdad79..4ff8d07 100644
--- a/user/src/com/google/web/bindery/autobean/vm/impl/JsonSplittable.java
+++ b/user/src/com/google/web/bindery/autobean/vm/impl/JsonSplittable.java
@@ -15,6 +15,7 @@
*/
package com.google.web.bindery.autobean.vm.impl;
+import com.google.gwt.core.client.impl.WeakMapping;
import com.google.web.bindery.autobean.shared.Splittable;
import com.google.web.bindery.autobean.shared.impl.HasSplittable;
import com.google.web.bindery.autobean.shared.impl.StringQuoter;
@@ -23,28 +24,18 @@
import org.json.JSONException;
import org.json.JSONObject;
-import java.lang.ref.Reference;
-import java.lang.ref.WeakReference;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.WeakHashMap;
/**
* Uses the org.json packages to slice and dice request payloads.
*/
public class JsonSplittable implements Splittable, HasSplittable {
- /**
- * Ensures that the same JsonSplittable will be returned for a given backing
- * JSONObject.
- */
- private static final Map<Object, Reference<JsonSplittable>> canonical =
- new WeakHashMap<Object, Reference<JsonSplittable>>();
-
public static JsonSplittable create() {
return new JsonSplittable(new JSONObject());
}
@@ -306,13 +297,19 @@
if (JSONObject.NULL.equals(object)) {
return null;
}
- Reference<JsonSplittable> ref = canonical.get(object);
- JsonSplittable seen = ref == null ? null : ref.get();
+ /*
+ * Maintain a 1:1 mapping between object instances and JsonSplittables.
+ * Doing this with a WeakHashMap doesn't work on Android, since its org.json
+ * arrays appear to have value-based equality.
+ */
+ JsonSplittable seen = (JsonSplittable) WeakMapping.get(object, JsonSplittable.class.getName());
if (seen == null) {
if (object instanceof JSONObject) {
seen = new JsonSplittable((JSONObject) object);
+ WeakMapping.set(object, JsonSplittable.class.getName(), seen);
} else if (object instanceof JSONArray) {
seen = new JsonSplittable((JSONArray) object);
+ WeakMapping.set(object, JsonSplittable.class.getName(), seen);
} else if (object instanceof String) {
seen = new JsonSplittable(object.toString());
} else if (object instanceof Number) {
@@ -322,7 +319,6 @@
} else {
throw new RuntimeException("Unhandled type " + object.getClass());
}
- canonical.put(object, new WeakReference<JsonSplittable>(seen));
}
return seen;
}