Skip to content

Instantly share code, notes, and snippets.

@abelaska
Created June 8, 2020 09:44
Show Gist options
  • Save abelaska/5a38196115cb3dcb963a773163d6a9e7 to your computer and use it in GitHub Desktop.
Save abelaska/5a38196115cb3dcb963a773163d6a9e7 to your computer and use it in GitHub Desktop.
Java Jackson Object Patcher
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import cz.monetplus.mep.fs.common.jackson.JacksonMapper;
import lombok.SneakyThrows;
import lombok.experimental.UtilityClass;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
@UtilityClass
public class ObjectPatcher {
@SneakyThrows
public static <T> Optional<T> patch(T obj, T patch, Class<T> clazz) {
JsonNode objNode = JacksonMapper.DEFAULT.valueToTree(obj);
JsonNode patchNode = JacksonMapper.DEFAULT.valueToTree(patch);
boolean modified = patchJsonNode(objNode, patchNode);
T mergedObj = modified ? JacksonMapper.DEFAULT.convertValue(objNode, clazz) : null;
return Optional.ofNullable(mergedObj);
}
static boolean patchJsonNode(JsonNode obj, JsonNode patch) {
boolean modified = false;
if (patch.isObject()) {
Iterator<Map.Entry<String, JsonNode>> it = patch.fields();
while (it.hasNext()) {
Map.Entry<String, JsonNode> e = it.next();
if (e.getValue().isObject()) {
if (patchJsonNode(obj.get(e.getKey()), e.getValue())) {
modified = true;
}
} else {
JsonNode oldNode = ((ObjectNode) obj).get(e.getKey());
String oldValue = oldNode == null ? null : oldNode.asText();
String newValue = e.getValue().asText();
if ((oldValue == null && newValue != null) || newValue.compareTo(oldValue) != 0) {
((ObjectNode) obj).set(e.getKey(), e.getValue());
modified = true;
}
}
}
}
return modified;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment