]> git.argeo.org Git - lgpl/argeo-commons.git/blob - GenericJsonDeserializer.java
5c865af961b845b5662efa05c68b75fd1130cbc5
[lgpl/argeo-commons.git] / GenericJsonDeserializer.java
1 package org.argeo.server.json;
2
3 import java.io.IOException;
4 import java.io.StringWriter;
5 import java.util.ArrayList;
6 import java.util.List;
7
8 import org.apache.commons.logging.Log;
9 import org.apache.commons.logging.LogFactory;
10 import org.argeo.ArgeoException;
11 import org.codehaus.jackson.JsonFactory;
12 import org.codehaus.jackson.JsonGenerator;
13 import org.codehaus.jackson.JsonNode;
14 import org.codehaus.jackson.JsonParser;
15 import org.codehaus.jackson.JsonProcessingException;
16 import org.codehaus.jackson.ObjectCodec;
17 import org.codehaus.jackson.map.DeserializationContext;
18 import org.codehaus.jackson.map.JsonDeserializer;
19 import org.codehaus.jackson.map.ObjectMapper;
20
21 public class GenericJsonDeserializer<T> extends JsonDeserializer<T> {
22 private final static Log log = LogFactory
23 .getLog(GenericJsonDeserializer.class);
24
25 private JsonFactory jsonFactory = new JsonFactory();
26 private ObjectCodec objectCodec = new ObjectMapper();
27 private JsonObjectFactory defaultObjectFactory = new JsonObjectFactoryImpl();
28
29 private String typeField = "type";
30
31 private List<JsonObjectFactory> objectFactories = new ArrayList<JsonObjectFactory>();
32
33 @SuppressWarnings("unchecked")
34 @Override
35 public T deserialize(JsonParser parser, DeserializationContext ctxt)
36 throws IOException, JsonProcessingException {
37 // first read as Json DOM in order to extract the type
38 // TODO: optimize with streaming API
39 JsonNode root = parser.readValueAsTree();
40 String type = root.get(typeField).getTextValue();
41
42 // Write it back as a string
43 StringWriter writer = new StringWriter();
44 JsonGenerator generator = jsonFactory.createJsonGenerator(writer);
45 generator.setCodec(objectCodec);
46 generator.writeTree(root);
47 String str = writer.toString();
48
49 if (log.isTraceEnabled())
50 log.debug("Deserialize object of type=" + type + ", str=" + str);
51
52 JsonObjectFactory objectFactory = null;
53 jofs: for (JsonObjectFactory jof : objectFactories) {
54 if (jof.supports(type)) {
55 objectFactory = jof;
56 break jofs;
57 }
58 }
59
60 if (objectFactory == null)
61 objectFactory = defaultObjectFactory;
62
63 if (objectFactory == null || !objectFactory.supports(type))
64 throw new ArgeoException(
65 "Cannot find JSON object factory for type " + type);
66
67 return (T) objectFactory.readValue(type, str);
68 }
69
70 public void setTypeField(String typeField) {
71 this.typeField = typeField;
72 }
73
74 public void setObjectFactories(List<JsonObjectFactory> objectFactories) {
75 this.objectFactories = objectFactories;
76 }
77
78 public List<JsonObjectFactory> getObjectFactories() {
79 return objectFactories;
80 }
81
82 }