This is an automated email from the ASF dual-hosted git repository.

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/johnzon.git


The following commit(s) were added to refs/heads/master by this push:
     new 34a8607  JOHNZON-304 Json.createDiff does not handle properly arrays 
overflow (more elements in target than source) + minor toString/cache values 
enhancements (useful for debug purposes)
34a8607 is described below

commit 34a860746a7da9316feddf84f5ccc8dc085cbd46
Author: Romain Manni-Bucau <rmannibu...@gmail.com>
AuthorDate: Mon Apr 13 16:57:20 2020 +0200

    JOHNZON-304 Json.createDiff does not handle properly arrays overflow (more 
elements in target than source) + minor toString/cache values enhancements 
(useful for debug purposes)
---
 .../org/apache/johnzon/core/JsonArrayImpl.java     |  3 +
 .../org/apache/johnzon/core/JsonObjectImpl.java    |  3 +
 .../org/apache/johnzon/core/JsonPatchDiff.java     | 15 +---
 .../org/apache/johnzon/core/JsonPatchImpl.java     | 95 +++++++++++++++-------
 .../org/apache/johnzon/core/JsonPatchDiffTest.java | 19 +++++
 5 files changed, 94 insertions(+), 41 deletions(-)

diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
index 7f87069..d05cfbf 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonArrayImpl.java
@@ -163,6 +163,9 @@ class JsonArrayImpl extends AbstractList<JsonValue> 
implements JsonArray, Serial
 
     @Override
     public String toString() {
+        if (unmodifieableBackingList.isEmpty()) {
+            return "[]";
+        }
         final StringWriter writer = new StringWriter();
         try (final JsonGenerator generator = new JsonGeneratorImpl(writer, 
provider, false)) {
             generator.writeStartArray();
diff --git 
a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java 
b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
index 03d65fe..4e45f08 100644
--- a/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
+++ b/johnzon-core/src/main/java/org/apache/johnzon/core/JsonObjectImpl.java
@@ -143,6 +143,9 @@ final class JsonObjectImpl extends AbstractMap<String, 
JsonValue> implements Jso
 
     @Override
     public String toString() {
+        if (unmodifieableBackingMap.isEmpty()) {
+            return "{}";
+        }
         final StringWriter writer = new StringWriter();
         try (final JsonGenerator generator = new JsonGeneratorImpl(writer, 
provider, false)) {
             generator.writeStartObject();
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 8610184..29577f0 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
@@ -61,19 +61,16 @@ class JsonPatchDiff extends DiffBase {
 
     private void diffJsonArray(JsonPatchBuilder patchBuilder, String basePath, 
JsonArray source, JsonArray target) {
         for (int i = 0; i < source.size(); i++) {
-            JsonValue sourceValue = source.get(i);
-
+            final JsonValue sourceValue = source.get(i);
             if (target.size() <= i) {
                 patchBuilder.remove(basePath + i);
                 continue;
             }
-
             diff(patchBuilder, basePath + i, sourceValue, target.get(i));
         }
 
         if (target.size() > source.size()) {
-
-            for (int i = target.size() - source.size(); i < target.size(); 
i++) {
+            for (int i = source.size(); i < target.size(); i++) {
                 patchBuilder.add(basePath + i, target.get(i));
             }
         }
@@ -81,8 +78,7 @@ class JsonPatchDiff extends DiffBase {
     }
 
     private void diffJsonObjects(JsonPatchBuilder patchBuilder, String 
basePath, JsonObject source, JsonObject target) {
-
-        for (Map.Entry<String, JsonValue> sourceEntry : source.entrySet()) {
+        for (final Map.Entry<String, JsonValue> sourceEntry : 
source.entrySet()) {
             String attributeName = sourceEntry.getKey();
 
             if (target.containsKey(attributeName)) {
@@ -93,13 +89,10 @@ class JsonPatchDiff extends DiffBase {
             }
         }
 
-        for (Map.Entry<String, JsonValue> targetEntry : target.entrySet()) {
+        for (final Map.Entry<String, JsonValue> targetEntry : 
target.entrySet()) {
             if (!source.containsKey(targetEntry.getKey())) {
                 patchBuilder.add(basePath + 
JsonPointerUtil.encode(targetEntry.getKey()), targetEntry.getValue());
             }
         }
-
     }
-
-
 }
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 ec3109d..91bb436 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
@@ -38,6 +38,7 @@ class JsonPatchImpl implements JsonPatch {
     private final JsonProvider provider;
     private final List<PatchValue> patches;
 
+    private volatile JsonArray json;
 
     JsonPatchImpl(final JsonProvider provider, final PatchValue... patches) {
         this(provider, Arrays.asList(patches));
@@ -118,16 +119,30 @@ class JsonPatchImpl implements JsonPatch {
 
     @Override
     public JsonArray toJsonArray() {
-
-        JsonArrayBuilder builder = provider.createArrayBuilder();
-        for (PatchValue patch : patches) {
-            builder.add(patch.toJson());
+        if (patches.isEmpty()) {
+            return JsonValue.EMPTY_JSON_ARRAY;
         }
-
-        return builder.build();
+        if (json == null) {
+            synchronized (this) {
+                if (json == null) {
+                    final JsonArrayBuilder builder = 
provider.createArrayBuilder();
+                    for (final PatchValue patch : patches) {
+                        builder.add(patch.toJson());
+                    }
+                    json = builder.build();
+                }
+            }
+        }
+        return json;
     }
 
-
+    @Override
+    public String toString() {
+        if (patches.isEmpty()) {
+            return "[]";
+        }
+        return toJsonArray().toString();
+    }
 
     static class PatchValue {
         private final JsonProvider provider;
@@ -136,6 +151,10 @@ class JsonPatchImpl implements JsonPatch {
         private final JsonPointerImpl from;
         private final JsonValue value;
 
+        private volatile String str;
+        private volatile JsonObject json;
+        private volatile Integer hash;
+
         PatchValue(final JsonProvider provider,
                    final JsonPatch.Operation operation,
                    final String path,
@@ -181,38 +200,54 @@ class JsonPatchImpl implements JsonPatch {
 
         @Override
         public int hashCode() {
-            int result = operation.hashCode();
-            result = 31 * result + path.hashCode();
-            result = 31 * result + (from != null ? from.hashCode() : 0);
-            result = 31 * result + (value != null ? value.hashCode() : 0);
-            return result;
+            if (hash == null) {
+                synchronized (this) {
+                    if (hash == null) {
+                        int result = operation.hashCode();
+                        result = 31 * result + path.hashCode();
+                        result = 31 * result + (from != null ? from.hashCode() 
: 0);
+                        result = 31 * result + (value != null ? 
value.hashCode() : 0);
+                        hash = result;
+                    }
+                }
+            }
+            return hash;
         }
 
 
         @Override
         public String toString() {
-            return "{" +
-                   "op: " + operation +
-                   ", path: " + path +
-                   ", from: " + from +
-                   ", value: " + value +
-                   '}';
+            if (str == null) {
+                synchronized (this) {
+                    if (str == null) {
+                        str = "{op: " + operation + ", path: " + path + ", 
from: " + from + ", value: " + value + '}';
+                    }
+                }
+            }
+            return str;
         }
 
         JsonObject toJson() {
-            JsonObjectBuilder builder = provider.createObjectBuilder()
-                                            .add("op", 
operation.name().toLowerCase())
-                                            .add("path", 
path.getJsonPointer());
-
-            if (from != null) {
-                builder.add("from", from.getJsonPointer());
-            }
-
-            if (value != null) {
-                builder.add("value", value);
+            if (json == null) {
+                synchronized (this) {
+                    if (json == null) {
+                        JsonObjectBuilder builder = 
provider.createObjectBuilder()
+                                .add("op", operation.name().toLowerCase())
+                                .add("path", path.getJsonPointer());
+
+                        if (from != null) {
+                            builder.add("from", from.getJsonPointer());
+                        }
+
+                        if (value != null) {
+                            builder.add("value", value);
+                        }
+
+                        json = builder.build();
+                    }
+                }
             }
-
-            return builder.build();
+            return json;
         }
     }
 }
diff --git 
a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java 
b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java
index 51bada2..d591b98 100644
--- a/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java
+++ b/johnzon-core/src/test/java/org/apache/johnzon/core/JsonPatchDiffTest.java
@@ -32,6 +32,25 @@ import org.junit.Ignore;
 import org.junit.Test;
 
 public class JsonPatchDiffTest {
+    @Test
+    public void fromEmptyArray() {
+        final JsonObject from = Json.createObjectBuilder().add("testEmpty", 
JsonValue.EMPTY_JSON_ARRAY).build();
+        final JsonObject to = Json.createObjectBuilder()
+                .add("testEmpty", Json.createArrayBuilder().add("something"))
+                .build();
+        final  JsonPatch diff = Json.createDiff(from, to);
+        
assertEquals("[{\"op\":\"add\",\"path\":\"/testEmpty/0\",\"value\":\"something\"}]",
 diff.toString());
+    }
+
+    @Test
+    public void toEmptyArray() {
+        final JsonObject from = Json.createObjectBuilder()
+                .add("testEmpty", Json.createArrayBuilder().add("something"))
+                .build();
+        final JsonObject to = Json.createObjectBuilder().add("testEmpty", 
JsonValue.EMPTY_JSON_ARRAY).build();
+        final  JsonPatch diff = Json.createDiff(from, to);
+        assertEquals("[{\"op\":\"remove\",\"path\":\"/testEmpty/0\"}]", 
diff.toString());
+    }
 
     @Test
     public void testAddDiff() {

Reply via email to