merging revisions 14601:14603, 14653:14683 from branches/cdmlib/vibrant-index into...
[cdmlib.git] / cdmlib-remote / src / main / java / eu / etaxonomy / cdm / remote / view / JsonView.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.remote.view;
11
12 import java.io.PrintWriter;
13 import java.util.Collection;
14 import java.util.Map;
15 import java.util.regex.Matcher;
16 import java.util.regex.Pattern;
17
18 import javax.servlet.http.HttpServletRequest;
19 import javax.servlet.http.HttpServletResponse;
20
21 import net.sf.json.JSON;
22 import net.sf.json.JSONArray;
23 import net.sf.json.JSONObject;
24 import net.sf.json.JsonConfig;
25 import net.sf.json.xml.XMLSerializer;
26
27 import org.apache.log4j.Logger;
28 import org.springframework.web.servlet.View;
29
30
31 public class JsonView extends BaseView implements View{
32
33 public static final Logger logger = Logger.getLogger(JsonView.class);
34
35 private JsonConfig jsonConfig;
36
37 public enum Type{
38 JSON("application/json"),
39 XML("application/xml");
40
41 private String contentType;
42
43 Type(String contentType){
44 this.contentType = contentType;
45 }
46
47 public String getContentType(){
48 return contentType;
49 }
50 }
51
52 private Type type = Type.JSON;
53
54 private String xsl = null;
55
56 public void setXsl(String xsl) {
57 this.xsl = xsl;
58 }
59
60 public String getXsl() {
61 return xsl;
62 }
63
64 public Type getType() {
65 return type;
66 }
67
68 /**
69 * Default is Type.JSON
70 * @param type
71 */
72 public void setType(Type type) {
73 this.type = type;
74 }
75
76 public void setJsonConfig(JsonConfig jsonConfig) {
77 this.jsonConfig = jsonConfig;
78 }
79
80 /*
81 * (non-Javadoc)
82 * @see org.springframework.web.servlet.View#getContentType()
83 */
84 public String getContentType() {
85 return type.getContentType();
86 }
87
88 public void render(Object entity, PrintWriter writer, String documentContextPath, String jsonpCallback) throws Exception {
89
90 if(jsonConfig == null){
91 logger.error("The jsonConfig must not be null. It must be set in the applicationContext.");
92 }
93
94 // create JSON Object
95 boolean isCollectionType = false;
96 JSON jsonObj;
97 if (entity == null){
98 jsonObj = JSONObject.fromObject("{}");
99 } else if(Collection.class.isAssignableFrom(entity.getClass())){
100 isCollectionType = true;
101 jsonObj = JSONArray.fromObject(entity, jsonConfig);
102 }else if(entity instanceof String){
103 jsonObj = JSONObject.fromObject("{\"String\":\""+entity.toString().replace("\"", "\\\"")+"\"}");
104 } else if(entity instanceof Integer){
105 jsonObj = JSONObject.fromObject("{\"Integer\":"+((Integer)entity).intValue()+"}");
106 } else if(entity instanceof Boolean){
107 jsonObj = JSONObject.fromObject("{\"Boolean\":"+((Boolean)entity).toString()+"}");
108 } else {
109 jsonObj = JSONObject.fromObject(entity, jsonConfig);
110 }
111
112 if(type.equals(Type.XML)){
113 XMLSerializer xmlSerializer = new XMLSerializer();
114 if(isCollectionType){
115 xmlSerializer.setArrayName(entity.getClass().getSimpleName());
116 Class elementType = Object.class;
117 Collection c = (Collection)entity;
118 if(c.size() > 0){
119 elementType = c.iterator().next().getClass();
120 }
121 xmlSerializer.setObjectName(elementType.getSimpleName());
122 } else if(entity != null){
123 xmlSerializer.setObjectName(entity.getClass().getSimpleName());
124 }
125 String xml = xmlSerializer.write( jsonObj );
126 if(type.equals(Type.XML) && xsl != null){
127 if(documentContextPath == null){
128 documentContextPath = "";
129 }
130 String replace = "\r\n<?xml-stylesheet type=\"text/xsl\" href=\"" + documentContextPath + "/" + xsl + "\"?>\r\n";
131 xml = xml.replaceFirst("\r\n", replace);
132 }
133 writer.append(xml);
134 } else {
135 // assuming json
136 if(jsonpCallback != null){
137 writer.append(jsonpCallback).append("(").append(jsonObj.toString()).append(")");
138 } else {
139 writer.append(jsonObj.toString());
140 }
141 }
142 //TODO resp.setContentType(type);
143 writer.flush();
144 }
145
146 /*
147 * (non-Javadoc)
148 * @see org.springframework.web.servlet.View#render(java.util.Map, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
149 */
150 public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
151
152 // Retrieve data from model
153 Object entity = getResponseData(model);
154
155 // set content type
156 response.setContentType(type.getContentType());
157
158 PrintWriter writer = response.getWriter();
159
160 // read jsonp parameter from query string
161 String[] tokens = request.getQueryString().split("&", 0);
162 String jsonpParamName = "callback";
163 String jsonpCallback= null;
164 for (int i = 0; i < tokens.length; i++) {
165 if(tokens[i].startsWith(jsonpParamName)){
166 jsonpCallback = tokens[i].substring(jsonpParamName.length() + 1);
167 break;
168 }
169 }
170
171 // render
172 render(entity, writer, request.getContextPath(), jsonpCallback);
173 }
174 }