1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.portals.bridges.struts;
17
18 import java.io.IOException;
19 import java.io.PrintWriter;
20
21 import javax.portlet.ActionRequest;
22 import javax.portlet.ActionResponse;
23 import javax.portlet.GenericPortlet;
24 import javax.portlet.PortletConfig;
25 import javax.portlet.PortletException;
26 import javax.portlet.PortletRequest;
27 import javax.portlet.PortletResponse;
28 import javax.portlet.RenderRequest;
29 import javax.portlet.RenderResponse;
30 import javax.servlet.RequestDispatcher;
31 import javax.servlet.ServletContext;
32 import javax.servlet.ServletException;
33 import javax.servlet.http.HttpServletRequest;
34 import javax.servlet.http.HttpServletResponse;
35 import javax.servlet.http.HttpSession;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.portals.bridges.common.ServletContextProvider;
40 import org.apache.portals.bridges.struts.config.StrutsPortletConfig;
41 import org.apache.portals.bridges.struts.util.EmptyHttpServletResponseWrapper;
42
43 /***
44 * StrutsPortlet
45 *
46 * @author <a href="mailto:ate@douma.nu">Ate Douma</a>
47 * @version $Id: StrutsPortlet.java 306954 2005-10-07 01:14:47 +0200 (Fri, 07 Oct 2005) ate $
48 */
49 public class StrutsPortlet extends GenericPortlet
50 {
51 /***
52 * Name of class implementing {@link ServletContextProvider}
53 */
54 public static final String PARAM_SERVLET_CONTEXT_PROVIDER = "ServletContextProvider";
55 /***
56 * Name of portlet preference for Struts Portlet Config Location
57 */
58 public static final String STRUTS_PORTLET_CONFIG_LOCATION = "StrutsPortletConfigLocation";
59 /***
60 * Name of portlet preference for Action page
61 */
62 public static final String PARAM_ACTION_PAGE = "ActionPage";
63 /***
64 * Name of portlet preference for Custom page
65 */
66 public static final String PARAM_CUSTOM_PAGE = "CustomPage";
67 /***
68 * Name of portlet preference for Edit page
69 */
70 public static final String PARAM_EDIT_PAGE = "EditPage";
71 /***
72 * Name of portlet preference for Edit page
73 */
74 public static final String PARAM_HELP_PAGE = "HelpPage";
75 /***
76 * Name of portlet preference for View page
77 */
78 public static final String PARAM_VIEW_PAGE = "ViewPage";
79 /***
80 * Default URL for the action page.
81 */
82 private String defaultActionPage = null;
83 /***
84 * Default URL for the custom page.
85 */
86 private String defaultCustomPage = null;
87 /***
88 * Default URL for the edit page.
89 */
90 private String defaultEditPage = null;
91 /***
92 * Default URL for the help page.
93 */
94 private String defaultHelpPage = null;
95 /***
96 * Default URL for the view page.
97 */
98 private String defaultViewPage = null;
99 private ServletContextProvider servletContextProvider;
100 private static final Log log = LogFactory.getLog(StrutsPortlet.class);
101 public static final String REQUEST_TYPE = "org.apache.portals.bridges.struts.request_type";
102 public static final String PAGE_URL = "org.apache.portals.bridges.struts.page_url";
103 public static final String ORIGIN_URL = "org.apache.portals.bridges.struts.origin_url";
104 public static final String REDIRECT_PAGE_URL = "org.apache.portals.bridges.struts.redirect_page_url";
105 public static final String REDIRECT_URL = "org.apache.portals.bridges.struts.redirect_url";
106 public static final String RENDER_CONTEXT = "org.apache.portals.bridges.struts.render_context";
107 public static final String ERROR_CONTEXT = "org.apache.portals.bridges.struts.error_context";
108 public static final String PORTLET_NAME = "org.apache.portals.bridges.struts.portlet_name";
109 public static final String STRUTS_PORTLET_CONFIG = "org.apache.portals.bridges.struts.portlet_config";
110 public static final String DEFAULT_STRUTS_PORTLET_CONFIG_LOCATION = "WEB-INF/struts-portlet-config.xml";
111 public static final String ACTION_REQUEST = "ACTION";
112 public static final String VIEW_REQUEST = "VIEW";
113 public static final String CUSTOM_REQUEST = "CUSTOM";
114 public static final String EDIT_REQUEST = "EDIT";
115 public static final String HELP_REQUEST = "HELP";
116
117 private StrutsPortletConfig strutsPortletConfig;
118
119 public void init(PortletConfig config) throws PortletException
120 {
121 super.init(config);
122 String contextProviderClassName = getContextProviderClassNameParameter(config);
123 if (contextProviderClassName == null)
124 throw new PortletException("Portlet " + config.getPortletName()
125 + " is incorrectly configured. Init parameter "
126 + PARAM_SERVLET_CONTEXT_PROVIDER + " not specified");
127 if (contextProviderClassName != null)
128 {
129 try
130 {
131 Class clazz = Class.forName(contextProviderClassName);
132 if (clazz != null)
133 {
134 Object obj = clazz.newInstance();
135 if (ServletContextProvider.class.isInstance(obj))
136 {
137 servletContextProvider = (ServletContextProvider) obj;
138 }
139 else
140 throw new PortletException("class not found");
141 }
142 } catch (Exception e)
143 {
144 if (e instanceof PortletException)
145 throw (PortletException) e;
146 e.printStackTrace();
147 throw new PortletException("Cannot load", e);
148 }
149 }
150 if (servletContextProvider == null)
151 throw new PortletException("Portlet " + config.getPortletName()
152 + " is incorrectly configured. Invalid init parameter "
153 + PARAM_SERVLET_CONTEXT_PROVIDER + " value "
154 + contextProviderClassName);
155 this.defaultActionPage = getActionPageParameter(config);
156 this.defaultCustomPage = getCustomPageParameter(config);
157 this.defaultEditPage = getEditPageParameter(config);
158 this.defaultViewPage = getViewPageParameter(config);
159 this.defaultHelpPage = getHelpPageParameter(config);
160
161 if (this.defaultViewPage == null)
162 {
163
164
165
166 throw new PortletException(
167 "Portlet "
168 + config.getPortletName()
169 + " is incorrectly configured. No default View page is defined.");
170 }
171 if (defaultActionPage == null)
172 defaultActionPage = defaultViewPage;
173 if (defaultCustomPage == null)
174 defaultCustomPage = defaultViewPage;
175 if (defaultHelpPage == null)
176 defaultHelpPage = defaultViewPage;
177 if (defaultEditPage == null)
178 defaultEditPage = defaultViewPage;
179
180 strutsPortletConfig = new StrutsPortletConfig();
181 String strutsPortletConfigLocation = getStrutsPortletConfigLocationParameter(config);
182 if ( strutsPortletConfigLocation == null )
183 {
184 strutsPortletConfigLocation = DEFAULT_STRUTS_PORTLET_CONFIG_LOCATION;
185 }
186 strutsPortletConfig.loadConfig(config.getPortletContext(),strutsPortletConfigLocation);
187 config.getPortletContext().setAttribute(STRUTS_PORTLET_CONFIG,strutsPortletConfig);
188 }
189
190 protected String getContextProviderClassNameParameter(PortletConfig config)
191 {
192 return config.getInitParameter(PARAM_SERVLET_CONTEXT_PROVIDER);
193 }
194
195 protected ServletContextProvider getServletContextProvider()
196 {
197 return servletContextProvider;
198 }
199
200 protected ServletContext getServletContext(GenericPortlet portlet, PortletRequest request, PortletResponse response)
201 {
202 return getServletContextProvider().getServletContext(portlet);
203 }
204
205 protected HttpServletRequest getHttpServletRequest(GenericPortlet portlet, PortletRequest request, PortletResponse response)
206 {
207 return getServletContextProvider().getHttpServletRequest(portlet, request);
208 }
209
210 protected HttpServletResponse getHttpServletResponse(GenericPortlet portlet, PortletRequest request, PortletResponse response)
211 {
212 return getServletContextProvider().getHttpServletResponse(portlet, response);
213 }
214
215 protected String getStrutsPageURL(PortletRequest request)
216 {
217 return request.getParameter(StrutsPortletURL.PAGE);
218 }
219
220 protected String getStrutsOriginURL(PortletRequest request)
221 {
222 return request.getParameter(StrutsPortletURL.ORIGIN);
223 }
224
225 protected String getActionPageParameter(PortletConfig config)
226 {
227 return config.getInitParameter(PARAM_ACTION_PAGE);
228 }
229
230 protected String getCustomPageParameter(PortletConfig config)
231 {
232 return config.getInitParameter(PARAM_CUSTOM_PAGE);
233 }
234
235 protected String getEditPageParameter(PortletConfig config)
236 {
237 return config.getInitParameter(PARAM_EDIT_PAGE);
238 }
239
240 protected String getViewPageParameter(PortletConfig config)
241 {
242 return config.getInitParameter(PARAM_VIEW_PAGE);
243 }
244
245 protected String getHelpPageParameter(PortletConfig config)
246 {
247 return config.getInitParameter(PARAM_HELP_PAGE);
248 }
249
250 protected String getStrutsPortletConfigLocationParameter(PortletConfig config)
251 {
252 return config.getInitParameter(STRUTS_PORTLET_CONFIG_LOCATION);
253 }
254
255 public void doEdit(RenderRequest request, RenderResponse response)
256 throws PortletException, IOException
257 {
258 processRequest(request, response, defaultEditPage, StrutsPortlet.EDIT_REQUEST);
259 }
260 public void doHelp(RenderRequest request, RenderResponse response)
261 throws PortletException, IOException
262 {
263 processRequest(request, response, defaultHelpPage, StrutsPortlet.HELP_REQUEST);
264 }
265 public void doCustom(RenderRequest request, RenderResponse response)
266 throws PortletException, IOException
267 {
268 processRequest(request, response, defaultCustomPage,
269 StrutsPortlet.CUSTOM_REQUEST);
270 }
271 public void doView(RenderRequest request, RenderResponse response)
272 throws PortletException, IOException
273 {
274 processRequest(request, response, defaultViewPage, StrutsPortlet.VIEW_REQUEST);
275 }
276 public void processAction(ActionRequest request, ActionResponse response)
277 throws PortletException, IOException
278 {
279 processRequest(request, response, defaultActionPage,
280 StrutsPortlet.ACTION_REQUEST);
281 }
282 protected void processRequest(PortletRequest request, PortletResponse response,
283 String defaultPage, String requestType) throws PortletException,
284 IOException
285 {
286 ServletContext servletContext = getServletContext(this, request, response);
287 HttpServletRequest req = getHttpServletRequest(this, request, response);
288 HttpServletResponse res = getHttpServletResponse(this, request, response);
289 HttpSession session = req.getSession();
290 String portletName = this.getPortletConfig().getPortletName();
291 req.setAttribute(PORTLET_NAME, portletName);
292 boolean actionRequest = (request instanceof ActionRequest);
293
294 try
295 {
296 StrutsPortletErrorContext errorContext = (StrutsPortletErrorContext) req
297 .getSession().getAttribute(StrutsPortlet.ERROR_CONTEXT + "_" + portletName);
298 if (errorContext != null)
299 {
300 if (!actionRequest)
301 {
302 req.getSession().removeAttribute(
303 StrutsPortlet.ERROR_CONTEXT + "_" + portletName);
304 renderError(res, errorContext);
305 }
306 return;
307 }
308
309 String keepRenderAttributes = null;
310
311 if ( !actionRequest )
312 {
313 keepRenderAttributes = request.getParameter(StrutsPortletURL.KEEP_RENDER_ATTRIBUTES);
314 }
315 if ( keepRenderAttributes == null )
316 {
317 strutsPortletConfig.getRenderContextAttributes().clearAttributes(session);
318 }
319 else
320 {
321 strutsPortletConfig.getRenderContextAttributes().restoreAttributes(req);
322 }
323
324 String path = null;
325 String pageURL = getStrutsPageURL(request);
326 if (pageURL == null)
327 path = defaultPage;
328 else
329 {
330 path = pageURL;
331 }
332
333 if (log.isDebugEnabled())
334 log.debug("process path: " + path + ", requestType: " + requestType);
335
336 RequestDispatcher rd = servletContext.getRequestDispatcher(path);
337 if (rd != null)
338 {
339 if (actionRequest)
340 {
341 res = new EmptyHttpServletResponseWrapper(res);
342
343
344
345
346
347
348 if ( req.getAttribute("javax.portlet.config") == null )
349 {
350 req.setAttribute("javax.portlet.config", getPortletConfig());
351 }
352 if ( req.getAttribute("javax.portlet.request") == null )
353 {
354 req.setAttribute("javax.portlet.request", request);
355 }
356 if ( req.getAttribute("javax.portlet.response") == null )
357 {
358 req.setAttribute("javax.portlet.response", response);
359 }
360 String origin = getStrutsOriginURL(request);
361 if ( origin == null )
362 {
363 origin = defaultPage;
364 }
365 request.setAttribute(StrutsPortlet.ORIGIN_URL, origin);
366 }
367 if (path != null)
368 {
369 req.setAttribute(StrutsPortlet.PAGE_URL, path);
370 }
371
372 req.setAttribute(StrutsPortlet.REQUEST_TYPE, requestType);
373 try
374 {
375 rd.include(new PortletServletRequestWrapper(servletContext, req), res);
376 }
377 catch (ServletException e)
378 {
379 if (log.isErrorEnabled())
380 log.error("Include exception", e);
381 errorContext = new StrutsPortletErrorContext();
382 errorContext.setError(e);
383 req.setAttribute(StrutsPortlet.ERROR_CONTEXT, errorContext);
384 if (!actionRequest)
385 renderError(res, errorContext);
386 }
387 if (actionRequest)
388 {
389 String renderURL;
390 if (req.getAttribute(StrutsPortlet.ERROR_CONTEXT) != null)
391 {
392 pageURL = StrutsPortletURL.getOriginURL(req);
393 if ( pageURL != null )
394 {
395 ((ActionResponse) response).setRenderParameter(StrutsPortletURL.PAGE, pageURL);
396 }
397 if (log.isDebugEnabled())
398 log.debug("action render error context");
399 try
400 {
401 req.getSession(true).setAttribute(
402 StrutsPortlet.ERROR_CONTEXT + "_" + portletName,
403 req.getAttribute(StrutsPortlet.ERROR_CONTEXT));
404 }
405 catch (IllegalStateException ise)
406 {
407
408
409
410 }
411 }
412 else
413 {
414 if ((renderURL = (String) req
415 .getAttribute(StrutsPortlet.REDIRECT_URL)) != null)
416 {
417 if (log.isDebugEnabled())
418 log.debug("action send redirect: " + renderURL);
419 ((ActionResponse) response).sendRedirect(renderURL);
420 }
421 else
422 {
423 strutsPortletConfig.getRenderContextAttributes().saveAttributes(req);
424 ((ActionResponse) response).setRenderParameter(
425 StrutsPortletURL.KEEP_RENDER_ATTRIBUTES, "1");
426
427 if ((renderURL = (String) req
428 .getAttribute(StrutsPortlet.REDIRECT_PAGE_URL)) != null)
429 {
430 if (log.isDebugEnabled())
431 log.debug("action render redirected page: "
432 + renderURL);
433 pageURL = renderURL;
434 }
435 if (pageURL != null)
436 {
437 if (renderURL == null && log.isWarnEnabled())
438 log.warn("Warning: Using the original action URL for render URL: " +pageURL+".\nA redirect should have been issued.");
439 ((ActionResponse) response).setRenderParameter(
440 StrutsPortletURL.PAGE, pageURL);
441 }
442 }
443 }
444 }
445 }
446 } catch (IOException e)
447 {
448 if (log.isErrorEnabled())
449 log.error("unexpected", e);
450 throw e;
451 }
452 }
453 protected void renderError(HttpServletResponse response,
454 StrutsPortletErrorContext errorContext) throws IOException
455 {
456 PrintWriter writer = response.getWriter();
457 writer.println("<hr/><h2>Error</h2>");
458 writer.println("<table border='1'>");
459 if (errorContext.getErrorCode() != 0)
460 writer.println("<tr><td valign='top'><b>Error Code</b></td><td>"
461 + errorContext.getErrorCode() + "</td></tr>");
462 if (errorContext.getErrorMessage() != null)
463 writer.println("<tr><td valign='top'><b>Error Message</b></td><td>"
464 + errorContext.getErrorMessage() + "</td></tr>");
465 if (errorContext.getError() != null)
466 {
467 Throwable e = errorContext.getError();
468 if (e instanceof ServletException
469 && ((ServletException) e).getRootCause() != null)
470 e = ((ServletException) e).getRootCause();
471 writer.print("<tr><td valign='top'><b>Error</b></td><td>"
472 + e.getMessage() + "</td></tr>");
473 writer.print("<tr><td valign='top'><b>Error Type</b></td><td>"
474 + e.getClass().getName() + "</td></tr>");
475 writer.print("<tr><td valign='top'><b>Stacktrace</b></td><td>");
476 StackTraceElement[] elements = e.getStackTrace();
477 StringBuffer buf = new StringBuffer();
478 for (int i = 0; i < elements.length; i++)
479 buf.append(" " + elements[i].toString() + "<br>");
480 writer.print(buf.toString());
481 writer.println("</td></tr>");
482 }
483 writer.println("</table>");
484 }
485 }