Last active
April 8, 2019 19:06
-
-
Save UnquietCode/7954032 to your computer and use it in GitHub Desktop.
Revisions
-
UnquietCode revised this gist
Dec 14, 2013 . 1 changed file with 0 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,3 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; -
UnquietCode revised this gist
Dec 14, 2013 . 1 changed file with 75 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ package com.sb.data.api; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.ByteArrayOutputStream; /** * @author Ben Fagin * @version 2013-12-13 */ public class Test { interface Point extends Model { int getX(); void setX(int x); int getY(); void setY(int y); Nub getNub(); void setNub(Nub nub); } interface Nub extends Model { void setThing(int thing); int getThing(); } public static void main(String[] args) throws Exception { final ObjectMapper jsonMapper = new ObjectMapper(); jsonMapper.registerModule(new MapperModule()); ObjectNode data = jsonMapper.createObjectNode(); data.put("x", 100); data.put("y", 200); data.putObject("nub").put("thing", 300); Point point = jsonMapper.reader(Point.class).readValue(data); System.out.println(point.getX()); System.out.println(point.getY()); System.out.println(point.getNub().getThing()); point.setX(111); point.setY(222); point.setNub(new Nub() { int val = 333; public void setThing(int thing) { val = thing; } public int getThing() { return val; } }); ByteArrayOutputStream os = new ByteArrayOutputStream(); System.out.println(point.getX()); System.out.println(point.getY()); System.out.println(point.getNub().getThing()); jsonMapper.writerWithType(Point.class).writeValue(os, point); System.out.println(os.toString()); os.reset(); point.getNub().setThing(400); System.out.println(point.getNub().getThing()); jsonMapper.writerWithType(Point.class).writeValue(os, point); System.out.println(os.toString()); } } -
UnquietCode created this gist
Dec 14, 2013 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,44 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.Version; import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.deser.Deserializers; import com.fasterxml.jackson.databind.node.ObjectNode; import java.io.IOException; import java.util.Iterator; /** * @author Ben Fagin * @version 2013-12-13 */ public class MapperModule extends Module { @Override public String getModuleName() { return "ModelMapper"; } @Override public Version version() { return new Version(2, 0, 0, null, null, null); } @Override public void setupModule(SetupContext context) { context.addDeserializers(new Deserializers.Base() { public @Override JsonDeserializer<?> findBeanDeserializer(final JavaType type, DeserializationConfig config, BeanDescription beanDesc) throws JsonMappingException { if (Model.class.isAssignableFrom(type.getRawClass())) { return new JsonDeserializer<Object>() { public @Override Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { Iterator<ObjectNode> obj = jp.readValuesAs(ObjectNode.class); return ModelMapper.map(type.getRawClass(), obj.next()); } }; } return super.findBeanDeserializer(type, config, beanDesc); } }); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ /** * Marker interface for all model objects. * * @author Ben Fagin * @version 2013-12-13 */ interface Model { // nothing here, as this is just a marker } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,78 @@ import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.POJONode; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; /** * @author Ben Fagin * @version 2013-12-13 */ public class ModelMapper { @SuppressWarnings("unchecked") public static <T> T map(Class<T> klaus, final ObjectNode data) { checkNotNull(data); checkArgument(klaus != null && klaus.isInterface(), "interfaces only please"); return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class[]{klaus}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String property = method.getName().substring(3); property = new String(new char[]{property.charAt(0)}).toLowerCase() + property.substring(1); // getter if (method.getName().startsWith("get") && method.getParameterTypes().length == 0) { return getProperty(data, property, method); } // setter if (method.getName().startsWith("set") && method.getParameterTypes().length == 1) { data.putPOJO(property, args[0]); return null; } throw new RuntimeException("Not a property: "+method.getName()); } }); } private static Object getProperty(ObjectNode data, String property, Method method) { Class<?> returnType = method.getReturnType(); JsonNode value = data.get(property); if (Integer.class.equals(returnType) || int.class.equals(returnType)) { return value.asInt(); } else if (Double.class.equals(returnType) || double.class.equals(returnType)) { return value.asDouble(); } else if (Long.class.equals(returnType) || long.class.equals(returnType)) { return value.asLong(); } else if (Boolean.class.equals(returnType) || boolean.class.equals(returnType)) { return value.asBoolean(); } else if (String.class.equals(returnType)) { return value.asText(); } else if (returnType.isInterface() && Model.class.isAssignableFrom(returnType)) { if (value.isObject()) { return map(returnType, (ObjectNode) value); } else if (value.isPojo()) { return ((POJONode) value).getPojo(); } } throw new RuntimeException("Unknown return type: "+returnType); } }