2020package com .github .fge .jsonpatch .diff2 ;
2121
2222import com .fasterxml .jackson .databind .JsonNode ;
23+ import com .github .fge .jackson .JsonNumEquals ;
2324import com .github .fge .jackson .jsonpointer .JsonPointer ;
2425import com .github .fge .jsonpatch .JsonPatch ;
2526import com .github .fge .jsonpatch .JsonPatchOperation ;
27+ import com .google .common .base .Equivalence ;
28+ import com .google .common .base .Predicate ;
2629import com .google .common .collect .ImmutableMap ;
2730import com .google .common .collect .Lists ;
2831
32+ import javax .annotation .Nullable ;
2933import java .util .List ;
3034import java .util .Map ;
3135
3236// Non final because we want to be able to Mockito.spy() on it
3337class 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}
0 commit comments