WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit 799c595

Browse files
committed
DiffProcessor: factorize additions into copies where possible
If an element is added which already exists in the source and is unchanged in the target, make the addition a copy instead.
1 parent 34f6ba5 commit 799c595

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/main/java/com/github/fge/jsonpatch/diff2/DiffProcessor.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,25 @@
2020
package com.github.fge.jsonpatch.diff2;
2121

2222
import com.fasterxml.jackson.databind.JsonNode;
23+
import com.github.fge.jackson.JsonNumEquals;
2324
import com.github.fge.jackson.jsonpointer.JsonPointer;
2425
import com.github.fge.jsonpatch.JsonPatch;
2526
import com.github.fge.jsonpatch.JsonPatchOperation;
27+
import com.google.common.base.Equivalence;
28+
import com.google.common.base.Predicate;
2629
import com.google.common.collect.ImmutableMap;
2730
import com.google.common.collect.Lists;
2831

32+
import javax.annotation.Nullable;
2933
import java.util.List;
3034
import java.util.Map;
3135

3236
// Non final because we want to be able to Mockito.spy() on it
3337
class DiffProcessor
3438
{
39+
private static final Equivalence<JsonNode> EQUIVALENCE
40+
= JsonNumEquals.getInstance();
41+
3542
private final Map<JsonPointer, JsonNode> unchanged;
3643

3744
private final List<DiffOperation> diffs = Lists.newArrayList();
@@ -54,7 +61,12 @@ void valueRemoved(final JsonPointer pointer, final JsonNode value)
5461

5562
void valueAdded(final JsonPointer pointer, final JsonNode value)
5663
{
57-
diffs.add(DiffOperation.add(pointer, value));
64+
final JsonPointer ptr = findUnchangedValue(value);
65+
final DiffOperation op = ptr != null
66+
? DiffOperation.copy(ptr, pointer, value)
67+
: DiffOperation.add(pointer, value);
68+
69+
diffs.add(op);
5870
}
5971

6072
JsonPatch getPatch()
@@ -66,4 +78,14 @@ JsonPatch getPatch()
6678

6779
return new JsonPatch(list);
6880
}
81+
82+
@Nullable
83+
private JsonPointer findUnchangedValue(final JsonNode value)
84+
{
85+
final Predicate<JsonNode> predicate = EQUIVALENCE.equivalentTo(value);
86+
for (final Map.Entry<JsonPointer, JsonNode> entry: unchanged.entrySet())
87+
if (predicate.apply(entry.getValue()))
88+
return entry.getKey();
89+
return null;
90+
}
6991
}

src/test/resources/jsonpatch/diff2/diff.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,18 @@
113113
{ "op": "replace", "path": "/0", "value": "x" },
114114
{ "op": "add", "path": "/1/-", "value": "y" }
115115
]
116+
},
117+
{
118+
"message": "similar element is copied instead of added",
119+
"first": {
120+
"a": "c"
121+
},
122+
"second": {
123+
"a": "c",
124+
"d": "c"
125+
},
126+
"patch": [
127+
{ "op": "copy", "path": "/d", "from": "/a" }
128+
]
116129
}
117130
]

0 commit comments

Comments
 (0)