diff --git a/gson/src/main/java/com/google/gson/JsonArray.java b/gson/src/main/java/com/google/gson/JsonArray.java index b3eb3598..a79f5df4 100644 --- a/gson/src/main/java/com/google/gson/JsonArray.java +++ b/gson/src/main/java/com/google/gson/JsonArray.java @@ -63,6 +63,18 @@ public final class JsonArray extends JsonElement implements Iterable entry : result.members.entrySet()) { + entry.setValue(entry.getValue().deepCopy()); + } + return result; + } + /** * Returns a set of members of this object. The set is ordered, and the order is in which the * elements were added. diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java index 2caae92d..4d2cedae 100644 --- a/gson/src/main/java/com/google/gson/JsonPrimitive.java +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -101,6 +101,10 @@ public final class JsonPrimitive extends JsonElement { } } + @Override JsonElement deepCopy() { + return this; // immutable! + } + /** * Check whether this primitive contains a boolean value. * diff --git a/gson/src/test/java/com/google/gson/JsonArrayTest.java b/gson/src/test/java/com/google/gson/JsonArrayTest.java index 6c8ddf3e..6692ea5c 100644 --- a/gson/src/test/java/com/google/gson/JsonArrayTest.java +++ b/gson/src/test/java/com/google/gson/JsonArrayTest.java @@ -49,4 +49,37 @@ public final class JsonArrayTest extends TestCase { assertFalse(a.equals(b)); assertFalse(b.equals(a)); } + + public void testDeepCopy() { + JsonObject v1 = new JsonObject(); + v1.add("k", new JsonPrimitive("v")); + JsonNull v2 = JsonNull.INSTANCE; + JsonPrimitive v3 = new JsonPrimitive("abc"); + JsonArray v4 = new JsonArray(); + v4.add(new JsonPrimitive("def")); + + JsonArray array = new JsonArray(); + array.add(v1); + array.add(v2); + array.add(v3); + array.add(v4); + + // the deep copy must be equal + JsonArray deepCopy = array.deepCopy(); + assertEquals(array, deepCopy); + + // collections must be copied by value + JsonObject d1 = deepCopy.get(0).getAsJsonObject(); + assertEquals(v1, d1); + assertTrue(v1 != d1); + JsonArray d4 = deepCopy.get(3).getAsJsonArray(); + assertEquals(v4, d4); + assertTrue(v4 != d4); + + // collections should themselves be deeply immutable + v1.add("k2", new JsonPrimitive("v2")); + assertEquals(1, d1.entrySet().size()); + v4.add(new JsonPrimitive("ghi")); + assertEquals(1, d4.size()); + } } diff --git a/gson/src/test/java/com/google/gson/JsonObjectTest.java b/gson/src/test/java/com/google/gson/JsonObjectTest.java index d0747a6e..720c466d 100644 --- a/gson/src/test/java/com/google/gson/JsonObjectTest.java +++ b/gson/src/test/java/com/google/gson/JsonObjectTest.java @@ -156,4 +156,37 @@ public class JsonObjectTest extends TestCase { assertFalse(a.equals(b)); assertFalse(b.equals(a)); } + + public void testDeepCopy() { + JsonObject v1 = new JsonObject(); + v1.add("k", new JsonPrimitive("v")); + JsonNull v2 = JsonNull.INSTANCE; + JsonPrimitive v3 = new JsonPrimitive("abc"); + JsonArray v4 = new JsonArray(); + v4.add(new JsonPrimitive("def")); + + JsonObject object = new JsonObject(); + object.add("1", v1); + object.add("2", v2); + object.add("3", v3); + object.add("4", v4); + + // the deep copy must be equal + JsonObject deepCopy = object.deepCopy(); + assertEquals(object, deepCopy); + + // collections must be copied by value + JsonObject d1 = deepCopy.get("1").getAsJsonObject(); + assertEquals(v1, d1); + assertTrue(v1 != d1); + JsonArray d4 = deepCopy.get("4").getAsJsonArray(); + assertEquals(v4, d4); + assertTrue(v4 != d4); + + // collections should themselves be deeply immutable + v1.add("k2", new JsonPrimitive("v2")); + assertEquals(1, d1.entrySet().size()); + v4.add(new JsonPrimitive("ghi")); + assertEquals(1, d4.size()); + } }