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); 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. * Reverses the elements of the array.
*/ */

View File

@ -235,7 +235,7 @@ public abstract class JsonElement {
public int getAsInt() { public int getAsInt() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** /**
* convenience method to get this element as a primitive byte value. * convenience method to get this element as a primitive byte value.
* *
@ -249,7 +249,7 @@ public abstract class JsonElement {
public byte getAsByte() { public byte getAsByte() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/** /**
* convenience method to get this element as a primitive character value. * convenience method to get this element as a primitive character value.
* *
@ -318,6 +318,11 @@ public abstract class JsonElement {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
/**
* Returns a deep copy of this. Immutable values can return this.
*/
abstract JsonElement deepCopy();
/** /**
* Returns a String representation of this element. * Returns a String representation of this element.
* *

View File

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

View File

@ -124,6 +124,18 @@ public final class JsonObject extends JsonElement {
return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value); 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 * Returns a set of members of this object. The set is ordered, and the order is in which the
* elements were added. * 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. * 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(a.equals(b));
assertFalse(b.equals(a)); 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(a.equals(b));
assertFalse(b.equals(a)); 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());
}
} }