1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portal.action;
24  
25  import com.liferay.portal.kernel.language.LanguageUtil;
26  import com.liferay.portal.kernel.log.Log;
27  import com.liferay.portal.kernel.log.LogFactoryUtil;
28  import com.liferay.portal.kernel.portlet.PortletModeFactory;
29  import com.liferay.portal.kernel.portlet.WindowStateFactory;
30  import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
31  import com.liferay.portal.kernel.servlet.HttpHeaders;
32  import com.liferay.portal.kernel.servlet.StringServletResponse;
33  import com.liferay.portal.kernel.upload.UploadServletRequest;
34  import com.liferay.portal.kernel.util.ContentTypes;
35  import com.liferay.portal.kernel.util.HttpUtil;
36  import com.liferay.portal.kernel.util.JavaConstants;
37  import com.liferay.portal.kernel.util.MapUtil;
38  import com.liferay.portal.kernel.util.ParamUtil;
39  import com.liferay.portal.kernel.util.StringPool;
40  import com.liferay.portal.kernel.util.Validator;
41  import com.liferay.portal.model.Layout;
42  import com.liferay.portal.model.LayoutConstants;
43  import com.liferay.portal.model.LayoutTypePortlet;
44  import com.liferay.portal.model.Portlet;
45  import com.liferay.portal.model.PortletPreferencesIds;
46  import com.liferay.portal.model.User;
47  import com.liferay.portal.service.PortletLocalServiceUtil;
48  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
49  import com.liferay.portal.service.permission.PortletPermissionUtil;
50  import com.liferay.portal.struts.ActionConstants;
51  import com.liferay.portal.struts.StrutsUtil;
52  import com.liferay.portal.theme.PortletDisplay;
53  import com.liferay.portal.theme.ThemeDisplay;
54  import com.liferay.portal.upload.UploadServletRequestImpl;
55  import com.liferay.portal.util.PortalUtil;
56  import com.liferay.portal.util.PropsValues;
57  import com.liferay.portal.util.WebKeys;
58  import com.liferay.portlet.ActionRequestFactory;
59  import com.liferay.portlet.ActionRequestImpl;
60  import com.liferay.portlet.ActionResponseFactory;
61  import com.liferay.portlet.ActionResponseImpl;
62  import com.liferay.portlet.EventRequestFactory;
63  import com.liferay.portlet.EventRequestImpl;
64  import com.liferay.portlet.EventResponseFactory;
65  import com.liferay.portlet.EventResponseImpl;
66  import com.liferay.portlet.InvokerPortlet;
67  import com.liferay.portlet.InvokerPortletImpl;
68  import com.liferay.portlet.PortletConfigFactory;
69  import com.liferay.portlet.PortletConfigImpl;
70  import com.liferay.portlet.PortletInstanceFactory;
71  import com.liferay.portlet.PortletPreferencesFactoryUtil;
72  import com.liferay.portlet.PortletRequestImpl;
73  import com.liferay.portlet.PortletURLImpl;
74  import com.liferay.portlet.RenderParametersPool;
75  import com.liferay.portlet.RenderRequestFactory;
76  import com.liferay.portlet.RenderRequestImpl;
77  import com.liferay.portlet.RenderResponseFactory;
78  import com.liferay.portlet.RenderResponseImpl;
79  import com.liferay.portlet.ResourceRequestFactory;
80  import com.liferay.portlet.ResourceRequestImpl;
81  import com.liferay.portlet.ResourceResponseFactory;
82  import com.liferay.portlet.ResourceResponseImpl;
83  import com.liferay.portlet.StateAwareResponseImpl;
84  import com.liferay.util.servlet.ServletResponseUtil;
85  
86  import java.io.ByteArrayInputStream;
87  import java.io.InputStream;
88  
89  import java.util.HashMap;
90  import java.util.List;
91  import java.util.Map;
92  
93  import javax.portlet.Event;
94  import javax.portlet.PortletConfig;
95  import javax.portlet.PortletContext;
96  import javax.portlet.PortletException;
97  import javax.portlet.PortletMode;
98  import javax.portlet.PortletPreferences;
99  import javax.portlet.PortletRequest;
100 import javax.portlet.PortletResponse;
101 import javax.portlet.PortletURL;
102 import javax.portlet.UnavailableException;
103 import javax.portlet.WindowState;
104 
105 import javax.servlet.RequestDispatcher;
106 import javax.servlet.ServletContext;
107 import javax.servlet.http.HttpServletRequest;
108 import javax.servlet.http.HttpServletResponse;
109 import javax.servlet.http.HttpSession;
110 
111 import javax.xml.namespace.QName;
112 
113 import org.apache.struts.action.Action;
114 import org.apache.struts.action.ActionForm;
115 import org.apache.struts.action.ActionForward;
116 import org.apache.struts.action.ActionMapping;
117 
118 /**
119  * <a href="LayoutAction.java.html"><b><i>View Source</i></b></a>
120  *
121  * @author Brian Wing Shun Chan
122  *
123  */
124 public class LayoutAction extends Action {
125 
126     public ActionForward execute(
127             ActionMapping mapping, ActionForm form, HttpServletRequest request,
128             HttpServletResponse response)
129         throws Exception {
130 
131         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
132             WebKeys.THEME_DISPLAY);
133 
134         Layout layout = themeDisplay.getLayout();
135 
136         Boolean layoutDefault = (Boolean)request.getAttribute(
137             WebKeys.LAYOUT_DEFAULT);
138 
139         if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
140             Layout requestedLayout =
141                 (Layout)request.getAttribute(WebKeys.REQUESTED_LAYOUT);
142 
143             if (requestedLayout != null) {
144                 String redirectParam = "redirect";
145 
146                 String authLoginURL = PortalUtil.getCommunityLoginURL(
147                     themeDisplay);
148 
149                 if (Validator.isNull(authLoginURL)) {
150                     authLoginURL = PropsValues.AUTH_LOGIN_URL;
151                 }
152 
153                 if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME) &&
154                     Validator.isNotNull(authLoginURL)) {
155 
156                     redirectParam =
157                         PortalUtil.getPortletNamespace(
158                             PropsValues.AUTH_LOGIN_PORTLET_NAME) +
159                         redirectParam;
160                 }
161 
162                 String url = PortalUtil.getLayoutURL(
163                     requestedLayout, themeDisplay);
164 
165                 String redirect = HttpUtil.addParameter(
166                     themeDisplay.getURLSignIn(), redirectParam, url);
167 
168                 if (_log.isDebugEnabled()) {
169                     _log.debug("Redirect requested layout to " + redirect);
170                 }
171 
172                 response.sendRedirect(redirect);
173             }
174             else {
175                 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
176 
177                 if (_log.isDebugEnabled()) {
178                     _log.debug("Redirect default layout to " + redirect);
179                 }
180 
181                 response.sendRedirect(redirect);
182             }
183 
184             return null;
185         }
186 
187         long plid = ParamUtil.getLong(request, "p_l_id");
188 
189         if (_log.isDebugEnabled()) {
190             _log.debug("p_l_id is " + plid);
191         }
192 
193         if (plid > 0) {
194             return processLayout(mapping, request, response, plid);
195         }
196         else {
197             try {
198                 forwardLayout(request);
199 
200                 return mapping.findForward(ActionConstants.COMMON_FORWARD_JSP);
201             }
202             catch (Exception e) {
203                 PortalUtil.sendError(e, request, response);
204 
205                 return null;
206             }
207         }
208     }
209 
210     protected void forwardLayout(HttpServletRequest request) throws Exception {
211         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
212 
213         long plid = LayoutConstants.DEFAULT_PLID;
214 
215         String layoutFriendlyURL = null;
216 
217         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
218             WebKeys.THEME_DISPLAY);
219 
220         if (layout != null) {
221             plid = layout.getPlid();
222 
223             layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
224                 layout, themeDisplay);
225         }
226 
227         String forwardURL = layoutFriendlyURL;
228 
229         if (Validator.isNull(forwardURL)) {
230             forwardURL =
231                 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
232 
233             if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
234                 forwardURL = HttpUtil.addParameter(
235                     forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
236             }
237         }
238 
239         if (_log.isDebugEnabled()) {
240             _log.debug("Forward layout to " + forwardURL);
241         }
242 
243         request.setAttribute(WebKeys.FORWARD_URL, forwardURL);
244     }
245 
246     protected void includeLayoutContent(
247             HttpServletRequest request, HttpServletResponse response,
248             ThemeDisplay themeDisplay, Layout layout)
249         throws Exception {
250 
251         ServletContext servletContext = (ServletContext)request.getAttribute(
252             WebKeys.CTX);
253 
254         String path = StrutsUtil.TEXT_HTML_DIR;
255 
256         if (BrowserSnifferUtil.isWap(request)) {
257             path = StrutsUtil.TEXT_WAP_DIR;
258         }
259 
260         // Manually check the p_p_id. See LEP-1724.
261 
262         if (themeDisplay.isStateExclusive() ||
263             Validator.isNotNull(ParamUtil.getString(request, "p_p_id"))) {
264 
265             if (layout.getType().equals(LayoutConstants.TYPE_PANEL)) {
266                 path += "/portal/layout/view/panel.jsp";
267             }
268             else {
269                 path += "/portal/layout/view/portlet.jsp";
270             }
271         }
272         else {
273             path += PortalUtil.getLayoutViewPage(layout);
274         }
275 
276         RequestDispatcher requestDispatcher =
277             servletContext.getRequestDispatcher(path);
278 
279         StringServletResponse stringResponse = new StringServletResponse(
280             response);
281 
282         requestDispatcher.include(request, stringResponse);
283 
284         request.setAttribute(
285             WebKeys.LAYOUT_CONTENT, stringResponse.getString());
286     }
287 
288     protected void processEvent(
289             PortletRequestImpl portletRequestImpl,
290             StateAwareResponseImpl stateAwareResponseImpl, Portlet portlet,
291             List<Portlet> portlets, Event event)
292         throws Exception {
293 
294         HttpServletRequest request = portletRequestImpl.getHttpServletRequest();
295         HttpServletResponse response =
296             stateAwareResponseImpl.getHttpServletResponse();
297         HttpSession session = request.getSession();
298 
299         String portletId = portlet.getPortletId();
300 
301         ServletContext servletContext =
302             (ServletContext)request.getAttribute(WebKeys.CTX);
303 
304         InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
305             portlet, servletContext);
306 
307         PortletConfig portletConfig = PortletConfigFactory.create(
308             portlet, servletContext);
309         PortletContext portletContext = portletConfig.getPortletContext();
310 
311         WindowState windowState = portletRequestImpl.getWindowState();
312         PortletMode portletMode = portletRequestImpl.getPortletMode();
313 
314         User user = stateAwareResponseImpl.getUser();
315         Layout layout = stateAwareResponseImpl.getLayout();
316 
317         PortletPreferences portletPreferences =
318             portletRequestImpl.getPreferencesImpl();
319 
320         EventRequestImpl eventRequestImpl = EventRequestFactory.create(
321             request, portlet, invokerPortlet, portletContext, windowState,
322             portletMode, portletPreferences, layout.getPlid());
323 
324         eventRequestImpl.setEvent(event);
325 
326         EventResponseImpl eventResponseImpl = EventResponseFactory.create(
327             eventRequestImpl, response, portletId, user, layout, windowState,
328             portletMode);
329 
330         eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
331 
332         try {
333             try {
334                 InvokerPortletImpl.clearResponse(
335                     session, layout.getPrimaryKey(), portletId,
336                     LanguageUtil.getLanguageId(eventRequestImpl));
337 
338                 invokerPortlet.processEvent(
339                     eventRequestImpl, eventResponseImpl);
340 
341                 if (eventResponseImpl.isCalledSetRenderParameter()) {
342                     Map<String, String[]> renderParameterMap =
343                         new HashMap<String, String[]>();
344 
345                     MapUtil.copy(
346                         eventResponseImpl.getRenderParameterMap(),
347                         renderParameterMap);
348 
349                     RenderParametersPool.put(
350                         request, layout.getPlid(), portletId,
351                         renderParameterMap);
352                 }
353             }
354             catch (UnavailableException ue) {
355                 throw ue;
356             }
357             catch (PortletException pe) {
358                 eventResponseImpl.setWindowState(windowState);
359                 eventResponseImpl.setPortletMode(portletMode);
360             }
361 
362             processEvents(eventRequestImpl, eventResponseImpl, portlets);
363         }
364         finally {
365             EventRequestFactory.recycle(eventRequestImpl);
366             EventResponseFactory.recycle(eventResponseImpl);
367         }
368     }
369 
370     protected void processEvents(
371             PortletRequestImpl portletRequestImpl,
372             StateAwareResponseImpl stateAwareResponseImpl,
373             List<Portlet> portlets)
374         throws Exception {
375 
376         List<Event> events = stateAwareResponseImpl.getEvents();
377 
378         if (events.size() == 0) {
379             return;
380         }
381 
382         for (Event event : events) {
383             QName qName = event.getQName();
384 
385             for (Portlet portlet : portlets) {
386                 QName processingQName = portlet.getProcessingEvent(
387                     qName.getNamespaceURI(), qName.getLocalPart());
388 
389                 if (processingQName != null) {
390                     processEvent(
391                         portletRequestImpl, stateAwareResponseImpl, portlet,
392                         portlets, event);
393                 }
394             }
395         }
396     }
397 
398     protected ActionForward processLayout(
399             ActionMapping mapping, HttpServletRequest request,
400             HttpServletResponse response, long plid)
401         throws Exception {
402 
403         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
404             WebKeys.THEME_DISPLAY);
405 
406         try {
407             Layout layout = themeDisplay.getLayout();
408 
409             boolean resetLayout = ParamUtil.getBoolean(
410                 request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
411 
412             if (!PropsValues.TCK_URL && resetLayout) {
413                 RenderParametersPool.clear(request, plid);
414             }
415 
416             if (themeDisplay.isLifecycleAction()) {
417                 Portlet portlet = processPortletRequest(
418                     request, response, PortletRequest.ACTION_PHASE);
419 
420                 if (portlet != null) {
421                     ActionResponseImpl actionResponseImpl =
422                         (ActionResponseImpl)request.getAttribute(
423                             JavaConstants.JAVAX_PORTLET_RESPONSE);
424 
425                     String redirectLocation =
426                         actionResponseImpl.getRedirectLocation();
427 
428                     if (Validator.isNotNull(redirectLocation)) {
429                         response.sendRedirect(redirectLocation);
430 
431                         return null;
432                     }
433 
434                     if (portlet.isActionURLRedirect()) {
435                         redirectActionURL(
436                             request, response, actionResponseImpl, portlet);
437 
438                         return null;
439                     }
440                 }
441             }
442             else if (themeDisplay.isLifecycleRender()) {
443                 processPortletRequest(
444                     request, response, PortletRequest.RENDER_PHASE);
445             }
446 
447             if (themeDisplay.isLifecycleResource()) {
448                 processPortletRequest(
449                     request, response, PortletRequest.RESOURCE_PHASE);
450 
451                 return null;
452             }
453             else {
454                 if (layout != null) {
455 
456                     // Include layout content before the page loads because
457                     // portlets on the page can set the page title and page
458                     // subtitle
459 
460                     includeLayoutContent(
461                         request, response, themeDisplay, layout);
462 
463                     if (themeDisplay.isStateExclusive()) {
464                         renderExclusive(request, response, themeDisplay);
465 
466                         return null;
467                     }
468                 }
469 
470                 return mapping.findForward("portal.layout");
471             }
472         }
473         catch (Exception e) {
474             PortalUtil.sendError(e, request, response);
475 
476             return null;
477         }
478         finally {
479             PortletRequest portletRequest =
480                 (PortletRequest)request.getAttribute(
481                     JavaConstants.JAVAX_PORTLET_REQUEST);
482 
483             try {
484                 if (portletRequest != null) {
485                     if (themeDisplay.isLifecycleAction()) {
486                         ActionRequestImpl actionRequestImpl =
487                             (ActionRequestImpl)portletRequest;
488 
489                         ActionRequestFactory.recycle(actionRequestImpl);
490                     }
491                     else if (themeDisplay.isLifecycleRender()) {
492                         RenderRequestImpl renderRequestImpl =
493                             (RenderRequestImpl)portletRequest;
494 
495                         RenderRequestFactory.recycle(renderRequestImpl);
496                     }
497                     else if (themeDisplay.isLifecycleResource()) {
498                         ResourceRequestImpl resourceRequestImpl =
499                             (ResourceRequestImpl)portletRequest;
500 
501                         ResourceRequestFactory.recycle(resourceRequestImpl);
502                     }
503                 }
504             }
505             catch (Exception e) {
506                 _log.error(e);
507             }
508 
509             request.removeAttribute(JavaConstants.JAVAX_PORTLET_REQUEST);
510 
511             PortletResponse portletResponse =
512                 (PortletResponse)request.getAttribute(
513                     JavaConstants.JAVAX_PORTLET_RESPONSE);
514 
515             try {
516                 if (portletResponse != null) {
517                     if (themeDisplay.isLifecycleAction()) {
518                         ActionResponseImpl actionResponseImpl =
519                             (ActionResponseImpl)portletResponse;
520 
521                         ActionResponseFactory.recycle(actionResponseImpl);
522                     }
523                     else if (themeDisplay.isLifecycleRender()) {
524                         RenderResponseImpl renderResponseImpl =
525                             (RenderResponseImpl)portletResponse;
526 
527                         RenderResponseFactory.recycle(renderResponseImpl);
528                     }
529                     else if (themeDisplay.isLifecycleResource()) {
530                         ResourceResponseImpl resourceResponseImpl =
531                             (ResourceResponseImpl)portletResponse;
532 
533                         ResourceResponseFactory.recycle(resourceResponseImpl);
534                     }
535                 }
536             }
537             catch (Exception e) {
538                 _log.error(e);
539             }
540 
541             request.removeAttribute(JavaConstants.JAVAX_PORTLET_RESPONSE);
542         }
543     }
544 
545     protected Portlet processPortletRequest(
546             HttpServletRequest request, HttpServletResponse response,
547             String lifecycle)
548         throws Exception {
549 
550         HttpSession session = request.getSession();
551 
552         long companyId = PortalUtil.getCompanyId(request);
553         User user = PortalUtil.getUser(request);
554         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
555 
556         String portletId = ParamUtil.getString(request, "p_p_id");
557 
558         if (Validator.isNull(portletId)) {
559             return null;
560         }
561 
562         Portlet portlet = PortletLocalServiceUtil.getPortletById(
563             companyId, portletId);
564 
565         if (portlet == null) {
566             return null;
567         }
568 
569         ServletContext servletContext = (ServletContext)request.getAttribute(
570             WebKeys.CTX);
571 
572         InvokerPortlet invokerPortlet = PortletInstanceFactory.create(
573             portlet, servletContext);
574 
575         if (user != null) {
576             InvokerPortletImpl.clearResponse(
577                 session, layout.getPrimaryKey(), portletId,
578                 LanguageUtil.getLanguageId(request));
579         }
580 
581         PortletConfig portletConfig = PortletConfigFactory.create(
582             portlet, servletContext);
583         PortletContext portletContext = portletConfig.getPortletContext();
584 
585         WindowState windowState = WindowStateFactory.getWindowState(
586             ParamUtil.getString(request, "p_p_state"));
587 
588         PortletMode portletMode = PortletModeFactory.getPortletMode(
589             ParamUtil.getString(request, "p_p_mode"));
590 
591         PortletPreferencesIds portletPreferencesIds =
592             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
593                 request, portletId);
594 
595         PortletPreferences portletPreferences =
596             PortletPreferencesLocalServiceUtil.getPreferences(
597                 portletPreferencesIds);
598 
599         if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
600             String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
601 
602             if (_log.isDebugEnabled()) {
603                 _log.debug("Content type " + contentType);
604             }
605 
606             UploadServletRequest uploadRequest = null;
607 
608             try {
609                 if ((contentType != null) &&
610                     (contentType.startsWith(
611                         ContentTypes.MULTIPART_FORM_DATA))) {
612 
613                     PortletConfigImpl invokerPortletConfigImpl =
614                         (PortletConfigImpl)invokerPortlet.getPortletConfig();
615 
616                     if (invokerPortlet.isStrutsPortlet() ||
617                         ((invokerPortletConfigImpl != null) &&
618                          (!invokerPortletConfigImpl.isWARFile()))) {
619 
620                         uploadRequest = new UploadServletRequestImpl(request);
621 
622                         request = uploadRequest;
623                     }
624                 }
625 
626                 ActionRequestImpl actionRequestImpl =
627                     ActionRequestFactory.create(
628                         request, portlet, invokerPortlet, portletContext,
629                         windowState, portletMode, portletPreferences,
630                         layout.getPlid());
631 
632                 ActionResponseImpl actionResponseImpl =
633                     ActionResponseFactory.create(
634                         actionRequestImpl, response, portletId, user, layout,
635                         windowState, portletMode);
636 
637                 actionRequestImpl.defineObjects(
638                     portletConfig, actionResponseImpl);
639 
640                 invokerPortlet.processAction(
641                     actionRequestImpl, actionResponseImpl);
642 
643                 actionResponseImpl.transferHeaders(response);
644 
645                 RenderParametersPool.put(
646                     request, layout.getPlid(), portletId,
647                     actionResponseImpl.getRenderParameterMap());
648 
649                 if (actionResponseImpl.getEvents().size() > 0) {
650                     if (layout.getType().equals(LayoutConstants.TYPE_PORTLET)) {
651                         LayoutTypePortlet layoutTypePortlet =
652                             (LayoutTypePortlet)layout.getLayoutType();
653 
654                         List<Portlet> portlets =
655                             layoutTypePortlet.getPortlets();
656 
657                         processEvents(
658                             actionRequestImpl, actionResponseImpl, portlets);
659 
660                         actionRequestImpl.defineObjects(
661                             portletConfig, actionResponseImpl);
662                     }
663                 }
664             }
665             finally {
666                 if (uploadRequest != null) {
667                     uploadRequest.cleanUp();
668                 }
669             }
670         }
671         else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
672                  lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
673 
674             PortalUtil.updateWindowState(
675                 portletId, user, layout, windowState, request);
676 
677             PortalUtil.updatePortletMode(
678                 portletId, user, layout, portletMode, request);
679         }
680 
681         if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
682             ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
683                 WebKeys.THEME_DISPLAY);
684 
685             PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
686 
687             String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
688                 layout.getPlid(), portletId);
689 
690             portletDisplay.setId(portletId);
691             portletDisplay.setRootPortletId(portlet.getRootPortletId());
692             portletDisplay.setInstanceId(portlet.getInstanceId());
693             portletDisplay.setResourcePK(portletPrimaryKey);
694             portletDisplay.setPortletName(portletConfig.getPortletName());
695             portletDisplay.setNamespace(
696                 PortalUtil.getPortletNamespace(portletId));
697 
698             ResourceRequestImpl resourceRequestImpl =
699                 ResourceRequestFactory.create(
700                     request, portlet, invokerPortlet, portletContext,
701                     windowState, portletMode, portletPreferences,
702                     layout.getPlid());
703 
704             ResourceResponseImpl resourceResponseImpl =
705                 ResourceResponseFactory.create(
706                     resourceRequestImpl, response, portletId, companyId);
707 
708             resourceRequestImpl.defineObjects(
709                 portletConfig, resourceResponseImpl);
710 
711             invokerPortlet.serveResource(
712                 resourceRequestImpl, resourceResponseImpl);
713         }
714 
715         return portlet;
716     }
717 
718     protected void redirectActionURL(
719             HttpServletRequest request, HttpServletResponse response,
720             ActionResponseImpl actionResponseImpl, Portlet portlet)
721         throws Exception {
722 
723         ActionRequestImpl actionRequestImpl =
724             (ActionRequestImpl)request.getAttribute(
725                 JavaConstants.JAVAX_PORTLET_REQUEST);
726 
727         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
728 
729         PortletURL portletURL = new PortletURLImpl(
730             actionRequestImpl, actionRequestImpl.getPortletName(),
731             layout.getLayoutId(), PortletRequest.RENDER_PHASE);
732 
733         Map<String, String[]> renderParameters =
734             actionResponseImpl.getRenderParameterMap();
735 
736         for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
737             String key = entry.getKey();
738             String[] value = entry.getValue();
739 
740             portletURL.setParameter(key, value);
741         }
742 
743         response.sendRedirect(portletURL.toString());
744     }
745 
746     protected void renderExclusive(
747             HttpServletRequest request, HttpServletResponse response,
748             ThemeDisplay themeDisplay)
749         throws Exception {
750 
751         RenderRequestImpl renderRequestImpl =
752             (RenderRequestImpl)request.getAttribute(
753                 JavaConstants.JAVAX_PORTLET_REQUEST);
754 
755         RenderResponseImpl renderResponseImpl =
756             (RenderResponseImpl)request.getAttribute(
757                 JavaConstants.JAVAX_PORTLET_RESPONSE);
758 
759         StringServletResponse stringResponse =
760             (StringServletResponse)renderRequestImpl.getAttribute(
761                 WebKeys.STRING_SERVLET_RESPONSE);
762 
763         renderResponseImpl.transferHeaders(response);
764 
765         if (stringResponse.isCalledGetOutputStream()) {
766             InputStream is = new ByteArrayInputStream(
767                 stringResponse.getByteArrayMaker().toByteArray());
768 
769             ServletResponseUtil.sendFile(
770                 response, renderResponseImpl.getResourceName(), is,
771                 renderResponseImpl.getContentType());
772         }
773         else {
774             byte[] content = stringResponse.getString().getBytes(
775                 StringPool.UTF8);
776 
777             ServletResponseUtil.sendFile(
778                 response, renderResponseImpl.getResourceName(), content,
779                 renderResponseImpl.getContentType());
780         }
781 
782         RenderRequestFactory.recycle(renderRequestImpl);
783         RenderResponseFactory.recycle(renderResponseImpl);
784     }
785 
786     private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
787 
788 }