1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.jetspeed.layout.impl;
18
19 import java.io.InputStream;
20 import java.io.InputStreamReader;
21 import java.io.Reader;
22 import java.io.StringWriter;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.StringTokenizer;
28
29 import org.apache.jetspeed.ajax.AJAXException;
30 import org.apache.jetspeed.ajax.AjaxAction;
31 import org.apache.jetspeed.ajax.AjaxBuilder;
32 import org.apache.jetspeed.ajax.AjaxRequestService;
33 import org.apache.jetspeed.layout.PortletActionSecurityBehavior;
34 import org.apache.jetspeed.page.PageManager;
35 import org.apache.jetspeed.request.JetspeedRequestContext;
36 import org.apache.jetspeed.request.RequestContext;
37 import org.apache.velocity.VelocityContext;
38 import org.apache.velocity.app.VelocityEngine;
39 import org.apache.velocity.context.Context;
40 import org.springframework.beans.BeansException;
41 import org.springframework.beans.factory.BeanFactory;
42 import org.springframework.beans.factory.BeanFactoryAware;
43
44 /***
45 *
46 * @author David Gurney
47 *
48 * The purpose of this object is to run several AJAX actions and aggregate the
49 * results into a single response. This is useful when the client needs to make
50 * more than one call as the result of a single user action.
51 *
52 * The sample request URL is shown below:
53 *
54 * http://host:port/ajaxapi?action=multiple&commands=(action;name,value;name,value)(action;name,value)
55 *
56 * The constructor accepts a map of the actions that are available to be run.
57 * The name,value pairs are parameter values needed by the action. The actions
58 * are run in the order that they are found on the URL string
59 *
60 */
61 public class MultipleAction extends BasePortletAction implements AjaxAction,
62 AjaxBuilder, BeanFactoryAware
63 {
64
65 protected static final String ALL_RESULTS = "results";
66
67 protected static final String BUILD_RESULTS = "buildresults";
68
69 protected static final String MULTIPLE_ACTION_PROCESSOR = "Multiple Action Processor";
70
71 protected static final String COMMANDS = "commands";
72
73 protected static final String COMMAND_TOKEN = ")";
74
75 protected static final String PARAM_TOKEN = ";";
76
77 protected static final String VALUE_TOKEN = ",";
78
79 protected Map actionMap = null;
80
81 protected VelocityEngine m_oVelocityEngine = null;
82
83 public MultipleAction(AjaxRequestService requestService, String p_sTemplate,
84 String p_sErrorTemplate, PageManager p_oPageManager,
85 PortletActionSecurityBehavior p_oSecurityBehavior,
86 VelocityEngine p_oVelocityEngine)
87 {
88 super(p_sTemplate, p_sErrorTemplate, p_oPageManager,
89 p_oSecurityBehavior);
90 actionMap = requestService.getActionMap();
91 m_oVelocityEngine = p_oVelocityEngine;
92 }
93
94 public void setBeanFactory(BeanFactory beanFactory) throws BeansException
95 {
96
97 Object proxy = beanFactory.getBean("AjaxMultipleAction");
98 actionMap.put("multiple", proxy);
99 }
100
101 public boolean run(RequestContext p_oRequestContext, Map p_oResultMap)
102 throws AJAXException
103 {
104 boolean a_bReturnSuccess = true;
105 List a_oResultArray = new ArrayList();
106
107 p_oResultMap.put(ACTION, "multiple");
108 p_oResultMap.put(STATUS, "success");
109
110
111 String a_sCommands = p_oRequestContext.getRequestParameter(COMMANDS);
112 if (a_sCommands == null || a_sCommands.length() <= 0)
113 {
114 buildErrorContext(p_oRequestContext, p_oResultMap);
115 p_oResultMap.put(STATUS, "failure");
116 p_oResultMap.put(REASON, "command parameters not found");
117
118 throw new AJAXException("command parameters not found");
119 }
120
121
122 StringTokenizer a_oCommandTok = new StringTokenizer(a_sCommands,
123 COMMAND_TOKEN);
124
125
126 while (a_oCommandTok.hasMoreTokens())
127 {
128
129 String a_sCommand = a_oCommandTok.nextToken();
130
131
132 a_sCommand = a_sCommand.substring(1);
133
134
135 StringTokenizer a_oParamTok = new StringTokenizer(a_sCommand,
136 PARAM_TOKEN);
137 if (a_oParamTok == null || a_oParamTok.hasMoreTokens() == false)
138 {
139 buildErrorContext(p_oRequestContext, p_oResultMap);
140 p_oResultMap.put(STATUS, "failure");
141 p_oResultMap.put(REASON, "incorrect url request");
142
143 throw new AJAXException("incorrect url request");
144 }
145
146
147 String a_sAction = a_oParamTok.nextToken();
148
149
150 Object a_oActionObject = actionMap.get(a_sAction);
151 if (a_oActionObject == null
152 && !(a_oActionObject instanceof AjaxAction))
153 {
154 buildErrorContext(p_oRequestContext, p_oResultMap);
155 p_oResultMap.put(REASON, "unknown action requested==>"
156 + a_sAction);
157
158 throw new AJAXException("unknown action requested==>"
159 + a_sAction);
160 }
161
162 AjaxAction a_oAction = (AjaxAction) a_oActionObject;
163
164 JetspeedRequestContext a_oJetspeedRequestContext = (JetspeedRequestContext) p_oRequestContext;
165
166
167 while (a_oParamTok.hasMoreTokens())
168 {
169 String a_sName = a_oParamTok.nextToken(VALUE_TOKEN);
170
171 if (a_sName.indexOf(';') >= 0)
172 {
173 a_sName = a_sName.substring(1);
174 }
175
176 String a_sValue = a_oParamTok.nextToken();
177
178
179 a_oJetspeedRequestContext.setAttribute(a_sName, a_sValue);
180 }
181
182
183 Map a_oResultMap = new HashMap();
184 boolean a_bSuccess;
185
186 try
187 {
188 a_bSuccess = a_oAction.runBatch(a_oJetspeedRequestContext,
189 a_oResultMap);
190 } catch (Exception e)
191 {
192
193 p_oResultMap.put(REASON, a_oResultMap.get(REASON));
194
195 throw new AJAXException(e);
196 }
197
198
199 if (a_bSuccess)
200 {
201
202 if (a_oAction instanceof AjaxBuilder)
203 {
204 processBuilder((AjaxBuilder) a_oAction, a_oResultMap,
205 p_oRequestContext, a_bSuccess);
206 }
207
208
209 String a_sBuildResults = (String) a_oResultMap
210 .get(BUILD_RESULTS);
211
212
213 int a_iStartIndex = a_sBuildResults.indexOf("<?xml");
214 if (a_iStartIndex >= 0)
215 {
216
217 int a_iEndIndex = a_sBuildResults.indexOf(">",
218 a_iStartIndex);
219 if (a_iEndIndex >= 0)
220 {
221 String a_sStart = a_sBuildResults.substring(0,
222 a_iStartIndex);
223 String a_sEnd = a_sBuildResults.substring(
224 a_iEndIndex + 1, a_sBuildResults.length());
225 a_sBuildResults = a_sStart + a_sEnd;
226 }
227 }
228
229 if (a_sBuildResults != null)
230 {
231
232 a_oResultArray.add(a_sBuildResults);
233 }
234 } else
235 {
236
237 p_oResultMap.put(REASON, a_oResultMap.get(REASON));
238
239
240 a_bReturnSuccess = false;
241 break;
242 }
243 }
244
245
246 p_oResultMap.put(ALL_RESULTS, a_oResultArray);
247
248 return a_bReturnSuccess;
249 }
250
251
252 protected void processBuilder(AjaxBuilder p_oBuilder, Map p_oInputMap,
253 RequestContext p_oRequestContext, boolean p_oActionSuccessFlag)
254 {
255 try
256 {
257
258
259 boolean result = true;
260
261 if (p_oActionSuccessFlag == true)
262 {
263 result = p_oBuilder
264 .buildContext(p_oRequestContext, p_oInputMap);
265 } else
266 {
267 result = p_oBuilder.buildErrorContext(p_oRequestContext,
268 p_oInputMap);
269 }
270
271 Context a_oContext = new VelocityContext(p_oInputMap);
272
273
274 if (result)
275 {
276
277 String a_sTemplateName = null;
278
279 if (p_oActionSuccessFlag == true)
280 {
281 a_sTemplateName = p_oBuilder.getTemplate();
282 } else
283 {
284 a_sTemplateName = p_oBuilder.getErrorTemplate();
285 }
286
287
288 final InputStream a_oTemplateStream = this.getClass()
289 .getClassLoader().getResourceAsStream(a_sTemplateName);
290
291 Reader a_oTemplate = new InputStreamReader(a_oTemplateStream);
292
293
294 StringWriter a_oStringWriter = new StringWriter();
295
296
297 m_oVelocityEngine.evaluate(a_oContext, a_oStringWriter,
298 MULTIPLE_ACTION_PROCESSOR, a_oTemplate);
299
300
301 String a_sResults = a_oStringWriter.getBuffer().toString();
302
303
304 p_oInputMap.put(BUILD_RESULTS, a_sResults);
305 } else
306 {
307 log.error("could not create builder context");
308 }
309 } catch (Exception e)
310 {
311 log.error("builder failed", e);
312 p_oInputMap.put(Constants.REASON, e.toString());
313 }
314 }
315
316 public boolean buildContext(RequestContext p_oRequestContext,
317 Map p_oInputMap)
318 {
319 boolean a_bResults = true;
320
321 a_bResults = super.buildContext(p_oRequestContext, p_oInputMap);
322
323 return a_bResults;
324 }
325
326 }