Repository: johnzon
Updated Branches:
  refs/heads/master 66ee778e8 -> 174ffa5ba


JOHNZON-103 add createMergeDiff handling


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

Branch: refs/heads/master
Commit: 174ffa5babf73356af9a273fc7991e7567118102
Parents: 66ee778
Author: Mark Struberg <[email protected]>
Authored: Wed Mar 8 14:08:49 2017 +0100
Committer: Mark Struberg <[email protected]>
Committed: Wed Mar 8 14:08:49 2017 +0100

----------------------------------------------------------------------
 .../java/org/apache/johnzon/core/DiffBase.java  | 34 ++++++++
 .../apache/johnzon/core/JsonMergePatchDiff.java | 81 ++++++++++++++++++++
 .../apache/johnzon/core/JsonMergePatchImpl.java |  5 --
 .../org/apache/johnzon/core/JsonPatchDiff.java  | 21 +----
 .../apache/johnzon/core/JsonProviderImpl.java   |  4 +
 .../johnzon/core/JsonMergeBatchDiffTest.java    | 51 ++++++++++++
 6 files changed, 173 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/johnzon-core/src/main/java/org/apache/johnzon/core/DiffBase.java
----------------------------------------------------------------------
diff --git a/johnzon-core/src/main/java/org/apache/johnzon/core/DiffBase.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/DiffBase.java
new file mode 100644
index 0000000..d6abfdf
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/DiffBase.java
@@ -0,0 +1,34 @@
+/*
+ * 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 javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.JsonValue;
+
+/**
+ * Commonly used methods for diffs
+ */
+class DiffBase {
+    protected boolean isJsonObject(JsonValue jsonValue) {
+        return jsonValue instanceof JsonObject;
+    }
+
+    protected boolean isJsonArray(JsonValue targetValue) {
+        return targetValue instanceof JsonArray;
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
new file mode 100644
index 0000000..5175e8d
--- /dev/null
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchDiff.java
@@ -0,0 +1,81 @@
+/*
+ * 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.JsonMergePatch;
+import javax.json.JsonObject;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonValue;
+
+/**
+ * Creates a JsonMergePatch as diff between two JsonValues
+ */
+class JsonMergePatchDiff extends DiffBase {
+    private final JsonValue source;
+    private final JsonValue target;
+
+    public JsonMergePatchDiff(JsonValue source, JsonValue target) {
+        this.source = source;
+        this.target = target;
+    }
+
+    public JsonMergePatch calculateDiff() {
+        return new JsonMergePatchImpl(diff(source, target));
+    }
+
+    private JsonValue diff(JsonValue source, JsonValue target) {
+        JsonObjectBuilder builder = new JsonObjectBuilderImpl();
+
+        if (isJsonObject(source) && isJsonObject(target)) {
+            JsonObject srcObj = source.asJsonObject();
+            JsonObject targetObj = target.asJsonObject();
+            for (Map.Entry<String, JsonValue> sourceEntry : srcObj.entrySet()) 
{
+                String attributeName = sourceEntry.getKey();
+                if (targetObj.containsKey(attributeName)) {
+                    // compare the attribute values
+                    JsonValue attribDiff = diff(sourceEntry.getValue(), 
targetObj.get(attributeName));
+                    if (!JsonValue.EMPTY_JSON_OBJECT.equals(attribDiff)) {
+                        builder.add(attributeName, attribDiff);
+                    }
+                } else {
+                    // attribute got removed
+                    builder.add(attributeName, JsonValue.NULL);
+                }
+            }
+
+            for (Map.Entry<String, JsonValue> targetEntry : 
targetObj.entrySet()) {
+                String attributeName = targetEntry.getKey();
+                if (!srcObj.containsKey(attributeName)) {
+                    // add operation
+                    builder.add(attributeName, targetEntry.getValue());
+                }
+            }
+
+            return builder.build();
+        } else if (source.equals(target)) {
+            // if the two objects are identical, then return an empty patch
+            return JsonValue.EMPTY_JSON_OBJECT;
+        } else {
+            // as defined in the RFC anything else than comparing JsonObjects 
will result
+            // in completely replacing the source with the target
+            // That means our target is the patch.
+            return target;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/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
index a28c3d2..b3f55c6 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonMergePatchImpl.java
@@ -19,7 +19,6 @@ 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;
@@ -43,10 +42,6 @@ public class JsonMergePatchImpl implements JsonMergePatch {
     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();

http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java
index bab7bd1..301a775 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonPatchDiff.java
@@ -17,7 +17,6 @@
 package org.apache.johnzon.core;
 
 import java.util.Map;
-import java.util.Set;
 
 import javax.json.JsonArray;
 import javax.json.JsonObject;
@@ -29,7 +28,7 @@ import javax.json.JsonValue;
 /**
  * Create a diff from a source and target JsonStructure
  */
-class JsonPatchDiff {
+class JsonPatchDiff extends DiffBase {
 
     private final JsonStructure source;
     private final JsonStructure target;
@@ -48,7 +47,6 @@ class JsonPatchDiff {
     }
 
     private void diff(JsonPatchBuilder patchBuilder, String basePath, 
JsonValue source, JsonValue target) {
-
         if (isJsonObject(source) && isJsonObject(target)) {
             diffJsonObjects(patchBuilder, basePath + "/", (JsonObject) source, 
(JsonObject) target);
         } else if (isJsonArray(source) && isJsonArray(target)) {
@@ -59,9 +57,7 @@ class JsonPatchDiff {
     }
 
     private void diffJsonArray(JsonPatchBuilder patchBuilder, String basePath, 
JsonArray source, JsonArray target) {
-
         for (int i = 0; i < source.size(); i++) {
-
             JsonValue sourceValue = source.get(i);
 
             if (target.size() <= i) {
@@ -82,10 +78,8 @@ class JsonPatchDiff {
     }
 
     private void diffJsonObjects(JsonPatchBuilder patchBuilder, String 
basePath, JsonObject source, JsonObject target) {
-        Set<Map.Entry<String, JsonValue>> sourceEntries = source.entrySet();
-
-        for (Map.Entry<String, JsonValue> sourceEntry : sourceEntries) {
 
+        for (Map.Entry<String, JsonValue> sourceEntry : source.entrySet()) {
             String attributeName = sourceEntry.getKey();
 
             if (target.containsKey(attributeName)) {
@@ -96,8 +90,7 @@ class JsonPatchDiff {
             }
         }
 
-        Set<Map.Entry<String, JsonValue>> targetEntries = target.entrySet();
-        for (Map.Entry<String, JsonValue> targetEntry : targetEntries) {
+        for (Map.Entry<String, JsonValue> targetEntry : target.entrySet()) {
             if (!source.containsKey(targetEntry.getKey())) {
                 patchBuilder.add(basePath + 
JsonPointerUtil.encode(targetEntry.getKey()), targetEntry.getValue());
             }
@@ -106,12 +99,4 @@ class JsonPatchDiff {
     }
 
 
-    private static boolean isJsonObject(JsonValue jsonValue) {
-        return jsonValue instanceof JsonObject;
-    }
-
-    private static boolean isJsonArray(JsonValue targetValue) {
-        return targetValue instanceof JsonArray;
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/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 a5d0c39..909d0ba 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
@@ -373,5 +373,9 @@ public class JsonProviderImpl extends JsonProvider 
implements Serializable {
             return new JsonMergePatchImpl(patch);
         }
 
+        @Override
+        public JsonMergePatch createMergeDiff(JsonValue source, JsonValue 
target) {
+            return new JsonMergePatchDiff(source, target).calculateDiff();
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/johnzon/blob/174ffa5b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchDiffTest.java
----------------------------------------------------------------------
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchDiffTest.java
 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchDiffTest.java
new file mode 100644
index 0000000..a2c7c3b
--- /dev/null
+++ 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonMergeBatchDiffTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.io.StringReader;
+
+import javax.json.Json;
+import javax.json.JsonMergePatch;
+import javax.json.JsonObject;
+
+import org.junit.Assert;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class JsonMergeBatchDiffTest {
+
+    @Test
+    public void testAddDiff() {
+        // {"a":"xa"}
+        String jsonA = "{\"a\":\"xa\"}";
+
+        // {"a":"xa","b":"xb"}
+        String jsonB = "{\"a\":\"xa\",\"b\":\"xb\"}";
+
+        // this results in 1 diff operations:
+        // adding "b"
+        JsonMergePatch jsonMergePatch = 
Json.createMergeDiff(Json.createReader(new StringReader(jsonA)).readObject(),
+                                                             
Json.createReader(new StringReader(jsonB)).readObject());
+        assertNotNull(jsonMergePatch);
+        JsonObject patchJson = jsonMergePatch.toJsonValue().asJsonObject();
+        assertNotNull(patchJson);
+        assertEquals(1, patchJson.entrySet().size());
+        Assert.assertEquals("xb", patchJson.getString("b"));
+    }
+
+}

Reply via email to