io.setl.json.merge.MergeDiff Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of canonical-json Show documentation
Show all versions of canonical-json Show documentation
An implementation of the Canonical JSON format with support for javax.json and Jackson
The newest version!
package io.setl.json.merge;
import java.util.HashSet;
import java.util.Iterator;
import jakarta.json.JsonObject;
import jakarta.json.JsonValue;
import jakarta.json.JsonValue.ValueType;
import io.setl.json.CJObject;
/**
* Generator of merge patches.
*
* @author Simon Greatrix on 28/01/2020.
*/
public class MergeDiff {
/**
* Create the "diff" of two values using a JSON Merge Patch.
*
* @param input the input value
* @param output the desired result of the patch
*
* @return the patch
*/
public static Merge create(JsonValue input, JsonValue output) {
if (input.getValueType() != ValueType.OBJECT || output.getValueType() != ValueType.OBJECT) {
return new Merge(output);
}
JsonObject merge = new CJObject();
JsonObject inObject = (JsonObject) input;
JsonObject outObject = (JsonObject) output;
doDiff(merge, inObject, outObject);
return new Merge(merge);
}
private static void doDiff(JsonObject merge, JsonObject inObject, JsonObject outObject) {
HashSet inKeys = new HashSet<>(inObject.keySet());
HashSet outKeys = new HashSet<>(outObject.keySet());
// do "removes"
doDiffRemoves(merge, inKeys, outKeys);
// do "adds", and trim "outKeys" so that it is just the common keys.
doDiffAdds(merge, inKeys, outKeys, outObject);
// do "replaces"
doDiffReplaces(outKeys, merge, inObject, outObject);
}
private static void doDiffAdds(JsonObject merge, HashSet inKeys, HashSet outKeys, JsonObject outObject) {
Iterator iterator = outKeys.iterator();
while (iterator.hasNext()) {
String s = iterator.next();
if (!inKeys.contains(s)) {
merge.put(s, outObject.get(s));
iterator.remove();
}
}
}
private static void doDiffRemoves(JsonObject merge, HashSet inKeys, HashSet outKeys) {
for (String s : inKeys) {
if (!outKeys.contains(s)) {
merge.put(s, JsonValue.NULL);
}
}
}
private static void doDiffReplaces(HashSet outKeys, JsonObject merge, JsonObject inObject, JsonObject outObject) {
for (String s : outKeys) {
JsonValue inValue = inObject.get(s);
JsonValue outValue = outObject.get(s);
if (inValue.getValueType() == ValueType.OBJECT && outValue.getValueType() == ValueType.OBJECT) {
CJObject childMerge = new CJObject();
doDiff(childMerge, (JsonObject) inValue, (JsonObject) outValue);
if (!childMerge.isEmpty()) {
merge.put(s, childMerge);
}
continue;
}
if ((inValue.getValueType() != outValue.getValueType()) || !inValue.equals(outValue)) {
merge.put(s, outValue);
}
}
}
private MergeDiff() {
// do nothing
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy