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