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