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 
310         String portletId = portlet.getPortletId();
311 
312         ServletContext servletContext =
313             (ServletContext)request.getAttribute(WebKeys.CTX);
314 
315         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
316             portlet, servletContext);
317 
318         PortletConfig portletConfig = PortletConfigFactory.create(
319             portlet, servletContext);
320         PortletContext portletContext = portletConfig.getPortletContext();
321 
322         WindowState windowState = portletRequestImpl.getWindowState();
323         PortletMode portletMode = portletRequestImpl.getPortletMode();
324 
325         User user = stateAwareResponseImpl.getUser();
326         Layout layout = stateAwareResponseImpl.getLayout();
327 
328         PortletPreferences portletPreferences =
329             portletRequestImpl.getPreferencesImpl();
330 
331         EventRequestImpl eventRequestImpl = EventRequestFactory.create(
332             request, portlet, invokerPortlet, portletContext, windowState,
333             portletMode, portletPreferences, layout.getPlid());
334 
335         eventRequestImpl.setEvent(event);
336 
337         EventResponseImpl eventResponseImpl = EventResponseFactory.create(
338             eventRequestImpl, response, portletId, user, layout, windowState,
339             portletMode);
340 
341         eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
342 
343         try {
344             try {
345                 invokerPortlet.processEvent(
346                     eventRequestImpl, eventResponseImpl);
347 
348                 if (eventResponseImpl.isCalledSetRenderParameter()) {
349                     Map<String, String[]> renderParameterMap =
350                         new HashMap<String, String[]>();
351 
352                     MapUtil.copy(
353                         eventResponseImpl.getRenderParameterMap(),
354                         renderParameterMap);
355 
356                     RenderParametersPool.put(
357                         request, layout.getPlid(), portletId,
358                         renderParameterMap);
359                 }
360             }
361             catch (UnavailableException ue) {
362                 throw ue;
363             }
364             catch (PortletException pe) {
365                 eventResponseImpl.setWindowState(windowState);
366                 eventResponseImpl.setPortletMode(portletMode);
367             }
368 
369             processEvents(eventRequestImpl, eventResponseImpl, portlets);
370         }
371         finally {
372             eventRequestImpl.cleanUp();
373         }
374     }
375 
376     protected void processEvents(
377             PortletRequestImpl portletRequestImpl,
378             StateAwareResponseImpl stateAwareResponseImpl,
379             List<Portlet> portlets)
380         throws Exception {
381 
382         List<Event> events = stateAwareResponseImpl.getEvents();
383 
384         if (events.size() == 0) {
385             return;
386         }
387 
388         for (Event event : events) {
389             javax.xml.namespace.QName qName = event.getQName();
390 
391             for (Portlet portlet : portlets) {
392                 QName processingQName = portlet.getProcessingEvent(
393                     qName.getNamespaceURI(), qName.getLocalPart());
394 
395                 if (processingQName != null) {
396                     processEvent(
397                         portletRequestImpl, stateAwareResponseImpl, portlet,
398                         portlets, event);
399                 }
400             }
401         }
402     }
403 
404     protected ActionForward processLayout(
405             ActionMapping mapping, HttpServletRequest request,
406             HttpServletResponse response, long plid)
407         throws Exception {
408 
409         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
410             WebKeys.THEME_DISPLAY);
411 
412         try {
413             Layout layout = themeDisplay.getLayout();
414 
415             boolean resetLayout = ParamUtil.getBoolean(
416                 request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
417 
418             if (!PropsValues.TCK_URL && resetLayout) {
419                 RenderParametersPool.clear(request, plid);
420             }
421 
422             if (themeDisplay.isLifecycleAction()) {
423                 Portlet portlet = processPortletRequest(
424                     request, response, PortletRequest.ACTION_PHASE);
425 
426                 if (portlet != null) {
427                     ActionResponseImpl actionResponseImpl =
428                         (ActionResponseImpl)request.getAttribute(
429                             JavaConstants.JAVAX_PORTLET_RESPONSE);
430 
431                     String redirectLocation =
432                         actionResponseImpl.getRedirectLocation();
433 
434                     if (Validator.isNotNull(redirectLocation)) {
435                         response.sendRedirect(redirectLocation);
436 
437                         return null;
438                     }
439 
440                     if (portlet.isActionURLRedirect()) {
441                         redirectActionURL(
442                             request, response, actionResponseImpl, portlet);
443 
444                         return null;
445                     }
446                 }
447             }
448             else if (themeDisplay.isLifecycleRender()) {
449                 processPortletRequest(
450                     request, response, PortletRequest.RENDER_PHASE);
451             }
452 
453             if (themeDisplay.isLifecycleResource()) {
454                 processPortletRequest(
455                     request, response, PortletRequest.RESOURCE_PHASE);
456 
457                 return null;
458             }
459             else {
460                 if (layout != null) {
461 
462                     // Include layout content before the page loads because
463                     // portlets on the page can set the page title and page
464                     // subtitle
465 
466                     includeLayoutContent(
467                         request, response, themeDisplay, layout);
468 
469                     if (themeDisplay.isStateExclusive()) {
470                         renderExclusive(request, response, themeDisplay);
471 
472                         return null;
473                     }
474                 }
475 
476                 return mapping.findForward("portal.layout");
477             }
478         }
479         catch (Exception e) {
480             PortalUtil.sendError(e, request, response);
481 
482             return null;
483         }
484         finally {
485             PortletRequest portletRequest =
486                 (PortletRequest)request.getAttribute(
487                     JavaConstants.JAVAX_PORTLET_REQUEST);
488 
489             if (portletRequest != null) {
490                 PortletRequestImpl portletRequestImpl =
491                     (PortletRequestImpl)portletRequest;
492 
493                 portletRequestImpl.cleanUp();
494             }
495         }
496     }
497 
498     protected Portlet processPortletRequest(
499             HttpServletRequest request, HttpServletResponse response,
500             String lifecycle)
501         throws Exception {
502 
503         HttpSession session = request.getSession();
504 
505         long companyId = PortalUtil.getCompanyId(request);
506         User user = PortalUtil.getUser(request);
507         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
508 
509         String portletId = ParamUtil.getString(request, "p_p_id");
510 
511         Portlet portlet = PortletLocalServiceUtil.getPortletById(
512             companyId, portletId);
513 
514         if (portlet == null) {
515             return null;
516         }
517 
518         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
519             WebKeys.THEME_DISPLAY);
520 
521         themeDisplay.setScopeGroupId(
522             PortalUtil.getScopeGroupId(request, portletId));
523 
524         ServletContext servletContext = (ServletContext)request.getAttribute(
525             WebKeys.CTX);
526 
527         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
528             portlet, servletContext);
529 
530         if (user != null) {
531             InvokerPortletImpl.clearResponse(
532                 session, layout.getPrimaryKey(), portletId,
533                 LanguageUtil.getLanguageId(request));
534         }
535 
536         PortletConfig portletConfig = PortletConfigFactory.create(
537             portlet, servletContext);
538         PortletContext portletContext = portletConfig.getPortletContext();
539 
540         WindowState windowState = WindowStateFactory.getWindowState(
541             ParamUtil.getString(request, "p_p_state"));
542 
543         PortletMode portletMode = PortletModeFactory.getPortletMode(
544             ParamUtil.getString(request, "p_p_mode"));
545 
546         PortletPreferencesIds portletPreferencesIds =
547             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
548                 request, portletId);
549 
550         PortletPreferences portletPreferences =
551             PortletPreferencesLocalServiceUtil.getPreferences(
552                 portletPreferencesIds);
553 
554         if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
555             String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
556 
557             if (_log.isDebugEnabled()) {
558                 _log.debug("Content type " + contentType);
559             }
560 
561             UploadServletRequest uploadRequest = null;
562 
563             try {
564                 if ((contentType != null) &&
565                     (contentType.startsWith(
566                         ContentTypes.MULTIPART_FORM_DATA))) {
567 
568                     PortletConfigImpl invokerPortletConfigImpl =
569                         (PortletConfigImpl)invokerPortlet.getPortletConfig();
570 
571                     if (invokerPortlet.isStrutsPortlet() ||
572                         ((invokerPortletConfigImpl != null) &&
573                          (!invokerPortletConfigImpl.isWARFile()))) {
574 
575                         uploadRequest = new UploadServletRequestImpl(request);
576 
577                         request = uploadRequest;
578                     }
579                 }
580 
581                 ActionRequestImpl actionRequestImpl =
582                     ActionRequestFactory.create(
583                         request, portlet, invokerPortlet, portletContext,
584                         windowState, portletMode, portletPreferences,
585                         layout.getPlid());
586 
587                 ActionResponseImpl actionResponseImpl =
588                     ActionResponseFactory.create(
589                         actionRequestImpl, response, portletId, user, layout,
590                         windowState, portletMode);
591 
592                 actionRequestImpl.defineObjects(
593                     portletConfig, actionResponseImpl);
594 
595                 invokerPortlet.processAction(
596                     actionRequestImpl, actionResponseImpl);
597 
598                 actionResponseImpl.transferHeaders(response);
599 
600                 RenderParametersPool.put(
601                     request, layout.getPlid(), portletId,
602                     actionResponseImpl.getRenderParameterMap());
603 
604                 if (actionResponseImpl.getEvents().size() > 0) {
605                     if (layout.getType().equals(LayoutConstants.TYPE_PORTLET)) {
606                         LayoutTypePortlet layoutTypePortlet =
607                             (LayoutTypePortlet)layout.getLayoutType();
608 
609                         List<Portlet> portlets =
610                             layoutTypePortlet.getPortlets();
611 
612                         processEvents(
613                             actionRequestImpl, actionResponseImpl, portlets);
614 
615                         actionRequestImpl.defineObjects(
616                             portletConfig, actionResponseImpl);
617                     }
618                 }
619             }
620             finally {
621                 if (uploadRequest != null) {
622                     uploadRequest.cleanUp();
623                 }
624             }
625         }
626         else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
627                  lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
628 
629             PortalUtil.updateWindowState(
630                 portletId, user, layout, windowState, request);
631 
632             PortalUtil.updatePortletMode(
633                 portletId, user, layout, portletMode, request);
634         }
635 
636         if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
637             PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
638 
639             String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
640                 layout.getPlid(), portletId);
641 
642             portletDisplay.setId(portletId);
643             portletDisplay.setRootPortletId(portlet.getRootPortletId());
644             portletDisplay.setInstanceId(portlet.getInstanceId());
645             portletDisplay.setResourcePK(portletPrimaryKey);
646             portletDisplay.setPortletName(portletConfig.getPortletName());
647             portletDisplay.setNamespace(
648                 PortalUtil.getPortletNamespace(portletId));
649 
650             ResourceRequestImpl resourceRequestImpl =
651                 ResourceRequestFactory.create(
652                     request, portlet, invokerPortlet, portletContext,
653                     windowState, portletMode, portletPreferences,
654                     layout.getPlid());
655 
656             ResourceResponseImpl resourceResponseImpl =
657                 ResourceResponseFactory.create(
658                     resourceRequestImpl, response, portletId, companyId);
659 
660             resourceRequestImpl.defineObjects(
661                 portletConfig, resourceResponseImpl);
662 
663             invokerPortlet.serveResource(
664                 resourceRequestImpl, resourceResponseImpl);
665         }
666 
667         return portlet;
668     }
669 
670     protected void redirectActionURL(
671             HttpServletRequest request, HttpServletResponse response,
672             ActionResponseImpl actionResponseImpl, Portlet portlet)
673         throws Exception {
674 
675         ActionRequestImpl actionRequestImpl =
676             (ActionRequestImpl)request.getAttribute(
677                 JavaConstants.JAVAX_PORTLET_REQUEST);
678 
679         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
680 
681         PortletURL portletURL = new PortletURLImpl(
682             actionRequestImpl, actionRequestImpl.getPortletName(),
683             layout.getLayoutId(), PortletRequest.RENDER_PHASE);
684 
685         Map<String, String[]> renderParameters =
686             actionResponseImpl.getRenderParameterMap();
687 
688         for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
689             String key = entry.getKey();
690             String[] value = entry.getValue();
691 
692             portletURL.setParameter(key, value);
693         }
694 
695         response.sendRedirect(portletURL.toString());
696     }
697 
698     protected void renderExclusive(
699             HttpServletRequest request, HttpServletResponse response,
700             ThemeDisplay themeDisplay)
701         throws Exception {
702 
703         RenderRequestImpl renderRequestImpl =
704             (RenderRequestImpl)request.getAttribute(
705                 JavaConstants.JAVAX_PORTLET_REQUEST);
706 
707         RenderResponseImpl renderResponseImpl =
708             (RenderResponseImpl)request.getAttribute(
709                 JavaConstants.JAVAX_PORTLET_RESPONSE);
710 
711         StringServletResponse stringResponse =
712             (StringServletResponse)renderRequestImpl.getAttribute(
713                 WebKeys.STRING_SERVLET_RESPONSE);
714 
715         renderResponseImpl.transferHeaders(response);
716 
717         if (stringResponse.isCalledGetOutputStream()) {
718             InputStream is = new ByteArrayInputStream(
719                 stringResponse.getByteArrayMaker().toByteArray());
720 
721             ServletResponseUtil.sendFile(
722                 response, renderResponseImpl.getResourceName(), is,
723                 renderResponseImpl.getContentType());
724         }
725         else {
726             byte[] content = stringResponse.getString().getBytes(
727                 StringPool.UTF8);
728 
729             ServletResponseUtil.sendFile(
730                 response, renderResponseImpl.getResourceName(), content,
731                 renderResponseImpl.getContentType());
732         }
733 
734         renderRequestImpl.cleanUp();
735     }
736 
737     private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
738 
739 }