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;
   }