Add deepCopy to JsonArray and JsonObject.

Resolves issue 301.
This commit is contained in:
Jesse Wilson 2011-06-17 21:46:28 +00:00
parent aa89773008
commit f74dffc6fd
7 changed files with 105 additions and 2 deletions

View File

@ -63,6 +63,18 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
elements.addAll(array.elements);
}
/**
* Returns a deep copy of this array.
*/
@Override public JsonArray deepCopy() {
JsonArray result = new JsonArray();
result.elements.addAll(elements);
for (int i = 0; i < result.elements.size(); i++) {
result.elements.set(i, result.elements.get(i).deepCopy());
}
return result;
}
/**
* Reverses the elements of the array.
*/

View File

@ -318,6 +318,11 @@ public abstract class JsonElement {
throw new UnsupportedOperationException();
}
/**
* Returns a deep copy of this. Immutable values can return this.
*/
abstract JsonElement deepCopy();
/**
* Returns a String representation of this element.
*

View File

@ -42,6 +42,10 @@ public final class JsonNull extends JsonElement {
// Do nothing
}
@Override JsonElement deepCopy() {
return this; // immutable!
}
@Override
protected void toString(Appendable sb, Escaper escaper) throws IOException {
sb.append("null");

View File

@ -124,6 +124,18 @@ public final class JsonObject extends JsonElement {
return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value);
}
/**
* Returns a deep copy of this object.
*/
@Override public JsonObject deepCopy() {
JsonObject result = new JsonObject();
result.members.putAll(members);
for (Map.Entry<String, JsonElement> 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.

View File

@ -101,6 +101,10 @@ public final class JsonPrimitive extends JsonElement {
}
}
@Override JsonElement deepCopy() {
return this; // immutable!
}
/**
* Check whether this primitive contains a boolean value.
*

View File

@ -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());
}
}

View File

@ -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());
}
}