Repository: johnzon
Updated Branches:
  refs/heads/master e2905f9ec -> ea31ad7d2


JOHNZON-96 implement JsonMergePatch


Project: http://git-wip-us.apache.org/repos/asf/johnzon/repo
Commit: http://git-wip-us.apache.org/repos/asf/johnzon/commit/ea31ad7d
Tree: http://git-wip-us.apache.org/repos/asf/johnzon/tree/ea31ad7d
Diff: http://git-wip-us.apache.org/repos/asf/johnzon/diff/ea31ad7d

Branch: refs/heads/master
Commit: ea31ad7d204d27221b89d268c4f89a93ebec41ef
Parents: e2905f9
Author: Mark Struberg <[email protected]>
Authored: Tue Mar 7 22:52:23 2017 +0100
Committer: Mark Struberg <[email protected]>
Committed: Tue Mar 7 22:52:43 2017 +0100

----------------------------------------------------------------------
 .../johnzon/core/JsonMergePatchBuilder.java     |  2 +-
 .../apache/johnzon/core/JsonMergePatchImpl.java | 85 ++++++++++++++++++++
 .../apache/johnzon/core/JsonProviderImpl.java   |  4 +
 .../apache/johnzon/core/JsonMergeBatchTest.java | 56 ++++++++++---
 4 files changed, 136 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/ea31ad7d/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
index 831e82e..2c56a13 100644
--- 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
+++ 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchBuilder.java
@@ -19,7 +19,7 @@ package org.apache.johnzon.core;
 import javax.json.JsonValue;
 
 /**
- * Creates and applies a Json Merge Patch as defined in
+ * Creates a JsonPatchBuilder which will create {@link 
javax.json.JsonMergePatch} as defined in
  * https://tools.ietf.org/html/rfc7396
  */
 public class JsonMergePatchBuilder {

http://git-wip-us.apache.org/repos/asf/johnzon/blob/ea31ad7d/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
new file mode 100644
index 0000000..a28c3d2
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.johnzon.core;
+
+
+import java.util.Map;
+
+import javax.json.JsonArray;
+import javax.json.JsonMergePatch;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+
+/**
+ * @author <a href="mailto:[email protected]";>Mark Struberg</a>
+ */
+public class JsonMergePatchImpl implements JsonMergePatch {
+    private final JsonValue patch;
+
+    public JsonMergePatchImpl(JsonValue patch) {
+        this.patch = patch;
+    }
+
+    @Override
+    public JsonValue apply(JsonValue valueToApplyPatchOn) {
+        return applyPatch(valueToApplyPatchOn, patch);
+    }
+
+    private JsonValue applyPatch(JsonValue valueToApplyPatchOn, JsonValue 
patch) {
+        if (patch == null) {
+            return JsonValue.NULL;
+        } else if (patch instanceof JsonArray) {
+            JsonArray patchArray = patch.asJsonArray();
+            //X TODO
+            throw new UnsupportedOperationException("not yet implemented TODO 
finish JsonArray support.");
+        } else if (patch instanceof JsonObject && valueToApplyPatchOn 
instanceof JsonObject) {
+            // we only apply an actual patch IF both sides are a JsonObject
+            JsonObject patchObject = patch.asJsonObject();
+
+            return applyJsonObjectPatch(valueToApplyPatchOn.asJsonObject(), 
patchObject);
+        } else {
+            // this must be a native JsonValue or JsonObject, so we just 
replace the
+            // the whole original valueToApplyPatchOn with the new jsonValue
+            return patch;
+        }
+    }
+
+    private JsonValue applyJsonObjectPatch(JsonObject jsonObject, JsonObject 
patch) {
+        JsonObjectBuilder builder = new JsonObjectBuilderImpl(jsonObject);
+
+        for (Map.Entry<String, JsonValue> patchAttrib : patch.entrySet()) {
+            String attribName = patchAttrib.getKey();
+            if (patchAttrib.getValue().equals(JsonValue.NULL)) {
+                builder.remove(attribName);
+            } else {
+                JsonValue originalAttrib = jsonObject.get(attribName);
+                if (originalAttrib == null) {
+                    builder.add(attribName, patchAttrib.getValue());
+                } else {
+                    builder.add(attribName, applyPatch(originalAttrib, 
patchAttrib.getValue()));
+                }
+            }
+        }
+        return builder.build();
+    }
+
+    @Override
+    public JsonValue toJsonValue() {
+        return patch;
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/ea31ad7d/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
index c7c8000..190ba05 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonProviderImpl.java
@@ -369,6 +369,10 @@ public class JsonProviderImpl extends JsonProvider 
implements Serializable {
             return new JsonPatchDiff(source, target).calculateDiff();
         }
 
+        public JsonMergePatch createMergePatch(JsonValue patch) {
+            return new JsonMergePatchImpl(patch);
+        }
+
         //X TODO add missing methods
 
     }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/ea31ad7d/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchTest.java
index ff4c078..172921b 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchTest.java
@@ -21,35 +21,71 @@ import java.io.StringReader;
 
 import javax.json.Json;
 import javax.json.JsonMergePatch;
+import javax.json.JsonNumber;
 import javax.json.JsonObject;
+import javax.json.JsonValue;
+import javax.json.spi.JsonProvider;
 
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class JsonMergeBatchTest {
 
+    private JsonProvider json = JsonProvider.provider();
+
     @Test
-    @Ignore(value = "work in progress, TODO finish")
-    public void testSimpleMergePatch() {
-        // {"a":"xa","b","xb"}
-        String source = "{\"a\":\"xa\",\"b\",\"xb\"}";
+    public void testApplyValueOnObject() {
+        // {"a":"xa","b":"xb"}
+        JsonObject source = jsonObjectFrom("{\"a\":\"xa\",\"b\":\"xb\"}");
 
         // {"b":"bNew","c":"xc"}
         // the result after this patch gets applied to source should be 
{"a":"xa","b","bNew","c":"xc"}
-        String patch = "{\"b\":\"bNew\",\"c\":\"xc\"}";
+        JsonValue patch = json.createValue(4711);
+
+        JsonMergePatch jsonMergePatch = Json.createMergePatch(patch);
+        JsonValue patchedValue = jsonMergePatch.apply(source);
+        Assert.assertEquals(4711, ((JsonNumber) patchedValue).intValue());
+    }
+
+    @Test
+    public void testApplyObjectOnValue() {
+        // {"a":"xa","b":"xb"}
+        JsonValue source = json.createValue(4711);
+
+        // {"b":"bNew","c":"xc"}
+        // the result after this patch gets applied to source should be 
{"a":"xa","b","bNew","c":"xc"}
+        JsonObject patch = jsonObjectFrom("{\"a\":\"xa\",\"b\":\"xb\"}");
+
+        JsonMergePatch jsonMergePatch = Json.createMergePatch(patch);
+        JsonValue patchedValue = jsonMergePatch.apply(source);
+        Assert.assertTrue(patchedValue instanceof JsonObject);
+        Assert.assertEquals("xa", patchedValue.asJsonObject().getString("a"));
+        Assert.assertEquals("xb", patchedValue.asJsonObject().getString("b"));
+    }
+
 
-        //X TODO Json.createMergePatch();
+    @Test
+    public void testSimpleJsonObjectMergePatch() {
+        // {"a":"xa","b":"xb"}
+        JsonObject source = jsonObjectFrom("{\"a\":\"xa\",\"b\":\"xb\"}");
 
-        JsonMergePatch jsonMergePatch = 
Json.createMergePatch(Json.createReader(new StringReader(patch)).readObject());
+        // {"b":"bNew","c":"xc"}
+        // the result after this patch gets applied to source should be 
{"a":"xa","b","bNew","c":"xc"}
+        JsonObject patch = jsonObjectFrom("{\"b\":\"bNew\",\"c\":\"xc\"}");
 
-        JsonObject jsonSource = Json.createReader(new 
StringReader(source)).readObject();
+        JsonMergePatch jsonMergePatch = Json.createMergePatch(patch);
 
-        JsonObject jsonTarget = 
jsonMergePatch.apply(jsonSource).asJsonObject();
+
+        JsonObject jsonTarget = jsonMergePatch.apply(source).asJsonObject();
         Assert.assertNotNull(jsonTarget);
         Assert.assertEquals(3, jsonTarget.entrySet().size());
         Assert.assertEquals("xa", jsonTarget.getString("a"));
         Assert.assertEquals("bNew", jsonTarget.getString("b"));
         Assert.assertEquals("xc", jsonTarget.getString("c"));
     }
+
+
+    private JsonObject jsonObjectFrom(String val) {
+        return json.createReader(new StringReader(val)).readObject();
+    }
 }

Reply via email to