Project

General

Profile

Download (6.78 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.remote.view;
10

    
11
import java.io.PrintWriter;
12
import java.util.Collection;
13
import java.util.Map;
14

    
15
import javax.servlet.http.HttpServletRequest;
16
import javax.servlet.http.HttpServletResponse;
17

    
18
import org.apache.commons.beanutils.BeanUtilsBean;
19
import org.apache.commons.beanutils.SuppressPropertiesBeanIntrospector;
20
import org.apache.log4j.Logger;
21
import org.springframework.web.servlet.View;
22

    
23
import eu.etaxonomy.cdm.opt.config.DataSourceProperties;
24
import eu.etaxonomy.cdm.remote.json.JsonpUtil;
25
import net.sf.json.JSON;
26
import net.sf.json.JSONArray;
27
import net.sf.json.JSONObject;
28
import net.sf.json.JsonConfig;
29
import net.sf.json.xml.XMLSerializer;
30

    
31

    
32
public class JsonView extends BaseView implements View {
33

    
34
    static {
35
        optOut_BEANUTILS_520();
36
    }
37

    
38
    /**
39
     * BEANUTILS-520 Fixes CVE-2014-0114: https://nvd.nist.gov/vuln/detail/CVE-2014-0114
40
     * This patch by default enables the SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS.
41
     *
42
     * see https://github.com/apache/commons-beanutils/pull/7
43
     */
44
    static private void optOut_BEANUTILS_520() {
45
        final BeanUtilsBean bub = new BeanUtilsBean();
46
        bub.getPropertyUtils().removeBeanIntrospector(SuppressPropertiesBeanIntrospector.SUPPRESS_CLASS);
47
        BeanUtilsBean.setInstance(bub);
48
    }
49

    
50
    public static final Logger logger = Logger.getLogger(JsonView.class);
51

    
52
    private JsonConfig jsonConfig;
53

    
54
    private DataSourceProperties dataSourceProperties;
55

    
56
    public DataSourceProperties getDataSourceProperties() {
57
        return dataSourceProperties;
58
    }
59

    
60
    public void setDataSourceProperties(DataSourceProperties dataSourceProperties) {
61
        this.dataSourceProperties = dataSourceProperties;
62
    }
63

    
64
    public enum Type{
65
        JSON("application/json"),
66
        XML("application/xml");
67

    
68
        private final String contentType;
69

    
70
        Type(String contentType){
71
            this.contentType = contentType;
72
        }
73

    
74
        public String getContentType(){
75
            return contentType;
76
        }
77
    }
78

    
79
    private Type type = Type.JSON;
80

    
81
    private String xsl = null;
82

    
83
    public void setXsl(String xsl) {
84
        this.xsl = xsl;
85
    }
86

    
87
    public String getXsl() {
88
        return xsl;
89
    }
90

    
91
    public Type getType() {
92
        return type;
93
    }
94

    
95
    /**
96
     * Default is Type.JSON
97
     * @param type
98
     */
99
    public void setType(Type type) {
100
        this.type = type;
101
    }
102

    
103
    public void setJsonConfig(JsonConfig jsonConfig) {
104
        this.jsonConfig = jsonConfig;
105
    }
106

    
107
    @Override
108
    public String getContentType() {
109
        return type.getContentType();
110
    }
111

    
112
    @Override
113
    public void render(Object entity, PrintWriter writer, String jsonpCallback, HttpServletRequest request, HttpServletResponse response) throws Exception {
114

    
115
        String contextPath = null;
116

    
117
        if (request != null)
118
        	{
119
        	contextPath = request.getContextPath();
120
        	}
121

    
122
        if(jsonConfig == null){
123
            logger.error("The jsonConfig must not be null. It must be set in the applicationContext.");
124
        }
125

    
126
        // option to skip json processing for debugging purposes, see #4925
127
        if(System.getProperty("SkipJSON") == null) {
128

    
129
        // create JSON Object
130

    
131
//        long start = System.currentTimeMillis();
132
        boolean isCollectionType = false;
133
        JSON jsonObj;
134
        if (entity == null){
135
          jsonObj = JSONObject.fromObject("{}");
136
        } else if(Collection.class.isAssignableFrom(entity.getClass())){
137
            isCollectionType = true;
138
            jsonObj = JSONArray.fromObject(entity, jsonConfig);
139
        }else if(entity instanceof String){
140
            jsonObj = JSONObject.fromObject("{\"String\":\""+entity.toString().replace("\"", "\\\"")+"\"}");
141
        } else if(entity instanceof Integer){
142
            jsonObj = JSONObject.fromObject("{\"Integer\":"+((Integer)entity).intValue()+"}");
143
        } else if(entity instanceof Boolean){
144
            jsonObj = JSONObject.fromObject("{\"Boolean\":"+((Boolean)entity).toString()+"}");
145
        } else {
146
            jsonObj = JSONObject.fromObject(entity, jsonConfig);
147
        }
148
//        System.err.println("create JSON Object " + (System.currentTimeMillis() - start));
149

    
150
        if(type.equals(Type.XML)){
151
            XMLSerializer xmlSerializer = new XMLSerializer();
152
            if(isCollectionType){
153
                xmlSerializer.setArrayName(entity.getClass().getSimpleName());
154
                Class elementType = Object.class;
155
                Collection c = (Collection)entity;
156
                if(c.size() > 0){
157
                    elementType = c.iterator().next().getClass();
158
                }
159
                xmlSerializer.setObjectName(elementType.getSimpleName());
160
            } else if(entity != null){
161
                xmlSerializer.setObjectName(entity.getClass().getSimpleName());
162
            }
163
            String xml = xmlSerializer.write( jsonObj );
164
            if(type.equals(Type.XML) && xsl != null){
165

    
166
                if(contextPath == null){
167
                    contextPath = "";
168
                }
169
                String basepath = dataSourceProperties.getXslBasePath(contextPath + "/xsl");
170
                String replace = "\r\n<?xml-stylesheet type=\"text/xsl\" href=\"" + basepath + "/" + xsl + "\"?>\r\n";
171
                xml = xml.replaceFirst("\r\n", replace);
172
            }
173
            writer.append(xml);
174
        } else {
175
            // assuming json
176
            if(jsonpCallback != null){
177
               // writer.append(jsonpCallback).append("(").append(jsonObj.toString()).append(");");
178
            } else {
179
                writer.append(jsonObj.toString());
180
            }
181
        }
182
        //TODO resp.setContentType(type);
183

    
184
        } else {
185
            writer.append("SkipJSON mode detected, this is for debugging only! Please contact the adminitrator.");
186
            // END SkipJSON
187
        }
188
        writer.flush();
189
    }
190

    
191
    @Override
192
    public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception {
193

    
194
        // Retrieve data from model
195
        Object entity = getResponseData(model);
196

    
197
        // set content type
198
        response.setContentType(type.getContentType());
199

    
200
        PrintWriter writer = response.getWriter();
201

    
202
        // read jsonp parameter from the request
203
        String jsonpCallback = JsonpUtil.readJsonpCallback(request);
204

    
205
        // render
206
        render(entity, writer, jsonpCallback, request, response);
207
    }
208

    
209

    
210
}
(5-5/10)