Skip to content

Instantly share code, notes, and snippets.

@alexcmd
Created September 27, 2017 07:30
Show Gist options
  • Save alexcmd/367a61d21e112343c5d5da64765cce05 to your computer and use it in GitHub Desktop.
Save alexcmd/367a61d21e112343c5d5da64765cce05 to your computer and use it in GitHub Desktop.
// Console out
// [{"op":"replace","path":"/b/name","value":"name2"},{"op":"replace","path":"/b/price","value":2.0}]
// Change B
// name string
// Change name to name2
// price float
// Change price to 2.0
// {"b":{"name":"name2","price":2.0},"id":0}
// ======================================================
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.flipkart.zjsonpatch.JsonDiff;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
public class App {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
ObjB b = new ObjB();
b.setName("name1");
b.setPrice(1.0f);
ObjA a = new ObjA();
a.setId(10);
a.setB(b);
String json = JSON.toJSONString(a);
JsonNode node1 = mapper.readTree(json);
b.setPrice(2.0f);
b.setName("name2");
String json2 = JSON.toJSONString(a);
JsonNode node2 = mapper.readTree(json2);
JsonNode diff = JsonDiff.asJson(node1, node2);
try {
ObjectPatch.apply(new ObjA(),diff.toString());
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
//System.out.println(diff.toString());
}
}
// ======================================================
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sun.xml.internal.ws.util.StringUtils;
import java.io.Console;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Stream;
public class ObjectPatch {
public static <T> void apply(T object, String jsonPatch) throws IOException, InvocationTargetException, IllegalAccessException, InstantiationException {
System.out.println(jsonPatch);
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.readTree(jsonPatch);
for (Iterator<JsonNode> it = node.elements(); it.hasNext(); ) {
Object currentObject = object;
JsonNode elm = it.next();
String operation = elm.get("path").asText();
String[] path = elm.get("path").asText().split("/");
JsonNode value = elm.get("value");
Class<?> currentType = object.getClass();
for (int i = 1; i < path.length; i++) {
String pathPart = path[i];
Optional<Field> field = Arrays.stream(currentType.getDeclaredFields()).filter(f -> f.getName().equalsIgnoreCase(pathPart)).findFirst();
if (!field.isPresent())
break;
String setMethodName = "set" + pathPart;
String getMethodName = "get" + pathPart;
Optional<Method> getMethod = null;
if (i<path.length-1) {
getMethod = Arrays.stream(currentType.getMethods()).filter(method1 -> method1.getName().equalsIgnoreCase(getMethodName)).findFirst();
Object newObj = getMethod.get().invoke(currentObject);
Optional<Method> setMethod = Arrays.stream(currentType.getMethods()).filter(method1 -> method1.getName().equalsIgnoreCase(setMethodName)).findFirst();
if (newObj == null) {
newObj = getMethod.get().getReturnType().getConstructors()[0].newInstance();
setMethod.get().invoke(currentObject,newObj);
}
currentType = field.get().getType();
currentObject = newObj;
continue;
}
Class<?> fieldType = field.get().getType();
Stream<Method> m = Arrays.stream(currentType.getMethods());
Optional<Method> setMethod = Arrays.stream(currentType.getMethods()).filter(method1 -> method1.getName().equalsIgnoreCase(setMethodName)).findFirst();
Object new_val=null;
switch (fieldType.getName())
{
case "float":
System.out.println(pathPart+" float");
new_val = ((float) value.asDouble());
break;
case "java.lang.String":
System.out.println(pathPart+" string");
new_val = value.asText();
break;
default:
break;
}
setMethod.get().invoke(currentObject,new_val);
}
}
System.out.println(JSON.toJSONString(object));
}
}
// ======================================================
public class ObjA {
private int id;
private ObjB b;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public ObjB getB() {
return b;
}
public void setB(ObjB b) {
System.out.println("Change B");
this.b = b;
}
}
// ======================================================
public class ObjB {
private String name;
private float price;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("Change name to " +name);
this.name = name;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
System.out.println("Change price to " +price);
this.price = price;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment