You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@johnzon.apache.org by st...@apache.org on 2017/02/24 12:07:21 UTC

[15/26] johnzon git commit: JOHNZON-95 fixed JsonPointer#add for complex objects

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/master
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"));