From b32c08bc1da7dd6868bd23ddb9064f4a03c0c035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Werner=20Donne=CC=81?= Date: Fri, 20 Oct 2017 21:54:33 +0200 Subject: [PATCH] Fixed issue #61 --- .../org/glassfish/json/JsonPatchImpl.java | 62 +++++++++++-------- tests/src/test/resources/jsonpatchdiff.json | 40 ++++++++++-- 2 files changed, 70 insertions(+), 32 deletions(-) diff --git a/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java b/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java index 240176f7..5c51e64f 100644 --- a/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java +++ b/impl/src/main/java/org/glassfish/json/JsonPatchImpl.java @@ -289,32 +289,42 @@ private void diffArray(String path, JsonArray source, JsonArray target) { } } - int i = m; - int j = n; - while (i > 0 || j > 0) { - if (i == 0) { - j--; - builder.add(path + '/' + j, target.get(j)); - } else if (j == 0) { - i--; - builder.remove(path + '/' + i); - } else if ((c[i][j] & 1) == 1) { - i--; j--; - } else { - int f = c[i][j-1] >> 1; - int g = c[i-1][j] >> 1; - if (f > g) { - j--; - builder.add(path + '/' + j, target.get(j)); - } else if (f < g) { - i--; - builder.remove(path + '/' + i); - } else { // f == g) { - i--; j--; - diff(path + '/' + i, source.get(i), target.get(j)); - } - } - } + emit(path, source, target, c, m, n); + } + + private void emit(final String path, + final JsonArray source, + final JsonArray target, + final int[][] c, + final int i, + final int j) { + if (i == 0) { + if (j > 0) { + emit(path, source, target, c, i, j - 1); + builder.add(path + '/' + (j - 1), target.get(j - 1)); + } + } else if (j == 0) { + if (i > 0) { + builder.remove(path + '/' + (i - 1)); + emit(path, source, target, c, i - 1, j); + } + } else if ((c[i][j] & 1) == 1) { + emit(path, source, target, c, i - 1, j - 1); + } else { + final int f = c[i][j-1] >> 1; + final int g = c[i-1][j] >> 1; + if (f > g) { + emit(path, source, target, c, i, j - 1); + builder.add(path + '/' + (j - 1), target.get(j - 1)); + } else if (f < g) { + builder.remove(path + '/' + (i - 1)); + emit(path, source, target, c, i - 1, j); + } else { // f == g) { + diff(path + '/' + (i - 1), source.get(i - 1), + target.get(j - 1)); + emit(path, source, target, c, i - 1, j - 1); + } + } } } } diff --git a/tests/src/test/resources/jsonpatchdiff.json b/tests/src/test/resources/jsonpatchdiff.json index ce3be5fc..529b79ec 100644 --- a/tests/src/test/resources/jsonpatchdiff.json +++ b/tests/src/test/resources/jsonpatchdiff.json @@ -8,8 +8,8 @@ "original": [ 1, 2, 3 ], "target": [ 1, 2, 3, 4, 5 ], "expected": [ - {"op":"add","path":"/4","value":5}, - {"op":"add","path":"/3","value":4} + {"op":"add","path":"/3","value":4}, + {"op":"add","path":"/4","value":5} ] }, { @@ -25,8 +25,8 @@ "target": [1,7,3,4,8,5], "expected": [ { "op": "remove", "path": "/5"}, - { "op": "add", "path": "/4", "value": 8}, - { "op": "replace", "path": "/1", "value": 7} + { "op": "replace", "path": "/1", "value": 7}, + { "op": "add", "path": "/4", "value": 8} ] }, { @@ -94,8 +94,8 @@ "a": [ "b", 2, 3, 4 ] }, "expected": [ - { "op": "add", "path": "/a/3", "value": 4 }, - { "op": "replace", "path": "/a/0", "value": "b" } + { "op": "replace", "path": "/a/0", "value":"b" }, + { "op": "add", "path": "/a/3", "value":4 } ] }, { @@ -128,5 +128,33 @@ "expected": [ { "op": "add", "path": "/d", "value": "c" } ] + }, + { + "original": [-1, 0, 1, 3, 4], + "target": [5, 0], + "expected": [ + { "path" : "/4", "op" : "remove"}, + { "path" : "/3", "op" : "remove"}, + { "path" : "/2", "op" : "remove"}, + { "value" : 5, "path" : "/0", "op" : "replace" } + ] + }, + { + "original": [0], + "target": [0, 1, 2, 3, 4], + "expected": [ + { "path" : "/1", "value" : 1, "op" : "add" }, + { "path" : "/2", "value" : 2, "op" : "add" }, + { "value" : 3, "path" : "/3", "op" : "add" }, + { "op" : "add", "path" : "/4", "value" : 4 } + ] + }, + { + "original": [0, 2, 4], + "target": [0, 1, 2, 3, 4], + "expected": [ + { "path" : "/1", "value" : 1, "op" : "add" }, + { "value" : 3, "op" : "add", "path" : "/3" } + ] } ]