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 <[email protected]> Authored: Thu Nov 24 18:28:10 2016 +0100 Committer: Reinhard Sandtner <[email protected]> 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"));
