1
22
23 package com.liferay.portal.action;
24
25 import com.liferay.portal.kernel.language.LanguageUtil;
26 import com.liferay.portal.kernel.portlet.PortletModeFactory;
27 import com.liferay.portal.kernel.portlet.WindowStateFactory;
28 import com.liferay.portal.kernel.servlet.BrowserSniffer;
29 import com.liferay.portal.kernel.servlet.HttpHeaders;
30 import com.liferay.portal.kernel.servlet.StringServletResponse;
31 import com.liferay.portal.kernel.util.ContentTypes;
32 import com.liferay.portal.kernel.util.HttpUtil;
33 import com.liferay.portal.kernel.util.JavaConstants;
34 import com.liferay.portal.kernel.util.ParamUtil;
35 import com.liferay.portal.kernel.util.StringPool;
36 import com.liferay.portal.kernel.util.Validator;
37 import com.liferay.portal.model.Layout;
38 import com.liferay.portal.model.LayoutTypePortlet;
39 import com.liferay.portal.model.Portlet;
40 import com.liferay.portal.model.PortletPreferencesIds;
41 import com.liferay.portal.model.User;
42 import com.liferay.portal.model.impl.LayoutImpl;
43 import com.liferay.portal.service.PortletLocalServiceUtil;
44 import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
45 import com.liferay.portal.struts.ActionConstants;
46 import com.liferay.portal.struts.StrutsUtil;
47 import com.liferay.portal.theme.ThemeDisplay;
48 import com.liferay.portal.util.PortalUtil;
49 import com.liferay.portal.util.PropsValues;
50 import com.liferay.portal.util.WebKeys;
51 import com.liferay.portlet.ActionRequestFactory;
52 import com.liferay.portlet.ActionRequestImpl;
53 import com.liferay.portlet.ActionResponseFactory;
54 import com.liferay.portlet.ActionResponseImpl;
55 import com.liferay.portlet.EventRequestFactory;
56 import com.liferay.portlet.EventRequestImpl;
57 import com.liferay.portlet.EventResponseFactory;
58 import com.liferay.portlet.EventResponseImpl;
59 import com.liferay.portlet.InvokerPortlet;
60 import com.liferay.portlet.PortletConfigFactory;
61 import com.liferay.portlet.PortletInstanceFactory;
62 import com.liferay.portlet.PortletPreferencesFactoryUtil;
63 import com.liferay.portlet.PortletRequestImpl;
64 import com.liferay.portlet.PortletURLImpl;
65 import com.liferay.portlet.RenderParametersPool;
66 import com.liferay.portlet.RenderRequestFactory;
67 import com.liferay.portlet.RenderRequestImpl;
68 import com.liferay.portlet.RenderResponseFactory;
69 import com.liferay.portlet.RenderResponseImpl;
70 import com.liferay.portlet.ResourceRequestFactory;
71 import com.liferay.portlet.ResourceRequestImpl;
72 import com.liferay.portlet.ResourceResponseFactory;
73 import com.liferay.portlet.ResourceResponseImpl;
74 import com.liferay.portlet.StateAwareResponseImpl;
75 import com.liferay.util.MapUtil;
76 import com.liferay.util.servlet.ServletResponseUtil;
77 import com.liferay.util.servlet.UploadServletRequest;
78
79 import java.io.ByteArrayInputStream;
80 import java.io.InputStream;
81
82 import java.util.HashMap;
83 import java.util.List;
84 import java.util.Map;
85
86 import javax.portlet.Event;
87 import javax.portlet.PortletConfig;
88 import javax.portlet.PortletContext;
89 import javax.portlet.PortletException;
90 import javax.portlet.PortletMode;
91 import javax.portlet.PortletPreferences;
92 import javax.portlet.PortletRequest;
93 import javax.portlet.PortletResponse;
94 import javax.portlet.PortletURL;
95 import javax.portlet.UnavailableException;
96 import javax.portlet.WindowState;
97
98 import javax.servlet.RequestDispatcher;
99 import javax.servlet.ServletContext;
100 import javax.servlet.http.HttpServletRequest;
101 import javax.servlet.http.HttpServletResponse;
102 import javax.servlet.http.HttpSession;
103 import javax.servlet.jsp.PageContext;
104
105 import javax.xml.namespace.QName;
106
107 import org.apache.commons.logging.Log;
108 import org.apache.commons.logging.LogFactory;
109 import org.apache.struts.action.Action;
110 import org.apache.struts.action.ActionForm;
111 import org.apache.struts.action.ActionForward;
112 import org.apache.struts.action.ActionMapping;
113
114
120 public class LayoutAction extends Action {
121
122 public ActionForward execute(
123 ActionMapping mapping, ActionForm form, HttpServletRequest req,
124 HttpServletResponse res)
125 throws Exception {
126
127 ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
128 WebKeys.THEME_DISPLAY);
129
130 Layout layout = themeDisplay.getLayout();
131
132 Boolean layoutDefault = (Boolean)req.getAttribute(
133 WebKeys.LAYOUT_DEFAULT);
134
135 if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
136 Layout requestedLayout =
137 (Layout)req.getAttribute(WebKeys.REQUESTED_LAYOUT);
138
139 if (requestedLayout != null) {
140 String redirectParam = "redirect";
141
142 String authLoginURL = PortalUtil.getCommunityLoginURL(
143 themeDisplay);
144
145 if (Validator.isNull(authLoginURL)) {
146 authLoginURL = PropsValues.AUTH_LOGIN_URL;
147 }
148
149 if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME) &&
150 Validator.isNotNull(authLoginURL)) {
151
152 redirectParam =
153 PortalUtil.getPortletNamespace(
154 PropsValues.AUTH_LOGIN_PORTLET_NAME) +
155 redirectParam;
156 }
157
158 String url = PortalUtil.getLayoutURL(
159 requestedLayout, themeDisplay);
160
161 String redirect = HttpUtil.addParameter(
162 themeDisplay.getURLSignIn(), redirectParam, url);
163
164 if (_log.isDebugEnabled()) {
165 _log.debug("Redirect requested layout to " + redirect);
166 }
167
168 res.sendRedirect(redirect);
169 }
170 else {
171 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
172
173 if (_log.isDebugEnabled()) {
174 _log.debug("Redirect default layout to " + redirect);
175 }
176
177 res.sendRedirect(redirect);
178 }
179
180 return null;
181 }
182
183 long plid = ParamUtil.getLong(req, "p_l_id");
184
185 if (plid > 0) {
186 return processLayout(mapping, req, res, plid);
187 }
188 else {
189 try {
190 forwardLayout(req);
191
192 return mapping.findForward(ActionConstants.COMMON_FORWARD);
193 }
194 catch (Exception e) {
195 req.setAttribute(PageContext.EXCEPTION, e);
196
197 return mapping.findForward(ActionConstants.COMMON_ERROR);
198 }
199 }
200 }
201
202 protected void forwardLayout(HttpServletRequest req) throws Exception {
203 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
204 long plid = LayoutImpl.DEFAULT_PLID;
205 String layoutFriendlyURL = null;
206
207 ThemeDisplay themeDisplay =
208 (ThemeDisplay)req.getAttribute(WebKeys.THEME_DISPLAY);
209
210 if (layout != null) {
211 plid = layout.getPlid();
212 layoutFriendlyURL =
213 PortalUtil.getLayoutFriendlyURL(layout, themeDisplay);
214 }
215
216 String forwardURL = layoutFriendlyURL;
217
218 if (Validator.isNull(forwardURL)) {
219 forwardURL =
220 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
221
222 if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
223 forwardURL = HttpUtil.addParameter(
224 forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
225 }
226 }
227
228 if (_log.isDebugEnabled()) {
229 _log.debug("Forward layout to " + forwardURL);
230 }
231
232 req.setAttribute(WebKeys.FORWARD_URL, forwardURL);
233 }
234
235 protected void includeLayoutContent(
236 HttpServletRequest req, HttpServletResponse res,
237 ThemeDisplay themeDisplay, Layout layout)
238 throws Exception {
239
240 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
241
242 String path = StrutsUtil.TEXT_HTML_DIR;
243
244 if (BrowserSniffer.is_wap_xhtml(req)) {
245 path = StrutsUtil.TEXT_WAP_DIR;
246 }
247
248
250 if (themeDisplay.isStateExclusive() ||
251 Validator.isNotNull(ParamUtil.getString(req, "p_p_id"))) {
252
253 path += "/portal/layout/view/portlet.jsp";
254 }
255 else {
256 path += PortalUtil.getLayoutViewPage(layout);
257 }
258
259 RequestDispatcher rd = ctx.getRequestDispatcher(path);
260
261 StringServletResponse stringServletRes = new StringServletResponse(res);
262
263 rd.include(req, stringServletRes);
264
265 req.setAttribute(WebKeys.LAYOUT_CONTENT, stringServletRes.getString());
266 }
267
268 protected void processEvent(
269 PortletRequestImpl portletReqImpl,
270 StateAwareResponseImpl stateAwareResImpl, Portlet portlet,
271 List<Portlet> portlets, Event event)
272 throws Exception {
273
274 HttpServletRequest req = portletReqImpl.getHttpServletRequest();
275 HttpServletResponse res = stateAwareResImpl.getHttpServletResponse();
276
277 String portletId = portlet.getPortletId();
278
279 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
280
281 InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
282 portlet, ctx);
283
284 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
285 PortletContext portletCtx = portletConfig.getPortletContext();
286
287 WindowState windowState = portletReqImpl.getWindowState();
288 PortletMode portletMode = portletReqImpl.getPortletMode();
289
290 User user = stateAwareResImpl.getUser();
291 Layout layout = stateAwareResImpl.getLayout();
292
293 PortletPreferences portletPreferences =
294 portletReqImpl.getPreferencesImpl();
295
296 EventRequestImpl eventReqImpl = EventRequestFactory.create(
297 req, portlet, invokerPortlet, portletCtx, windowState,
298 portletMode, portletPreferences, layout.getPlid());
299
300 eventReqImpl.setEvent(event);
301
302 EventResponseImpl eventResImpl = EventResponseFactory.create(
303 eventReqImpl, res, portletId, user, layout, windowState,
304 portletMode);
305
306 eventReqImpl.defineObjects(portletConfig, eventResImpl);
307
308 try {
309 try {
310 invokerPortlet.processEvent(eventReqImpl, eventResImpl);
311
312 if (eventResImpl.isCalledSetRenderParameter()) {
313 Map<String, String[]> renderParameterMap =
314 new HashMap<String, String[]>();
315
316 MapUtil.copy(
317 eventResImpl.getRenderParameterMap(),
318 renderParameterMap);
319
320 RenderParametersPool.put(
321 req, layout.getPlid(), portletId, renderParameterMap);
322 }
323 }
324 catch (UnavailableException ue) {
325 throw ue;
326 }
327 catch (PortletException pe) {
328 eventResImpl.setWindowState(windowState);
329 eventResImpl.setPortletMode(portletMode);
330 }
331
332 processEvents(eventReqImpl, eventResImpl, portlets);
333 }
334 finally {
335 EventRequestFactory.recycle(eventReqImpl);
336 EventResponseFactory.recycle(eventResImpl);
337 }
338 }
339
340 protected void processEvents(
341 PortletRequestImpl portletReqImpl,
342 StateAwareResponseImpl stateAwareResImpl, List<Portlet> portlets)
343 throws Exception {
344
345 List<Event> events = stateAwareResImpl.getEvents();
346
347 if (events.size() == 0) {
348 return;
349 }
350
351 for (Event event : events) {
352 QName qName = event.getQName();
353
354 for (Portlet portlet : portlets) {
355 QName processingQName = portlet.getProcessingEvent(
356 qName.getNamespaceURI(), qName.getLocalPart());
357
358 if (processingQName != null) {
359 processEvent(
360 portletReqImpl, stateAwareResImpl, portlet, portlets,
361 event);
362 }
363 }
364 }
365 }
366
367 protected ActionForward processLayout(
368 ActionMapping mapping, HttpServletRequest req,
369 HttpServletResponse res, long plid)
370 throws Exception {
371
372 ThemeDisplay themeDisplay = (ThemeDisplay)req.getAttribute(
373 WebKeys.THEME_DISPLAY);
374
375 try {
376 Layout layout = themeDisplay.getLayout();
377
378 boolean resetLayout = ParamUtil.getBoolean(
379 req, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
380
381 if (!PropsValues.TCK_URL && resetLayout) {
382 RenderParametersPool.clear(req, plid);
383 }
384
385 if (themeDisplay.isLifecycleAction()) {
386 Portlet portlet = processPortletRequest(
387 req, res, PortletRequest.ACTION_PHASE);
388
389 if (portlet != null) {
390 ActionResponseImpl actionResImpl =
391 (ActionResponseImpl)req.getAttribute(
392 JavaConstants.JAVAX_PORTLET_RESPONSE);
393
394 String redirectLocation =
395 actionResImpl.getRedirectLocation();
396
397 if (Validator.isNotNull(redirectLocation)) {
398 res.sendRedirect(redirectLocation);
399
400 return null;
401 }
402
403 if (portlet.isActionURLRedirect()) {
404 redirectActionURL(
405 req, res, actionResImpl, portlet);
406
407 return null;
408 }
409 }
410 }
411 else if (themeDisplay.isLifecycleRender()) {
412 processPortletRequest(req, res, PortletRequest.RENDER_PHASE);
413 }
414
415 if (themeDisplay.isLifecycleResource()) {
416 processPortletRequest(req, res, PortletRequest.RESOURCE_PHASE);
417
418 return null;
419 }
420 else {
421 if (layout != null) {
422
423
427 includeLayoutContent(req, res, themeDisplay, layout);
428
429 if (themeDisplay.isStateExclusive()) {
430 renderExclusive(req, res, themeDisplay);
431
432 return null;
433 }
434 }
435
436 return mapping.findForward("portal.layout");
437 }
438 }
439 catch (Exception e) {
440 req.setAttribute(PageContext.EXCEPTION, e);
441
442 return mapping.findForward(ActionConstants.COMMON_ERROR);
443 }
444 finally {
445 PortletRequest portletReq = (PortletRequest)req.getAttribute(
446 JavaConstants.JAVAX_PORTLET_REQUEST);
447
448 try {
449 if (portletReq != null) {
450 if (themeDisplay.isLifecycleAction()) {
451 ActionRequestImpl actionReqImpl =
452 (ActionRequestImpl)portletReq;
453
454 ActionRequestFactory.recycle(actionReqImpl);
455 }
456 else if (themeDisplay.isLifecycleRender()) {
457 RenderRequestImpl renderReqImpl =
458 (RenderRequestImpl)portletReq;
459
460 RenderRequestFactory.recycle(renderReqImpl);
461 }
462 else if (themeDisplay.isLifecycleResource()) {
463 ResourceRequestImpl resourceReqImpl =
464 (ResourceRequestImpl)portletReq;
465
466 ResourceRequestFactory.recycle(resourceReqImpl);
467 }
468 }
469 }
470 catch (Exception e) {
471 _log.error(e);
472 }
473
474 req.removeAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);
475
476 PortletResponse portletRes = (PortletResponse)req.getAttribute(
477 JavaConstants.JAVAX_PORTLET_RESPONSE);
478
479 try {
480 if (portletRes != null) {
481 if (themeDisplay.isLifecycleAction()) {
482 ActionResponseImpl actionResImpl =
483 (ActionResponseImpl)portletRes;
484
485 ActionResponseFactory.recycle(actionResImpl);
486 }
487 else if (themeDisplay.isLifecycleRender()) {
488 RenderResponseImpl renderResImpl =
489 (RenderResponseImpl)portletRes;
490
491 RenderResponseFactory.recycle(renderResImpl);
492 }
493 else if (themeDisplay.isLifecycleResource()) {
494 ResourceResponseImpl resourceResImpl =
495 (ResourceResponseImpl)portletRes;
496
497 ResourceResponseFactory.recycle(resourceResImpl);
498 }
499 }
500 }
501 catch (Exception e) {
502 _log.error(e);
503 }
504
505 req.removeAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);
506 }
507 }
508
509 protected Portlet processPortletRequest(
510 HttpServletRequest req, HttpServletResponse res, String lifecycle)
511 throws Exception {
512
513 HttpSession ses = req.getSession();
514
515 long companyId = PortalUtil.getCompanyId(req);
516 User user = PortalUtil.getUser(req);
517 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
518
519 String portletId = ParamUtil.getString(req, "p_p_id");
520
521 Portlet portlet = PortletLocalServiceUtil.getPortletById(
522 companyId, portletId);
523
524 if (portlet == null) {
525 return null;
526 }
527
528 ServletContext ctx = (ServletContext)req.getAttribute(WebKeys.CTX);
529
530 InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
531 portlet, ctx);
532
533 if (user != null) {
534 InvokerPortlet.clearResponse(
535 ses, layout.getPrimaryKey(), portletId,
536 LanguageUtil.getLanguageId(req));
537 }
538
539 PortletConfig portletConfig = PortletConfigFactory.create(portlet, ctx);
540 PortletContext portletCtx = portletConfig.getPortletContext();
541
542 WindowState windowState = WindowStateFactory.getWindowState(
543 ParamUtil.getString(req, "p_p_state"));
544
545 PortletMode portletMode = PortletModeFactory.getPortletMode(
546 ParamUtil.getString(req, "p_p_mode"));
547
548 PortletPreferencesIds portletPreferencesIds =
549 PortletPreferencesFactoryUtil.getPortletPreferencesIds(
550 req, portletId);
551
552 PortletPreferences portletPreferences =
553 PortletPreferencesLocalServiceUtil.getPreferences(
554 portletPreferencesIds);
555
556 if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
557 String contentType = req.getHeader(HttpHeaders.CONTENT_TYPE);
558
559 if (_log.isDebugEnabled()) {
560 _log.debug("Content type " + contentType);
561 }
562
563 UploadServletRequest uploadReq = null;
564
565 try {
566 if ((contentType != null) &&
567 (contentType.startsWith(
568 ContentTypes.MULTIPART_FORM_DATA))) {
569
570 if (!invokerPortlet.getPortletConfig().isWARFile() ||
571 invokerPortlet.isStrutsPortlet()) {
572
573 uploadReq = new UploadServletRequest(req);
574
575 req = uploadReq;
576 }
577 }
578
579 ActionRequestImpl actionReqImpl = ActionRequestFactory.create(
580 req, portlet, invokerPortlet, portletCtx, windowState,
581 portletMode, portletPreferences, layout.getPlid());
582
583 ActionResponseImpl actionResImpl = ActionResponseFactory.create(
584 actionReqImpl, res, portletId, user, layout, windowState,
585 portletMode);
586
587 actionReqImpl.defineObjects(portletConfig, actionResImpl);
588
589 invokerPortlet.processAction(actionReqImpl, actionResImpl);
590
591 RenderParametersPool.put(
592 req, layout.getPlid(), portletId,
593 actionResImpl.getRenderParameterMap());
594
595 if (actionResImpl.getEvents().size() > 0) {
596 if (layout.getType().equals(LayoutImpl.TYPE_PORTLET)) {
597 LayoutTypePortlet layoutTypePortlet =
598 (LayoutTypePortlet)layout.getLayoutType();
599
600 List<Portlet> portlets =
601 layoutTypePortlet.getPortlets();
602
603 processEvents(actionReqImpl, actionResImpl, portlets);
604
605 actionReqImpl.defineObjects(
606 portletConfig, actionResImpl);
607 }
608 }
609 }
610 finally {
611 if (uploadReq != null) {
612 uploadReq.cleanUp();
613 }
614 }
615 }
616 else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
617 lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
618
619 PortalUtil.updateWindowState(
620 portletId, user, layout, windowState, req);
621
622 PortalUtil.updatePortletMode(
623 portletId, user, layout, portletMode, req);
624 }
625
626 if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
627 ResourceRequestImpl resourceReqImpl =
628 ResourceRequestFactory.create(
629 req, portlet, invokerPortlet, portletCtx, windowState,
630 portletMode, portletPreferences, layout.getPlid());
631
632 StringServletResponse stringServletRes = new StringServletResponse(
633 res);
634
635 ResourceResponseImpl resourceResImpl =
636 ResourceResponseFactory.create(
637 resourceReqImpl, stringServletRes, portletId, companyId);
638
639 resourceReqImpl.defineObjects(portletConfig, resourceResImpl);
640
641 invokerPortlet.serveResource(resourceReqImpl, resourceResImpl);
642
643 if (stringServletRes.isCalledGetOutputStream()) {
644 InputStream is = new ByteArrayInputStream(
645 stringServletRes.getByteArrayMaker().toByteArray());
646
647 ServletResponseUtil.sendFile(
648 res, resourceReqImpl.getResourceID(), is,
649 resourceResImpl.getContentType());
650 }
651 else {
652 byte[] content = stringServletRes.getString().getBytes(
653 StringPool.UTF8);
654
655 ServletResponseUtil.sendFile(
656 res, resourceReqImpl.getResourceID(), content,
657 resourceResImpl.getContentType());
658 }
659 }
660
661 return portlet;
662 }
663
664 protected void redirectActionURL(
665 HttpServletRequest req, HttpServletResponse res,
666 ActionResponseImpl actionResImpl, Portlet portlet)
667 throws Exception {
668
669 ActionRequestImpl actionReqImpl = (ActionRequestImpl)req.getAttribute(
670 JavaConstants.JAVAX_PORTLET_REQUEST);
671
672 Layout layout = (Layout)req.getAttribute(WebKeys.LAYOUT);
673
674 PortletURL portletURL = new PortletURLImpl(
675 actionReqImpl, actionReqImpl.getPortletName(), layout.getLayoutId(),
676 PortletRequest.RENDER_PHASE);
677
678 Map<String, String[]> renderParameters =
679 actionResImpl.getRenderParameterMap();
680
681 for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
682 String key = entry.getKey();
683 String[] value = entry.getValue();
684
685 portletURL.setParameter(key, value);
686 }
687
688 res.sendRedirect(portletURL.toString());
689 }
690
691 protected void renderExclusive(
692 HttpServletRequest req, HttpServletResponse res,
693 ThemeDisplay themeDisplay)
694 throws Exception {
695
696 RenderRequestImpl renderReqImpl = (RenderRequestImpl)req.getAttribute(
697 JavaConstants.JAVAX_PORTLET_REQUEST);
698
699 RenderResponseImpl renderResImpl = (RenderResponseImpl)req.getAttribute(
700 JavaConstants.JAVAX_PORTLET_RESPONSE);
701
702 StringServletResponse stringServletRes =
703 (StringServletResponse)renderReqImpl.getAttribute(
704 WebKeys.STRING_SERVLET_RESPONSE);
705
706 renderResImpl.transferHeaders(res);
707
708 if (stringServletRes.isCalledGetOutputStream()) {
709 InputStream is = new ByteArrayInputStream(
710 stringServletRes.getByteArrayMaker().toByteArray());
711
712 ServletResponseUtil.sendFile(
713 res, renderResImpl.getResourceName(), is,
714 renderResImpl.getContentType());
715 }
716 else {
717 byte[] content = stringServletRes.getString().getBytes(
718 StringPool.UTF8);
719
720 ServletResponseUtil.sendFile(
721 res, renderResImpl.getResourceName(), content,
722 renderResImpl.getContentType());
723 }
724
725 RenderRequestFactory.recycle(renderReqImpl);
726 RenderResponseFactory.recycle(renderResImpl);
727 }
728
729 private static Log _log = LogFactory.getLog(LayoutAction.class);
730
731 }