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