1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.ajax;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.io.Reader;
23 import java.io.Writer;
24 import java.io.OutputStreamWriter;
25 import java.io.StringWriter;
26 import java.util.HashMap;
27 import java.util.Map;
28
29 import javax.servlet.ServletOutputStream;
30 import javax.servlet.http.HttpServletResponse;
31
32 import org.apache.commons.logging.Log;
33 import org.apache.commons.logging.LogFactory;
34 import org.apache.jetspeed.layout.impl.Constants;
35 import org.apache.jetspeed.request.RequestContext;
36 import org.apache.velocity.VelocityContext;
37 import org.apache.velocity.app.VelocityEngine;
38 import org.apache.velocity.context.Context;
39 import org.apache.velocity.tools.generic.EscapeTool;
40
41 /***
42 *
43 * Provides a generic way to handle a Ajax request/response. Useful for AJAX since
44 * the processing can be broken down into actions and builders
45 */
46 public class AjaxRequestServiceImpl implements AjaxRequestService
47 {
48
49 protected static final String CONTENT_TYPE = "text/xml";
50
51 protected static final String AJAX_PROCESSOR = "AJAX processor";
52
53 protected static final String DEFAULT_ERROR = "<js><status>failure</status><action>unknown</action></js>";
54
55
56
57
58
59
60
61
62
63
64 protected static final String URL_PARAMETER_NAME = "action";
65
66 /*** Logger */
67 protected Log log = LogFactory.getLog(AjaxRequestServiceImpl.class);
68
69
70
71
72
73
74 protected Map objects;
75
76
77 protected VelocityEngine velocityEngine = null;
78
79
80 protected String urlParameterName = URL_PARAMETER_NAME;
81
82
83 protected String defaultAction = "getpage";
84
85
86 protected EscapeTool velocityEscTool = null;
87
88
89 public AjaxRequestServiceImpl(Map objects, VelocityEngine velocityEngine)
90 {
91 this.objects = objects;
92 this.velocityEngine = velocityEngine;
93 this.velocityEscTool = new EscapeTool();
94 }
95
96
97 public AjaxRequestServiceImpl(Map objects, VelocityEngine velocityEngine,
98 String urlParameterName)
99 {
100 this.objects = objects;
101 this.velocityEngine = velocityEngine;
102 this.urlParameterName = urlParameterName;
103 this.velocityEscTool = new EscapeTool();
104 }
105
106
107 public void process(RequestContext requestContext) throws AJAXException
108 {
109
110 String objectKey = requestContext.getRequestParameter(urlParameterName);
111 if (objectKey == null)
112 {
113 objectKey = defaultAction;
114 }
115
116 Object object = objects.get(objectKey);
117 if (object != null)
118 {
119 Map resultMap = new HashMap();
120
121 boolean success = true;
122 try
123 {
124
125
126 if (object instanceof AjaxAction)
127 {
128 success = processAction((AjaxAction) object,
129 requestContext, resultMap);
130 }
131 } catch (Exception e)
132 {
133 success = false;
134 }
135
136 try
137 {
138
139
140 if (object instanceof AjaxBuilder)
141 {
142 processBuilder((AjaxBuilder) object, resultMap,
143 requestContext, success);
144 }
145 } catch (Exception e)
146 {
147
148 buildError(requestContext);
149 }
150 } else
151 {
152
153 log.debug("could not find the object named:" + objectKey);
154
155
156 buildError(requestContext);
157 }
158 }
159
160
161 protected boolean processAction(AjaxAction action,
162 RequestContext requestContext, Map resultMap)
163 throws Exception
164 {
165 return action.run(requestContext, resultMap);
166 }
167
168
169 protected void processBuilder(AjaxBuilder builder, Map inputMap,
170 RequestContext requestContext, boolean actionSuccessFlag)
171 {
172
173 String format = requestContext.getRequestParameter("format");
174 if (format == null)
175 {
176 requestContext.getResponse().setContentType(CONTENT_TYPE);
177 }
178 else
179 {
180 if (format.equals("json"))
181 {
182 requestContext.getResponse().setContentType("text/json");
183 }
184 }
185
186 try
187 {
188
189
190
191 boolean result = true;
192
193 if (actionSuccessFlag == true)
194 {
195 result = builder.buildContext(requestContext, inputMap);
196 }
197 else
198 {
199 result = builder.buildErrorContext(requestContext, inputMap);
200 }
201
202 Context context = new VelocityContext(inputMap);
203 context.put("esc", this.velocityEscTool);
204
205
206 if (result)
207 {
208
209 String templateName = null;
210
211 if (actionSuccessFlag == true)
212 {
213 templateName = builder.getTemplate();
214 }
215 else
216 {
217 templateName = builder.getErrorTemplate();
218 }
219
220
221 final InputStream templateStream = this.getClass()
222 .getClassLoader().getResourceAsStream(templateName);
223
224 Reader template = new InputStreamReader(templateStream);
225
226
227 StringWriter stringWriter = new StringWriter();
228
229
230 velocityEngine.evaluate(context, stringWriter,
231 AJAX_PROCESSOR, template);
232
233
234 String buffer = stringWriter.getBuffer().toString();
235
236
237
238
239 HttpServletResponse response = requestContext.getResponse();
240 ServletOutputStream sos = response.getOutputStream();
241
242 Writer writer = new OutputStreamWriter(sos, "UTF-8");
243 writer.write(buffer);
244 writer.flush();
245 }
246 else
247 {
248 log.error("could not create builder context");
249 buildError(requestContext);
250 }
251 } catch (Exception e)
252 {
253 log.error("builder failed", e);
254 inputMap.put(Constants.REASON, e.toString());
255
256 buildError(requestContext);
257 }
258 }
259
260
261
262
263 protected void buildError(RequestContext requestContext)
264 {
265 try
266 {
267 requestContext.getResponse().getOutputStream().print(DEFAULT_ERROR);
268 }
269 catch (IOException e)
270 {
271
272 log.error("exception while trying to build an error message", e);
273 }
274 }
275
276 /***
277 * @return Returns the objects.
278 */
279 public Map getActionMap()
280 {
281 return objects;
282 }
283
284 }