|
@ -19,27 +19,73 @@ import java.io.IOException; |
|
|
import java.io.InputStream; |
|
|
import java.io.InputStream; |
|
|
import java.io.OutputStream; |
|
|
import java.io.OutputStream; |
|
|
import java.util.ArrayList; |
|
|
import java.util.ArrayList; |
|
|
|
|
|
import java.util.Collections; |
|
|
import java.util.Iterator; |
|
|
import java.util.Iterator; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
import java.util.Map; |
|
|
import java.util.Map; |
|
|
|
|
|
import java.util.Set; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
import java.util.concurrent.ConcurrentHashMap; |
|
|
|
|
|
|
|
|
import org.codehaus.jackson.JsonNode; |
|
|
import org.codehaus.jackson.JsonNode; |
|
|
import org.codehaus.jackson.JsonParser; |
|
|
import org.codehaus.jackson.JsonParser; |
|
|
import org.codehaus.jackson.JsonProcessingException; |
|
|
import org.codehaus.jackson.JsonProcessingException; |
|
|
import org.codehaus.jackson.Version; |
|
|
import org.codehaus.jackson.Version; |
|
|
|
|
|
import org.codehaus.jackson.annotate.JsonTypeInfo; |
|
|
import org.codehaus.jackson.map.DeserializationContext; |
|
|
import org.codehaus.jackson.map.DeserializationContext; |
|
|
import org.codehaus.jackson.map.ObjectMapper; |
|
|
import org.codehaus.jackson.map.ObjectMapper; |
|
|
|
|
|
import org.codehaus.jackson.map.ObjectMapper.DefaultTypeResolverBuilder; |
|
|
|
|
|
import org.codehaus.jackson.map.ObjectMapper.DefaultTyping; |
|
|
import org.codehaus.jackson.map.annotate.JsonSerialize; |
|
|
import org.codehaus.jackson.map.annotate.JsonSerialize; |
|
|
|
|
|
import org.codehaus.jackson.map.deser.BeanDeserializer; |
|
|
import org.codehaus.jackson.map.deser.std.StdDeserializer; |
|
|
import org.codehaus.jackson.map.deser.std.StdDeserializer; |
|
|
|
|
|
import org.codehaus.jackson.map.jsontype.TypeResolverBuilder; |
|
|
import org.codehaus.jackson.map.module.SimpleModule; |
|
|
import org.codehaus.jackson.map.module.SimpleModule; |
|
|
import org.codehaus.jackson.node.ObjectNode; |
|
|
import org.codehaus.jackson.node.ObjectNode; |
|
|
|
|
|
|
|
|
|
|
|
import com.corundumstudio.socketio.Configuration; |
|
|
|
|
|
|
|
|
public class JacksonJsonSupport implements JsonSupport { |
|
|
public class JacksonJsonSupport implements JsonSupport { |
|
|
|
|
|
|
|
|
|
|
|
private class JsonObjectDeserializer extends StdDeserializer<JsonObject> { |
|
|
|
|
|
|
|
|
|
|
|
final Set<Class<?>> classes = Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>()); |
|
|
|
|
|
|
|
|
|
|
|
protected JsonObjectDeserializer() { |
|
|
|
|
|
super(JsonObject.class); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public JsonObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, |
|
|
|
|
|
JsonProcessingException { |
|
|
|
|
|
ObjectMapper mapper = (ObjectMapper) jp.getCodec(); |
|
|
|
|
|
JsonNode rootNode = mapper.readTree(jp); |
|
|
|
|
|
if (!rootNode.isObject()) { |
|
|
|
|
|
return null; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Class<?> clazz = Object.class; |
|
|
|
|
|
ObjectNode root = (ObjectNode) rootNode; |
|
|
|
|
|
JsonNode node = root.remove(configuration.getJsonTypeFieldName()); |
|
|
|
|
|
if (node != null) { |
|
|
|
|
|
try { |
|
|
|
|
|
String typeName = node.asText(); |
|
|
|
|
|
Class<?> supportClazz = Class.forName(typeName); |
|
|
|
|
|
if (classes.contains(supportClazz)) { |
|
|
|
|
|
clazz = supportClazz; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (ClassNotFoundException e) { |
|
|
|
|
|
// skip it |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
Object val = mapper.readValue(root, clazz); |
|
|
|
|
|
return new JsonObject(val); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private class EventDeserializer extends StdDeserializer<Event> { |
|
|
private class EventDeserializer extends StdDeserializer<Event> { |
|
|
|
|
|
|
|
|
Map<String, Class<?>> eventMapping = new ConcurrentHashMap<String, Class<?>>(); |
|
|
|
|
|
|
|
|
final Map<String, Class<?>> eventMapping = new ConcurrentHashMap<String, Class<?>>(); |
|
|
|
|
|
|
|
|
protected EventDeserializer() { |
|
|
protected EventDeserializer() { |
|
|
super(Event.class); |
|
|
super(Event.class); |
|
@ -74,20 +120,40 @@ public class JacksonJsonSupport implements JsonSupport { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private final Configuration configuration; |
|
|
private final ObjectMapper objectMapper = new ObjectMapper(); |
|
|
private final ObjectMapper objectMapper = new ObjectMapper(); |
|
|
private final EventDeserializer eventDeserializer = new EventDeserializer(); |
|
|
private final EventDeserializer eventDeserializer = new EventDeserializer(); |
|
|
|
|
|
private final JsonObjectDeserializer jsonObjectDeserializer = new JsonObjectDeserializer(); |
|
|
|
|
|
|
|
|
|
|
|
public JacksonJsonSupport(Configuration configuration) { |
|
|
|
|
|
this.configuration = configuration; |
|
|
|
|
|
|
|
|
public JacksonJsonSupport() { |
|
|
|
|
|
SimpleModule module = new SimpleModule("EventDeserializerModule", new Version(1, 0, 0, null)); |
|
|
SimpleModule module = new SimpleModule("EventDeserializerModule", new Version(1, 0, 0, null)); |
|
|
module.addDeserializer(Event.class, eventDeserializer); |
|
|
module.addDeserializer(Event.class, eventDeserializer); |
|
|
|
|
|
module.addDeserializer(JsonObject.class, jsonObjectDeserializer); |
|
|
|
|
|
|
|
|
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); |
|
|
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); |
|
|
objectMapper.registerModule(module); |
|
|
objectMapper.registerModule(module); |
|
|
|
|
|
|
|
|
|
|
|
// TODO If jsonObjectDeserializer will be not enough |
|
|
|
|
|
// TypeResolverBuilder<?> typer = new DefaultTypeResolverBuilder(DefaultTyping.NON_FINAL); |
|
|
|
|
|
// typer.init(JsonTypeInfo.Id.CLASS, null); |
|
|
|
|
|
// typer.inclusion(JsonTypeInfo.As.PROPERTY); |
|
|
|
|
|
// typer.typeProperty(configuration.getJsonTypeFieldName()); |
|
|
|
|
|
// objectMapper.setDefaultTyping(typer); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
public void addEventMapping(String eventName, Class<?> eventClass) { |
|
|
public void addEventMapping(String eventName, Class<?> eventClass) { |
|
|
eventDeserializer.eventMapping.put(eventName, eventClass); |
|
|
eventDeserializer.eventMapping.put(eventName, eventClass); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public void addJsonClass(Class<?> clazz) { |
|
|
|
|
|
jsonObjectDeserializer.classes.add(clazz); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
public void removeEventMapping(String eventName) { |
|
|
public void removeEventMapping(String eventName) { |
|
|
eventDeserializer.eventMapping.remove(eventName); |
|
|
eventDeserializer.eventMapping.remove(eventName); |
|
|
} |
|
|
} |
|
|