You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by rs...@apache.org on 2016/11/25 13:36:57 UTC
[1/2] johnzon git commit: JOHNZON-95 fixed JsonPointer#add for
complex objects
Repository: johnzon
Updated Branches:
refs/heads/JSONP-1.1 b0c19662b -> 74cb90884
JOHNZON-95 fixed JsonPointer#add for complex objects
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/24fe453b
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/24fe453b
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/24fe453b
Branch: refs/heads/JSONP-1.1
Commit: 24fe453bd7bed2faa6a812040cbbdf5440a4bcf7
Parents: b0c1966
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Thu Nov 24 18:28:10 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Fri Nov 25 14:05:54 2016 +0100
----------------------------------------------------------------------
.../apache/johnzon/core/JsonPointerImpl.java | 40 ++++++++++-----
.../apache/johnzon/core/JsonPointerTest.java | 51 ++++++++++++++++++++
2 files changed, 78 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/24fe453b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
index 25e5ceb..8057f95 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPointerImpl.java
@@ -35,7 +35,7 @@ import java.util.Map;
public class JsonPointerImpl implements JsonPointer {
private final String jsonPointer;
- private final List<String> referenceTokens = new ArrayList<String>();
+ private final List<String> referenceTokens = new ArrayList<>();
private final String lastReferenceToken;
/**
@@ -150,11 +150,7 @@ public class JsonPointerImpl implements JsonPointer {
return (JsonStructure) value;
}
- if (target instanceof JsonObject) {
- return add((JsonObject) target, value);
- } else {
- return add((JsonArray) target, value);
- }
+ return addInternal(target, value);
}
/**
@@ -173,7 +169,7 @@ public class JsonPointerImpl implements JsonPointer {
public JsonObject add(JsonObject target, JsonValue value) {
validateAdd(target);
- return (JsonObject) add(target, 1, referenceTokens.size() - 1, value);
+ return addInternal(target, value);
}
/**
@@ -192,7 +188,7 @@ public class JsonPointerImpl implements JsonPointer {
public JsonArray add(JsonArray target, JsonValue value) {
validateAdd(target);
- return (JsonArray) add(target, 1, referenceTokens.size() - 1, value);
+ return addInternal(target, value);
}
/**
@@ -336,7 +332,14 @@ public class JsonPointerImpl implements JsonPointer {
}
}
- private JsonValue add(JsonValue jsonValue, int currentPosition, int referencePosition, JsonValue newValue) {
+ private <T extends JsonStructure> T addInternal(T jsonValue, JsonValue newValue) {
+ List<String> currentPath = new ArrayList<>();
+ currentPath.add("");
+
+ return (T) addInternal(jsonValue, newValue, currentPath);
+ }
+
+ private JsonValue addInternal(JsonValue jsonValue, JsonValue newValue, List<String> currentPath) {
if (jsonValue instanceof JsonObject) {
JsonObject jsonObject = (JsonObject) jsonValue;
JsonObjectBuilder objectBuilder = Json.createObjectBuilder();
@@ -345,8 +348,13 @@ public class JsonPointerImpl implements JsonPointer {
objectBuilder.add(lastReferenceToken, newValue);
} else {
for (Map.Entry<String, JsonValue> entry : jsonObject.entrySet()) {
- objectBuilder.add(entry.getKey(), add(entry.getValue(), currentPosition + 1, referencePosition, newValue));
- if (currentPosition == referencePosition) {
+
+ currentPath.add(entry.getKey());
+ objectBuilder.add(entry.getKey(), addInternal(entry.getValue(), newValue, currentPath));
+ currentPath.remove(entry.getKey());
+
+ if (currentPath.size() == referenceTokens.size() - 1 &&
+ currentPath.get(currentPath.size() - 1).equals(referenceTokens.get(referenceTokens.size() - 2))) {
objectBuilder.add(lastReferenceToken, newValue);
}
}
@@ -357,7 +365,9 @@ public class JsonPointerImpl implements JsonPointer {
JsonArrayBuilder arrayBuilder = Json.createArrayBuilder();
int arrayIndex = -1;
- if (currentPosition == referencePosition) {
+ if (currentPath.size() == referenceTokens.size() - 1 &&
+ currentPath.get(currentPath.size() - 1).equals(referenceTokens.get(referenceTokens.size() - 2))) {
+
arrayIndex = getArrayIndex(lastReferenceToken, jsonArray, true);
}
@@ -369,7 +379,11 @@ public class JsonPointerImpl implements JsonPointer {
if (i == jsonArraySize) {
break;
}
- arrayBuilder.add(add(jsonArray.get(i), currentPosition + 1, referencePosition, newValue));
+
+ String path = String.valueOf(i);
+ currentPath.add(path);
+ arrayBuilder.add(addInternal(jsonArray.get(i), newValue, currentPath));
+ currentPath.remove(path);
}
return arrayBuilder.build();
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/24fe453b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
index 57d52b9..5c345e8 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPointerTest.java
@@ -26,12 +26,15 @@ import javax.json.JsonException;
import javax.json.JsonObject;
import javax.json.JsonPointer;
import javax.json.JsonReader;
+import javax.json.JsonString;
import javax.json.JsonStructure;
import javax.json.JsonValue;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
public class JsonPointerTest {
@@ -607,6 +610,54 @@ public class JsonPointerTest {
assertFalse(jsonPointer1.equals(jsonPointer2));
}
+ @Test
+ public void testAddObjectMemberToNestedObject() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("object1", Json.createObjectBuilder()
+ .add("key1", "value1"))
+ .add("object2", Json.createObjectBuilder()
+ .add("key2", "value2"))
+ .build();
+
+ JsonPointerImpl pointer = new JsonPointerImpl("/object2/key3");
+
+ JsonObject pointered = pointer.add(object, new JsonStringImpl("value3"));
+ assertNotNull(pointered);
+ assertNotSame(object, pointered);
+
+ JsonObject object1 = pointered.getJsonObject("object1");
+ assertEquals(1, object1.size());
+ assertEquals("value1", object1.getString("key1"));
+
+ JsonObject object2 = pointered.getJsonObject("object2");
+ assertEquals(2, object2.size());
+ assertEquals("value2", object2.getString("key2"));
+ assertEquals("value3", object2.getString("key3"));
+ }
+
+ @Test
+ public void testGetValueFromNestedObject() {
+
+ JsonObject family = Json.createObjectBuilder()
+ .add("family", Json.createObjectBuilder()
+ .add("father", Json.createObjectBuilder()
+ .add("name", "Anakin Skywalker"))
+ .add("mother", Json.createObjectBuilder()
+ .add("name", "Padme Amidala"))
+ .add("children", Json.createArrayBuilder()
+ .add(Json.createObjectBuilder()
+ .add("name", "Luke Skywalker"))
+ .add(Json.createObjectBuilder()
+ .add("name", "Leia Skywalker"))))
+ .build();
+
+ JsonValue padme = new JsonPointerImpl("/family/mother/name").getValue(family);
+ assertTrue("padme must be instanceOf JsonString", padme instanceof JsonString);
+ assertEquals("Padme Amidala", ((JsonString) padme).getString());
+ }
+
+
private JsonStructure getJsonDocument() {
JsonReader reader = Json.createReaderFactory(Collections.<String, Object>emptyMap()).createReader(
Thread.currentThread().getContextClassLoader().getResourceAsStream("json/jsonPointerTest.json"));
[2/2] johnzon git commit: JOHNZON-97 implemented JsonPatch
Posted by rs...@apache.org.
JOHNZON-97 implemented JsonPatch
Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/74cb9088
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/74cb9088
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/74cb9088
Branch: refs/heads/JSONP-1.1
Commit: 74cb90884b51861361929cb6f5bcb32ca154a96c
Parents: 24fe453
Author: Reinhard Sandtner <rs...@apache.org>
Authored: Thu Nov 24 00:11:42 2016 +0100
Committer: Reinhard Sandtner <rs...@apache.org>
Committed: Fri Nov 25 14:35:56 2016 +0100
----------------------------------------------------------------------
.../org/apache/johnzon/core/JsonPatchImpl.java | 23 +
.../org/apache/johnzon/core/JsonPatchTest.java | 920 ++++++++++++++++++-
2 files changed, 931 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/johnzon/blob/74cb9088/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
index 352af88..0aaedf9 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchImpl.java
@@ -22,6 +22,7 @@ package org.apache.johnzon.core;
import java.util.Arrays;
import java.util.List;
+import javax.json.JsonException;
import javax.json.JsonPatch;
import javax.json.JsonPointer;
import javax.json.JsonStructure;
@@ -42,12 +43,34 @@ class JsonPatchImpl implements JsonPatch {
//X TODO JsonPointer should use generics like JsonPatch
JsonStructure patched = target;
+
for (PatchValue patch : patches) {
switch (patch.operation) {
case ADD:
patched = patch.path.add(patched, patch.value);
break;
+ case REMOVE:
+ patched = patch.path.remove(patched);
+ break;
+ case REPLACE:
+ // first remove the existing element and then add the new value
+ patched = patch.path.add(patch.path.remove(patched), patch.value);
+ break;
+ case MOVE:
+ JsonValue valueToMove = patch.from.getValue(patched);
+ patched = patch.path.add(patch.from.remove(patched), valueToMove);
+ break;
+ case COPY:
+ JsonValue toCopy = patch.from.getValue(patched);
+ patched = patch.path.add(patched, toCopy);
+ break;
+ case TEST:
+ JsonValue toTest = patch.path.getValue(patched);
+ if (!toTest.equals(patch.value)) {
+ throw new JsonException("JsonPatchOperation.TEST fails! Values are not equal");
+ }
+ break;
default:
throw new IllegalStateException("unsupported operation: " + patch.operation);
}
http://git-wip-us.apache.org/repos/asf/johnzon/blob/74cb9088/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
index a303893..b4665ed 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchTest.java
@@ -18,16 +18,22 @@
*/
package org.apache.johnzon.core;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import java.io.StringReader;
-import java.io.StringWriter;
+import org.junit.Test;
import javax.json.Json;
+import javax.json.JsonArray;
+import javax.json.JsonException;
import javax.json.JsonObject;
+import javax.json.JsonStructure;
+import javax.json.JsonValue;
+import java.io.StringReader;
+import java.io.StringWriter;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
public class JsonPatchTest {
@@ -37,21 +43,911 @@ public class JsonPatchTest {
JsonObject object = Json.createReader(new StringReader("{ \"foo\": \"bar\" }"))
.readObject();
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/baz"),
+ null, // no from
+ new JsonStringImpl("qux")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertEquals("bar", patched.getString("foo"));
+ assertEquals("qux", patched.getString("baz"));
+
+ assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", toJsonString(patched));
+ }
+
+ @Test
+ public void testAddArrayElementWithIndex() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("baz"))
+ .build();
JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
- Json.createJsonPointer("/baz"),
- null, // no from
- new JsonStringImpl("qux")));
+ Json.createJsonPointer("/foo/1"),
+ null, // no from
+ new JsonStringImpl("qux")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertNotNull(array);
+ assertEquals("bar", array.getString(0));
+ assertEquals("qux", array.getString(1));
+ assertEquals("baz", array.getString(2));
+
+ assertEquals("{\"foo\":[\"bar\",\"qux\",\"baz\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testAddArrayElementAppend() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("baz"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/foo/-"),
+ null, // no from
+ new JsonStringImpl("qux")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertNotNull(array);
+ assertEquals("bar", array.getString(0));
+ assertEquals("baz", array.getString(1));
+ assertEquals("qux", array.getString(2));
+
+ assertEquals("{\"foo\":[\"bar\",\"baz\",\"qux\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testAddArrayElementPlainArray() {
+ JsonArray array = Json.createArrayBuilder()
+ .add("bar")
+ .add("baz")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/-"),
+ null, // no from
+ new JsonStringImpl("qux")));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertNotSame(array, patched);
+ assertEquals("bar", patched.getString(0));
+ assertEquals("baz", patched.getString(1));
+ assertEquals("qux", patched.getString(2));
+
+ assertEquals("[\"bar\",\"baz\",\"qux\"]", toJsonString(patched));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testAddNonexistentTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/baz/bat"),
+ null, // no from
+ new JsonStringImpl("qux")));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testAddArrayIndexOutOfBounds() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/5"),
+ null,
+ new JsonStringImpl("baz")));
+
+ patch.apply(array);
+ }
+
+
+ @Test
+ public void testRemoveObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("baz", "qux")
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/baz"),
+ null,
+ null));
JsonObject patched = patch.apply(object);
assertNotNull(patched);
assertEquals("bar", patched.getString("foo"));
+ assertFalse("patched JsonObject must no contain \"baz\"", patched.containsKey("baz"));
+
+ assertEquals("{\"foo\":\"bar\"}", toJsonString(patched));
+ }
+
+ @Test
+ public void testRemoveArrayElement() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/foo/1"),
+ null,
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertNotNull(array);
+ assertEquals(2, array.size());
+ assertEquals("bar", array.getString(0));
+ assertEquals("baz", array.getString(1));
+
+ assertEquals("{\"foo\":[\"bar\",\"baz\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testRemoveArrayElementPlainArray() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .add("baz")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/1"),
+ null,
+ null));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertEquals(2, patched.size());
+ assertEquals("bar", patched.getString(0));
+ assertEquals("baz", patched.getString(1));
+
+ assertEquals("[\"bar\",\"baz\"]", toJsonString(patched));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testRemoveObjectElementNonexistentTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .add("baz", "qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/nomatch"),
+ null,
+ null));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testRemoveArrayElementIndexOutOfBounds() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/5"),
+ null,
+ null));
+
+ patch.apply(array);
+ }
+
+
+ @Test
+ public void testReplacingObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("baz", "qux")
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+ Json.createJsonPointer("/baz"),
+ null,
+ new JsonStringImpl("boo")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+ assertEquals("boo", patched.getString("baz"));
+ assertEquals("bar", patched.getString("foo"));
+
+ assertEquals("{\"foo\":\"bar\",\"baz\":\"boo\"}", toJsonString(patched));
+ }
+
+ @Test
+ public void testReplacingArrayElement() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("qux"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+ Json.createJsonPointer("/foo/1"),
+ null,
+ new JsonStringImpl("boo")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertNotNull(array);
+ assertNotSame(object.getJsonArray("foo"), array);
+ assertEquals(2, array.size());
+ assertEquals("bar", array.getString(0));
+ assertEquals("boo", array.getString(1));
+
+ assertEquals("{\"foo\":[\"bar\",\"boo\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testReplacingArrayElementPlainArray() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("bar")
+ .add("qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+ Json.createJsonPointer("/0"),
+ null,
+ new JsonStringImpl("boo")));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertNotSame(array, patched);
+ assertEquals(2, patched.size());
+ assertEquals("boo", patched.getString(0));
+ assertEquals("qux", patched.getString(1));
+
+ assertEquals("[\"boo\",\"qux\"]", toJsonString(patched));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testReplacingObjectMemberNonexistingTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+ Json.createJsonPointer("/nomatch"),
+ null,
+ new JsonStringImpl("notneeded")));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testReplacingArrayElementIndexOutOfBounds() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("foo")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.REPLACE,
+ Json.createJsonPointer("/1"),
+ null,
+ new JsonStringImpl("notneeded")));
+
+ patch.apply(array);
+ }
+
+
+ @Test
+ public void testMovingObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createObjectBuilder()
+ .add("bar", "baz")
+ .add("waldo", "fred"))
+ .add("qux", Json.createObjectBuilder()
+ .add("corge", "grault"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/qux/thud"),
+ Json.createJsonPointer("/foo/waldo"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+
+ JsonObject foo = patched.getJsonObject("foo");
+ assertNotNull(foo);
+ assertEquals("baz", foo.getString("bar"));
+ assertFalse("JsonObject with key 'foo' must not contain 'waldo'", foo.containsKey("waldo"));
+
+ JsonObject qux = patched.getJsonObject("qux");
+ assertNotNull(qux);
+ assertEquals("grault", qux.getString("corge"));
+ assertEquals("fred", qux.getString("thud"));
+
+ assertEquals("{\"foo\":{\"bar\":\"baz\"},\"qux\":{\"corge\":\"grault\",\"thud\":\"fred\"}}", toJsonString(patched));
+ }
+
+ @Test
+ public void testMovingArrayElement() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("all")
+ .add("grass")
+ .add("cows")
+ .add("eat"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/foo/3"),
+ Json.createJsonPointer("/foo/1"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertNotNull(array);
+ assertEquals("all", array.getString(0));
+ assertEquals("cows", array.getString(1));
+ assertEquals("eat", array.getString(2));
+ assertEquals("grass", array.getString(3));
+
+ assertEquals("{\"foo\":[\"all\",\"cows\",\"eat\",\"grass\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testMovingArrayElementPlainArray() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("two")
+ .add("three")
+ .add("four")
+ .add("one")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/0"),
+ Json.createJsonPointer("/3"),
+ null));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertNotSame(array, patched);
+ assertEquals("one", patched.getString(0));
+ assertEquals("two", patched.getString(1));
+ assertEquals("three", patched.getString(2));
+ assertEquals("four", patched.getString(3));
+ }
+
+ @Test
+ public void testMovingArrayElementToObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("one")
+ .add("two")
+ .add("dog"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/bar"),
+ Json.createJsonPointer("/foo/2"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertEquals(2, patched.size());
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertEquals(2, array.size());
+ assertEquals("one", array.getString(0));
+ assertEquals("two", array.getString(1));
+
+ assertEquals("dog", patched.getString("bar"));
+
+ assertEquals("{\"foo\":[\"one\",\"two\"],\"bar\":\"dog\"}", toJsonString(patched));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testMovingObjectMemberNonexistingFrom() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/baz"),
+ Json.createJsonPointer("/nomatch"),
+ null));
+
+ patch.apply(object);
+
+ }
+
+ @Test(expected = JsonException.class)
+ public void testMovingObjectMemberNonexistingTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/nomatch/child"),
+ Json.createJsonPointer("/foo"),
+ null));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testMovingObjectMemberMoveToSubFrom() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("object", Json.createObjectBuilder()
+ .add("key", "value"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/object/key"),
+ Json.createJsonPointer("/object"),
+ null));
+
+ patch.apply(object);
+ }
+
+
+ @Test
+ public void testCopyObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/baz"),
+ Json.createJsonPointer("/foo"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertEquals(2, patched.size());
+ assertEquals("bar", patched.getString("foo"));
+ assertEquals("bar", patched.getString("baz"));
+
+ assertEquals("{\"foo\":\"bar\",\"baz\":\"bar\"}", toJsonString(patched));
+ }
+
+ @Test
+ public void testCopyArrayMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("baz"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/foo/-"),
+ Json.createJsonPointer("/foo/0"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+
+ JsonArray array = patched.getJsonArray("foo");
+ assertEquals(3, array.size());
+ assertEquals("bar", array.getString(0));
+ assertEquals("baz", array.getString(1));
+ assertEquals("bar", array.getString(2));
+
+ assertEquals("{\"foo\":[\"bar\",\"baz\",\"bar\"]}", toJsonString(patched));
+ }
+
+ @Test
+ public void testCopyArrayMemberPlainArray() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("foo")
+ .add("bar")
+ .build();
+
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/0"),
+ Json.createJsonPointer("/1"),
+ null));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertNotSame(array, patched);
+ assertEquals(3, patched.size());
+ assertEquals("bar", patched.getString(0));
+ assertEquals("foo", patched.getString(1));
+ assertEquals("bar", patched.getString(2));
+
+ assertEquals("[\"bar\",\"foo\",\"bar\"]", toJsonString(patched));
+ }
+
+ @Test
+ public void testCopyObjectMemberToObjectMember() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("name", "Hugo")
+ .add("partner", Json.createObjectBuilder()
+ .add("name", "Leia")
+ .add("partner", JsonValue.EMPTY_JSON_OBJECT))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/partner/partner/name"),
+ Json.createJsonPointer("/name"),
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+ assertEquals("Hugo", patched.getString("name"));
+
+ JsonObject partner = patched.getJsonObject("partner");
+ assertEquals("Leia", partner.getString("name"));
+
+ JsonObject parent = partner.getJsonObject("partner");
+ assertEquals(patched.getString("name"), parent.getString("name"));
+
+ assertEquals("{\"name\":\"Hugo\",\"partner\":{\"name\":\"Leia\",\"partner\":{\"name\":\"Hugo\"}}}", toJsonString(patched));
+ }
+
+ @Test(expected = JsonException.class)
+ public void testCopyObjectMemberFromNonexistentTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/notneeded"),
+ Json.createJsonPointer("/nomatch"),
+ null));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testCopyObjectMemberToNonexistingTarget() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/path/nomatch"),
+ Json.createJsonPointer("/foo"),
+ null));
+
+ patch.apply(object);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testCopyArrayMemberFromIndexOutOfBounds() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("foo")
+ .add("bar")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/-"),
+ Json.createJsonPointer("/2"),
+ null));
+
+ patch.apply(array);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testCopyArrayMemberToIndexOutOfBounds() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("foo")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/1"),
+ Json.createJsonPointer("/-"),
+ null));
+
+ patch.apply(array);
+ }
+
+
+ @Test
+ public void testTestingObjectMemberValueSuccess() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/foo"),
+ null,
+ new JsonStringImpl("qux")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertSame(object, patched);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testTestingObjectMemberValueFailed() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/foo"),
+ null,
+ Json.createArrayBuilder().build()));
+
+ patch.apply(object);
+ }
+
+ @Test
+ public void testTestingArrayAsObjectMemberSuccess() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("name", "Thor")
+ .add("parents", Json.createArrayBuilder()
+ .add("Odin")
+ .add("Forjgyn"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/parents"),
+ null,
+ Json.createArrayBuilder() // yessss, we really want to create a new JsonArray ;)
+ .add("Odin")
+ .add("Forjgyn")
+ .build()));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertSame(object, patched);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testTestingArrayAsObjectMemberFailed() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("magic", "array")
+ .add("numbers", Json.createArrayBuilder()
+ .add(1)
+ .add(2))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/numbers"),
+ null,
+ Json.createArrayBuilder() // different ordering
+ .add(2)
+ .add(1)
+ .build()));
+
+ patch.apply(object);
+ }
+
+ @Test
+ public void testTestingArrayElementSuccess() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", Json.createArrayBuilder()
+ .add("bar")
+ .add("baz"))
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/foo/1"),
+ null,
+ new JsonStringImpl("baz")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertSame(object, patched);
+ }
+
+ @Test
+ public void testTestingArrayElementPlainArraySuccess() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add("foo")
+ .add("bar")
+ .add("qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/2"),
+ null,
+ new JsonStringImpl("qux")));
+
+ JsonArray patched = patch.apply(array);
+ assertNotNull(patched);
+ assertSame(array, patched);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testTestingArrayElementPlainArrayFailed() {
+
+ JsonArray array = Json.createArrayBuilder()
+ .add(1)
+ .add("2")
+ .add("qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/0"),
+ null,
+ new JsonStringImpl("bar")));
+
+ patch.apply(array);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testTestingObjectMemeberNonexistentTarget() {
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/nomatch"),
+ null,
+ JsonValue.EMPTY_JSON_OBJECT));
+
+ patch.apply(JsonValue.EMPTY_JSON_OBJECT);
+ }
+
+ @Test(expected = JsonException.class)
+ public void testTestingArrayElementIndexOutOfBounds() {
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.TEST,
+ Json.createJsonPointer("/3"),
+ null,
+ JsonValue.EMPTY_JSON_OBJECT));
+
+ patch.apply(JsonValue.EMPTY_JSON_ARRAY);
+ }
+
+
+ @Test
+ public void testAddObjectMemberAlreadyExists() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("foo", "bar")
+ .add("baz", "qux")
+ .build();
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/foo"),
+ null,
+ new JsonStringImpl("abcd")));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+ assertEquals("abcd", patched.getString("foo"));
assertEquals("qux", patched.getString("baz"));
- StringWriter writer = new StringWriter();
- Json.createWriter(writer).write(patched);
+ assertEquals("{\"foo\":\"abcd\",\"baz\":\"qux\"}", toJsonString(patched));
+ }
- assertEquals("{\"foo\":\"bar\",\"baz\":\"qux\"}", writer.toString());
+ @Test
+ public void testAddArrayElementToEmptyArray() {
+
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/-"),
+ null,
+ new JsonStringImpl("foo")));
+
+ JsonArray patched = patch.apply(JsonValue.EMPTY_JSON_ARRAY);
+ assertNotNull(patched);
+ assertEquals(1, patched.size());
+ assertEquals("foo", patched.getString(0));
+ }
+
+ @Test
+ public void testPatchWithMoreOperations() {
+
+ JsonObject object = Json.createObjectBuilder()
+ .add("family", Json.createObjectBuilder()
+ .add("children", JsonValue.EMPTY_JSON_ARRAY))
+ .build();
+
+ // i know this can be done with PatchBuilder but
+ // currently it's not implemented and its fun ;)
+ JsonPatchImpl patch = new JsonPatchImpl(new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/family/father"),
+ null,
+ Json.createObjectBuilder()
+ .add("name", "Gaio Modry Effect")
+ .build()),
+ new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/family/mother"),
+ null,
+ Json.createObjectBuilder()
+ .add("name", "Cassius vom Hause Clarabella")
+ .build()),
+ new JsonPatchImpl.PatchValue(JsonPatchOperation.MOVE,
+ Json.createJsonPointer("/family/children/0"),
+ Json.createJsonPointer("/family/mother"),
+ null),
+ new JsonPatchImpl.PatchValue(JsonPatchOperation.ADD,
+ Json.createJsonPointer("/family/mother"),
+ null,
+ Json.createObjectBuilder()
+ .add("name", "Aimee vom Hause Clarabella")
+ .build()),
+ new JsonPatchImpl.PatchValue(JsonPatchOperation.COPY,
+ Json.createJsonPointer("/pedigree"),
+ Json.createJsonPointer("/family"),
+ null),
+ new JsonPatchImpl.PatchValue(JsonPatchOperation.REMOVE,
+ Json.createJsonPointer("/family"),
+ null,
+ null));
+
+ JsonObject patched = patch.apply(object);
+ assertNotNull(patched);
+ assertNotSame(object, patched);
+
+ JsonObject pedigree = patched.getJsonObject("pedigree");
+ assertEquals("Gaio Modry Effect", pedigree.getJsonObject("father").getString("name"));
+ assertEquals("Aimee vom Hause Clarabella", pedigree.getJsonObject("mother").getString("name"));
+ assertEquals("Cassius vom Hause Clarabella", pedigree.getJsonArray("children").getJsonObject(0).getString("name"));
+
+ assertEquals("{\"pedigree\":{" +
+ "\"children\":[" +
+ "{\"name\":\"Cassius vom Hause Clarabella\"}]," +
+ "\"mother\":{\"name\":\"Aimee vom Hause Clarabella\"}," +
+ "\"father\":{\"name\":\"Gaio Modry Effect\"}}}", toJsonString(patched));
+ }
+
+
+
+ private static String toJsonString(JsonStructure value) {
+ StringWriter writer = new StringWriter();
+ Json.createWriter(writer).write(value);
+ return writer.toString();
}
}