Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
add flag to not generate Move or Copy operations.
  • Loading branch information
bdwdax committed Aug 28, 2020
commit ad9199b9fe58074a7123776681145ef4bd58607e
14 changes: 13 additions & 1 deletion src/main/java/com/github/fge/jsonpatch/diff/DiffProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,18 @@ final class DiffProcessor

private final Map<JsonPointer, JsonNode> unchanged;

private final boolean withMoveOrCopyOperation;
public static final boolean WITH_MOVE_OR_COPY_OPERATION = true;

private final List<DiffOperation> diffs = new ArrayList<DiffOperation>();

DiffProcessor(final Map<JsonPointer, JsonNode> unchanged)
DiffProcessor(final Map<JsonPointer, JsonNode> unchanged) {
this(unchanged, WITH_MOVE_OR_COPY_OPERATION);
}

DiffProcessor(final Map<JsonPointer, JsonNode> unchanged, boolean withMoveOrCopyOperation)
{
this.withMoveOrCopyOperation = withMoveOrCopyOperation;
this.unchanged = Collections.unmodifiableMap(new HashMap<JsonPointer, JsonNode>(unchanged));
}

Expand All @@ -56,6 +64,10 @@ void valueRemoved(final JsonPointer pointer, final JsonNode value)

void valueAdded(final JsonPointer pointer, final JsonNode value)
{
if (!withMoveOrCopyOperation) {
diffs.add(DiffOperation.add(pointer, value));
return;
}
final int removalIndex = findPreviouslyRemoved(value);
if (removalIndex != -1) {
final DiffOperation removed = diffs.get(removalIndex);
Expand Down
25 changes: 22 additions & 3 deletions src/main/java/com/github/fge/jsonpatch/diff/JsonDiff.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
import java.io.IOException;
import java.util.*;

import static com.github.fge.jsonpatch.diff.DiffProcessor.WITH_MOVE_OR_COPY_OPERATION;

/**
* JSON "diff" implementation
*
Expand Down Expand Up @@ -81,14 +83,25 @@ private JsonDiff()
*
* @since 1.9
*/

// public static JsonPatch asJsonPatch(final JsonNode source,
// final JsonNode target, false)
// {
// return
// }
public static JsonPatch asJsonPatch(final JsonNode source,
final JsonNode target)
final JsonNode target)
{
return asJsonPatch(source, target, WITH_MOVE_OR_COPY_OPERATION);
}
public static JsonPatch asJsonPatch(final JsonNode source,
final JsonNode target, final boolean withMoveOrCopyOperation)
{
BUNDLE.checkNotNull(source, "common.nullArgument");
BUNDLE.checkNotNull(target, "common.nullArgument");
final Map<JsonPointer, JsonNode> unchanged
= getUnchangedValues(source, target);
final DiffProcessor processor = new DiffProcessor(unchanged);
final DiffProcessor processor = new DiffProcessor(unchanged, withMoveOrCopyOperation);

generateDiffs(processor, JsonPointer.empty(), source, target);
return processor.getPatch();
Expand All @@ -103,10 +116,16 @@ public static JsonPatch asJsonPatch(final JsonNode source,
* @return the patch as a {@link JsonNode}
*/
public static JsonNode asJson(final JsonNode source, final JsonNode target)
{
return asJson(source, target, WITH_MOVE_OR_COPY_OPERATION);
}


public static JsonNode asJson(final JsonNode source, final JsonNode target, final boolean withMoveOrCopyOperation)
{
final String s;
try {
s = MAPPER.writeValueAsString(asJsonPatch(source, target));
s = MAPPER.writeValueAsString(asJsonPatch(source, target, withMoveOrCopyOperation));
return MAPPER.readTree(s);
} catch (IOException e) {
throw new RuntimeException("cannot generate JSON diff", e);
Expand Down
17 changes: 11 additions & 6 deletions src/test/java/com/github/fge/jsonpatch/diff/JsonDiffTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Iterator;
import java.util.List;

import static com.github.fge.jsonpatch.diff.DiffProcessor.WITH_MOVE_OR_COPY_OPERATION;
import static org.assertj.core.api.Assertions.assertThat;

public final class JsonDiffTest
Expand All @@ -53,17 +54,20 @@ public Iterator<Object[]> getPatchesOnly()
final List<Object[]> list = Lists.newArrayList();

for (final JsonNode node: testData)
list.add(new Object[] { node.get("first"), node.get("second") });
list.add(new Object[] {
node.get("first"), node.get("second"),
node.has("withMoveOrCopy") ? node.get("withMoveOrCopy").booleanValue() : WITH_MOVE_OR_COPY_OPERATION
});

return list.iterator();
}

@Test(dataProvider = "getPatchesOnly")
public void generatedPatchAppliesCleanly(final JsonNode first,
final JsonNode second)
final JsonNode second, final boolean withMoveOrCopy)
throws JsonPatchException
{
final JsonPatch patch = JsonDiff.asJsonPatch(first, second);
final JsonPatch patch = JsonDiff.asJsonPatch(first, second, withMoveOrCopy);
final JsonNode actual = patch.apply(first);

assertThat(EQUIVALENCE.equivalent(second, actual)).overridingErrorMessage(
Expand All @@ -82,7 +86,8 @@ public Iterator<Object[]> getLiteralPatches()
continue;
list.add(new Object[] {
node.get("message").textValue(), node.get("first"),
node.get("second"), node.get("patch")
node.get("second"), node.get("patch"),
node.has("withMoveOrCopy") ? node.get("withMoveOrCopy").booleanValue() : WITH_MOVE_OR_COPY_OPERATION
});
}

Expand All @@ -94,9 +99,9 @@ public Iterator<Object[]> getLiteralPatches()
dependsOnMethods = "generatedPatchAppliesCleanly"
)
public void generatedPatchesAreWhatIsExpected(final String message,
final JsonNode first, final JsonNode second, final JsonNode expected)
final JsonNode first, final JsonNode second, final JsonNode expected, final boolean withMoveOrCopyOperation)
{
final JsonNode actual = JsonDiff.asJson(first, second);
final JsonNode actual = JsonDiff.asJson(first, second, withMoveOrCopyOperation);

assertThat(EQUIVALENCE.equivalent(expected, actual)).overridingErrorMessage(
"patch is not what was expected\nscenario: %s\n"
Expand Down
23 changes: 23 additions & 0 deletions src/test/resources/jsonpatch/diff/diff.json
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,28 @@
"patch": [
{ "op": "move", "path": "/c", "from": "/a" }
]
},{
"message": "similar element is copied instead of added",
"first": {
"a": "c"
},
"second": {
"a": "c",
"d": "c"
},
"patch": [
{ "op": "add", "path": "/d", "value": "c" }
],
"withMoveOrCopy": false
},
{
"message": "similar element removed then added is moved instead",
"first": { "a": "b" },
"second": { "c": "b" },
"patch": [
{ "op": "remove", "path": "/a" },
{ "op": "add", "path": "/c", "value": "b" }
],
"withMoveOrCopy": false
}
]