Improve logging
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.json / src / main / java / org / argeo / server / json / JsonServerMapper.java
index 4ab128e0b51f24605ad98cb75f9c7646dd0634df..25b9f8d1753218d342427d18b9ef474afd1f1c87 100644 (file)
 package org.argeo.server.json;
 
-import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.argeo.server.ArgeoServerException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.ArgeoException;
+import org.argeo.server.Deserializer;
 import org.argeo.server.ServerDeserializer;
-import org.argeo.server.ServerSerializer;
-import org.codehaus.jackson.JsonFactory;
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.JsonProcessingException;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.DeserializationProblemHandler;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.deser.CustomDeserializerFactory;
+import org.codehaus.jackson.map.deser.StdDeserializerProvider;
+import org.springframework.beans.factory.InitializingBean;
 
-public class JsonServerMapper implements ServerSerializer, ServerDeserializer {
-       private JsonFactory jsonFactory = new JsonFactory();
-       private ObjectMapper objectMapper = new ObjectMapper();
+public class JsonServerMapper extends JsonServerSerializer implements
+               ServerDeserializer, Deserializer, InitializingBean {
+       private final static Log log = LogFactory.getLog(JsonServerMapper.class);
 
-       public void serialize(Object obj, HttpServletRequest request,
-                       HttpServletResponse response) {
-               try {
-                       response.setContentType("application/json");
+       private Class<?> targetClass;
+
+       private Map<Class<?>, JsonDeserializer<?>> deserializers = new HashMap<Class<?>, JsonDeserializer<?>>();
+
+       @SuppressWarnings("unchecked")
+       public void afterPropertiesSet() throws Exception {
+               CustomDeserializerFactory dsf = new CustomDeserializerFactory();
+               for (Class clss : deserializers.keySet()) {
+                       dsf.addSpecificMapping(clss, deserializers.get(clss));
+                       if (log.isDebugEnabled())
+                               log.debug("Add JSON mapping for " + clss);
+               }
+               StdDeserializerProvider sdp = new StdDeserializerProvider(dsf);
+               getObjectMapper().setDeserializerProvider(sdp);
+               // ignore unkown properties
+               getObjectMapper().getDeserializationConfig().addHandler(
+                               new DeserializationProblemHandler() {
+                                       public boolean handleUnknownProperty(
+                                                       DeserializationContext ctxt,
+                                                       JsonDeserializer<?> deserializer, Object bean,
+                                                       String propertyName) throws IOException,
+                                                       JsonProcessingException {
+                                               if (log.isTraceEnabled())
+                                                       log.debug("Ignore property " + propertyName
+                                                                       + " in bean " + bean);
+                                               ctxt.getParser().skipChildren();
+                                               return true;
+                                       }
+                               });
+       }
 
-                       JsonGenerator jsonGenerator = jsonFactory
-                                       .createJsonGenerator(response.getWriter());
-                       jsonGenerator.useDefaultPrettyPrinter();
+       public Object deserialize(Reader reader) {
+               try {
+                       if (log.isTraceEnabled()) {
+                               String str = IOUtils.toString(reader);
+                               log.debug(str);
+                               reader = new StringReader(str);
+                       }
 
-                       objectMapper.writeValue(jsonGenerator, obj);
+                       return getObjectMapper().readValue(reader, targetClass);
                } catch (Exception e) {
-                       throw new ArgeoServerException("Cannot serialize " + obj, e);
+                       throw new ArgeoException("Cannot deserialize " + reader, e);
                }
+
        }
 
-       public Object deserialize(Object obj, HttpServletRequest request) {
+       public <T> T deserialize(Reader reader, Class<T> clss) {
                try {
-                       String body = request.getParameter("body");
-                       if (body == null) {
-                               // lets read the message body instead
-                               BufferedReader reader = request.getReader();
-                               StringBuffer buffer = new StringBuffer();
-                               String line = null;
-                               while (((line = reader.readLine()) != null)) {
-                                       buffer.append(line);
-                               }
-                               body = buffer.toString();
+                       if (log.isTraceEnabled()) {
+                               String str = IOUtils.toString(reader);
+                               log.debug(str);
+                               reader = new StringReader(str);
                        }
-                       return objectMapper.readValue(body, Object.class);
+
+                       return getObjectMapper().readValue(reader, clss);
                } catch (Exception e) {
-                       throw new ArgeoServerException("Cannot deserialize " + request, e);
+                       throw new ArgeoException("Cannot deserialize " + reader, e);
                }
+
+       }
+
+       public Object deserialize(String content) {
+               StringReader reader = new StringReader(content);
+               try {
+                       return deserialize(reader);
+               } finally {
+                       IOUtils.closeQuietly(reader);
+               }
+       }
+
+       public void setTargetClass(Class<?> targetClass) {
+               this.targetClass = targetClass;
+       }
+
+       public void setDeserializers(
+                       Map<Class<?>, JsonDeserializer<?>> deserializers) {
+               this.deserializers = deserializers;
+       }
+
+       public Class<?> getTargetClass() {
+               return targetClass;
+       }
+
+       public Map<Class<?>, JsonDeserializer<?>> getDeserializers() {
+               return deserializers;
        }
 
 }