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