]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - server/runtime/org.argeo.server.json/src/main/java/org/argeo/server/json/JsonServerSerializer.java
Add license headers
[lgpl/argeo-commons.git] / server / runtime / org.argeo.server.json / src / main / java / org / argeo / server / json / JsonServerSerializer.java
index 90a9c135c2815a37637f4d2f85b685a32c7ab38c..a77c7fd88a9f3f8c3d5b8d170380df60d4c08cac 100644 (file)
+/*
+ * Copyright (C) 2010 Mathieu Baudier <mbaudier@argeo.org>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *         http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.argeo.server.json;
 
 import java.io.IOException;
 import java.io.StringWriter;
+import java.io.Writer;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.argeo.server.ArgeoServerException;
+import org.argeo.ArgeoException;
+import org.argeo.server.Serializer;
 import org.argeo.server.ServerSerializer;
 import org.codehaus.jackson.JsonFactory;
 import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.JsonSerializer;
 import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.SerializationConfig;
+import org.codehaus.jackson.map.SerializerFactory;
+import org.codehaus.jackson.map.SerializerProvider;
+import org.codehaus.jackson.map.ser.StdSerializerProvider;
 
-public class JsonServerSerializer implements ServerSerializer {
+public class JsonServerSerializer implements ServerSerializer, Serializer {
        private final static Log log = LogFactory
                        .getLog(JsonServerSerializer.class);
 
        private JsonFactory jsonFactory = new JsonFactory();
        private ObjectMapper objectMapper = new ObjectMapper();
+       private SerializerProvider serializerProvider = new CustomSerializerProvider();
+
+       private Boolean prettyPrint = false;
+
+       private Boolean asHtml = false;
+
+       private String contentTypeCharset = "UTF-8";
 
-       private Boolean prettyPrint = true;
+       // private Map<Class<?>,String> ignoredFields = new HashMap<Class<?>,
+       // String>();
 
+       public JsonServerSerializer() {
+               objectMapper.setSerializerProvider(serializerProvider);
+       }
+
+       @SuppressWarnings("restriction")
        public void serialize(Object obj, HttpServletRequest request,
                        HttpServletResponse response) {
-               JsonGenerator jsonGenerator = null;
+               if (asHtml)
+                       response.setContentType("text/html;charset=" + contentTypeCharset);
+               else
+                       response.setContentType("application/json;charset="
+                                       + contentTypeCharset);
+
                try {
-                       response.setContentType("application/json");
+                       if (asHtml)
+                               response.getWriter().append("<pre>");
+
+                       serialize(obj, response.getWriter());
+
+                       if (asHtml)
+                               response.getWriter().append("</pre>");
+
+               } catch (IOException e) {
+                       throw new ArgeoException("Cannot open response stream.", e);
+               }
+       }
 
-                       StringWriter stringWriter = null;
-                       if (log.isTraceEnabled()) {
-                               stringWriter = new StringWriter();
-                               jsonGenerator = jsonFactory.createJsonGenerator(stringWriter);
-                       } else {
-                               jsonGenerator = jsonFactory.createJsonGenerator(response
-                                               .getWriter());
-                       }
+       public void serialize(Object obj, Writer writer) {
+               serializeAndLog(obj);
+
+               JsonGenerator jsonGenerator = null;
+               try {
+                       jsonGenerator = jsonFactory.createJsonGenerator(writer);
 
                        if (prettyPrint)
                                jsonGenerator.useDefaultPrettyPrinter();
 
                        objectMapper.writeValue(jsonGenerator, obj);
+                       jsonGenerator.flush();
+               } catch (Exception e) {
+                       throw new ArgeoException("Cannot serialize " + obj, e);
+               } finally {
+                       if (jsonGenerator != null)
+                               try {
+                                       jsonGenerator.close();
+                               } catch (IOException e) {
+                                       if (log.isTraceEnabled())
+                                               log.error("Cannot close JSON generator", e);
+                               }
+               }
+       }
 
-                       jsonGenerator.close();
+       @Deprecated
+       public void serialize(Writer writer, Object obj) {
+               serialize(obj, writer);
+       }
 
-                       if (stringWriter != null) {
-                               if (log.isTraceEnabled())
-                                       log.debug(stringWriter.toString());
-                               response.getWriter().append(stringWriter.toString());
-                       }
+       protected void serializeAndLog(Object obj) {
+               if (!log.isTraceEnabled())
+                       return;
 
+               JsonGenerator jsonGenerator = null;
+               try {
+                       StringWriter stringWriter = new StringWriter();
+                       jsonGenerator = jsonFactory.createJsonGenerator(stringWriter);
+                       jsonGenerator.useDefaultPrettyPrinter();
+                       objectMapper.writeValue(jsonGenerator, obj);
+                       jsonGenerator.close();
+                       log.debug(stringWriter.toString());
                } catch (Exception e) {
-                       throw new ArgeoServerException("Cannot serialize " + obj, e);
+                       throw new ArgeoException("Cannot log JSON", e);
                } finally {
                        if (jsonGenerator != null)
                                try {
@@ -61,6 +134,7 @@ public class JsonServerSerializer implements ServerSerializer {
                                        if (log.isTraceEnabled())
                                                log.error("Cannot close JSON generator", e);
                                }
+
                }
        }
 
@@ -71,4 +145,48 @@ public class JsonServerSerializer implements ServerSerializer {
        protected ObjectMapper getObjectMapper() {
                return objectMapper;
        }
+
+       public void setContentTypeCharset(String contentTypeCharset) {
+               this.contentTypeCharset = contentTypeCharset;
+       }
+
+       static class CustomSerializerProvider extends StdSerializerProvider {
+
+               public CustomSerializerProvider() {
+                       super();
+               }
+
+               public CustomSerializerProvider(SerializationConfig config,
+                               StdSerializerProvider src, SerializerFactory f) {
+                       super(config, src, f);
+               }
+
+               protected StdSerializerProvider createInstance(
+                               SerializationConfig config, SerializerFactory jsf) {
+                       return new CustomSerializerProvider(config, this, jsf);
+               }
+
+               @Override
+               public JsonSerializer<Object> getUnknownTypeSerializer(
+                               Class<?> unknownType) {
+                       JsonSerializer<Object> res = new JsonSerializer<Object>() {
+                               public void serialize(Object value, JsonGenerator jgen,
+                                               SerializerProvider provider)
+                                               throws JsonMappingException {
+                                       if (log.isDebugEnabled())
+                                               log.warn("Unknown serializer for "
+                                                               + value.getClass().getName());
+                                       try {
+                                               jgen.writeNull();
+                                       } catch (Exception e) {
+                                               throw new ArgeoException("Cannot write null", e);
+                                       }
+                               }
+
+                       };
+
+                       return res;
+               }
+
+       }
 }