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