com.dnastack.audit.diff.JsonPatchDiffProvider Maven / Gradle / Ivy
The newest version!
package com.dnastack.audit.diff;
import com.dnastack.audit.ObjectMapperFactory;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.flipkart.zjsonpatch.DiffFlags;
import com.flipkart.zjsonpatch.JsonDiff;
import com.flipkart.zjsonpatch.JsonPatch;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
public class JsonPatchDiffProvider {
private final static Pattern pattern = Pattern.compile("\\d+");
private static final ObjectMapper objectMapper = ObjectMapperFactory.create();
public static List getDiff(Object source, Object target) {
JsonNode jsonSource = source != null ? objectMapper.convertValue(source, JsonNode.class) : null;
JsonNode jsonTarget = target != null ? objectMapper.convertValue(target, JsonNode.class) : null;
JsonNode patch = JsonDiff.asJson(jsonSource, jsonTarget, DiffFlags.dontNormalizeOpIntoMoveAndCopy().clone());
TypeReference> type = new TypeReference<>() {};
List jsonDiffPatches = objectMapper.convertValue(patch, type);
JsonNode intermediateObject = jsonSource;
for (JsonPatchDiff patchDiff : jsonDiffPatches) {
if ("remove".equalsIgnoreCase(patchDiff.getOp())) {
patchDiff.setOriginalValue(intermediateObject.at(patchDiff.getPath()));
patchDiff.setValue(null);
}
if ("replace".equalsIgnoreCase(patchDiff.getOp())) {
patchDiff.setOriginalValue(intermediateObject.at(patchDiff.getPath()));
}
if ("add".equalsIgnoreCase(patchDiff.getOp()) && intermediateObject == null) {
intermediateObject = objectMapper.convertValue(patchDiff.getValue(), JsonNode.class);
patchDiff.setContext(prepareContext(intermediateObject, patchDiff.getPath()));
} else if ("remove".equalsIgnoreCase(patchDiff.getOp()) && "".equalsIgnoreCase(patchDiff.getPath())) {
patchDiff.setContext(prepareContext(intermediateObject, patchDiff.getPath()));
intermediateObject = objectMapper.nullNode();
} else {
intermediateObject = JsonPatch.apply(objectMapper.convertValue(List.of(patchDiff), JsonNode.class), intermediateObject);
patchDiff.setContext(prepareContext(intermediateObject, patchDiff.getPath()));
}
}
return jsonDiffPatches;
}
private static JsonNode prepareContext(JsonNode object, String patchPath) {
JsonNode context = object.deepCopy();
if (context.at(patchPath).isValueNode()) { // TRIM unnecessary array(s) of parent
context.at(patchPath.substring(0, patchPath.lastIndexOf("/"))).fields().forEachRemaining((entry) -> {
if (entry.getValue().isArray()) {
((ArrayNode) entry.getValue()).removeAll();
}
});
} else if (context.at(patchPath).isObject()) { // TRIM unnecessary array(s)
context.at(patchPath).fields().forEachRemaining((entry) -> {
if (entry.getValue().isArray()) {
((ArrayNode) entry.getValue()).removeAll();
}
});
}
String[] pathArray = patchPath.split("/");
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy