1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.io.unsync.UnsyncByteArrayInputStream;
26  import com.liferay.portal.kernel.language.LanguageUtil;
27  import com.liferay.portal.kernel.log.Log;
28  import com.liferay.portal.kernel.log.LogFactoryUtil;
29  import com.liferay.portal.kernel.portlet.LiferayPortletMode;
30  import com.liferay.portal.kernel.portlet.PortletModeFactory;
31  import com.liferay.portal.kernel.portlet.WindowStateFactory;
32  import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
33  import com.liferay.portal.kernel.servlet.HttpHeaders;
34  import com.liferay.portal.kernel.servlet.StringServletResponse;
35  import com.liferay.portal.kernel.upload.UploadServletRequest;
36  import com.liferay.portal.kernel.util.ContentTypes;
37  import com.liferay.portal.kernel.util.HttpUtil;
38  import com.liferay.portal.kernel.util.JavaConstants;
39  import com.liferay.portal.kernel.util.MapUtil;
40  import com.liferay.portal.kernel.util.ParamUtil;
41  import com.liferay.portal.kernel.util.PropsKeys;
42  import com.liferay.portal.kernel.util.StringPool;
43  import com.liferay.portal.kernel.util.Validator;
44  import com.liferay.portal.kernel.xml.QName;
45  import com.liferay.portal.model.Layout;
46  import com.liferay.portal.model.LayoutConstants;
47  import com.liferay.portal.model.LayoutTypePortlet;
48  import com.liferay.portal.model.Portlet;
49  import com.liferay.portal.model.PortletPreferencesIds;
50  import com.liferay.portal.model.PublicRenderParameter;
51  import com.liferay.portal.model.User;
52  import com.liferay.portal.service.LayoutLocalServiceUtil;
53  import com.liferay.portal.service.PortletLocalServiceUtil;
54  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
55  import com.liferay.portal.service.permission.PortletPermissionUtil;
56  import com.liferay.portal.struts.ActionConstants;
57  import com.liferay.portal.struts.StrutsUtil;
58  import com.liferay.portal.theme.PortletDisplay;
59  import com.liferay.portal.theme.ThemeDisplay;
60  import com.liferay.portal.upload.UploadServletRequestImpl;
61  import com.liferay.portal.util.PortalUtil;
62  import com.liferay.portal.util.PrefsPropsUtil;
63  import com.liferay.portal.util.PropsValues;
64  import com.liferay.portal.util.WebKeys;
65  import com.liferay.portlet.ActionRequestFactory;
66  import com.liferay.portlet.ActionRequestImpl;
67  import com.liferay.portlet.ActionResponseFactory;
68  import com.liferay.portlet.ActionResponseImpl;
69  import com.liferay.portlet.EventRequestFactory;
70  import com.liferay.portlet.EventRequestImpl;
71  import com.liferay.portlet.EventResponseFactory;
72  import com.liferay.portlet.EventResponseImpl;
73  import com.liferay.portlet.InvokerPortlet;
74  import com.liferay.portlet.InvokerPortletImpl;
75  import com.liferay.portlet.PortletConfigFactory;
76  import com.liferay.portlet.PortletConfigImpl;
77  import com.liferay.portlet.PortletInstanceFactoryUtil;
78  import com.liferay.portlet.PortletPreferencesFactoryUtil;
79  import com.liferay.portlet.PortletQName;
80  import com.liferay.portlet.PortletQNameUtil;
81  import com.liferay.portlet.PortletRequestImpl;
82  import com.liferay.portlet.PortletURLImpl;
83  import com.liferay.portlet.PublicRenderParametersPool;
84  import com.liferay.portlet.RenderParametersPool;
85  import com.liferay.portlet.RenderRequestImpl;
86  import com.liferay.portlet.RenderResponseImpl;
87  import com.liferay.portlet.ResourceRequestFactory;
88  import com.liferay.portlet.ResourceRequestImpl;
89  import com.liferay.portlet.ResourceResponseFactory;
90  import com.liferay.portlet.ResourceResponseImpl;
91  import com.liferay.portlet.StateAwareResponseImpl;
92  import com.liferay.portlet.login.util.LoginUtil;
93  import com.liferay.util.servlet.ServletResponseUtil;
94  
95  import java.io.InputStream;
96  
97  import java.util.ArrayList;
98  import java.util.Enumeration;
99  import java.util.HashMap;
100 import java.util.List;
101 import java.util.Map;
102 
103 import javax.portlet.Event;
104 import javax.portlet.PortletConfig;
105 import javax.portlet.PortletContext;
106 import javax.portlet.PortletMode;
107 import javax.portlet.PortletPreferences;
108 import javax.portlet.PortletRequest;
109 import javax.portlet.PortletURL;
110 import javax.portlet.UnavailableException;
111 import javax.portlet.WindowState;
112 
113 import javax.servlet.RequestDispatcher;
114 import javax.servlet.ServletContext;
115 import javax.servlet.http.HttpServletRequest;
116 import javax.servlet.http.HttpServletResponse;
117 import javax.servlet.http.HttpSession;
118 
119 import org.apache.struts.action.Action;
120 import org.apache.struts.action.ActionForm;
121 import org.apache.struts.action.ActionForward;
122 import org.apache.struts.action.ActionMapping;
123 
124 /**
125  * <a href="LayoutAction.java.html"><b><i>View Source</i></b></a>
126  *
127  * @author Brian Wing Shun Chan
128  */
129 public class LayoutAction extends Action {
130 
131     public ActionForward execute(
132             ActionMapping mapping, ActionForm form, HttpServletRequest request,
133             HttpServletResponse response)
134         throws Exception {
135 
136         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
137             WebKeys.THEME_DISPLAY);
138 
139         Layout layout = themeDisplay.getLayout();
140 
141         Boolean layoutDefault = (Boolean)request.getAttribute(
142             WebKeys.LAYOUT_DEFAULT);
143 
144         if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
145             Layout requestedLayout = (Layout)request.getAttribute(
146                 WebKeys.REQUESTED_LAYOUT);
147 
148             if (requestedLayout != null) {
149                 String redirectParam = "redirect";
150 
151                 if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME)) {
152                     redirectParam =
153                         PortalUtil.getPortletNamespace(
154                             PropsValues.AUTH_LOGIN_PORTLET_NAME) +
155                         redirectParam;
156                 }
157 
158                 String authLoginURL = null;
159 
160                 if (PrefsPropsUtil.getBoolean(
161                         themeDisplay.getCompanyId(), PropsKeys.CAS_AUTH_ENABLED,
162                         PropsValues.CAS_AUTH_ENABLED)) {
163 
164                     authLoginURL = themeDisplay.getURLSignIn();
165                 }
166 
167                 if (Validator.isNull(authLoginURL)) {
168                     authLoginURL = PortalUtil.getCommunityLoginURL(
169                         themeDisplay);
170                 }
171 
172                 if (Validator.isNull(authLoginURL)) {
173                     authLoginURL = PropsValues.AUTH_LOGIN_URL;
174                 }
175 
176                 if (Validator.isNull(authLoginURL)) {
177                     PortletURL loginURL = LoginUtil.getLoginURL(
178                         request, themeDisplay.getPlid());
179 
180                     authLoginURL = loginURL.toString();
181                 }
182 
183                 String currentURL = PortalUtil.getCurrentURL(request);
184 
185                 authLoginURL = HttpUtil.setParameter(
186                     authLoginURL, redirectParam, currentURL);
187 
188                 if (_log.isDebugEnabled()) {
189                     _log.debug("Redirect requested layout to " + authLoginURL);
190                 }
191 
192                 response.sendRedirect(authLoginURL);
193             }
194             else {
195                 String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
196 
197                 if (_log.isDebugEnabled()) {
198                     _log.debug("Redirect default layout to " + redirect);
199                 }
200 
201                 response.sendRedirect(redirect);
202             }
203 
204             return null;
205         }
206 
207         long plid = ParamUtil.getLong(request, "p_l_id");
208 
209         if (_log.isDebugEnabled()) {
210             _log.debug("p_l_id is " + plid);
211         }
212 
213         if (plid > 0) {
214             return processLayout(mapping, request, response, plid);
215         }
216         else {
217             try {
218                 forwardLayout(request);
219 
220                 return mapping.findForward(ActionConstants.COMMON_FORWARD_JSP);
221             }
222             catch (Exception e) {
223                 PortalUtil.sendError(e, request, response);
224 
225                 return null;
226             }
227         }
228     }
229 
230     protected void forwardLayout(HttpServletRequest request) throws Exception {
231         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
232 
233         long plid = LayoutConstants.DEFAULT_PLID;
234 
235         String layoutFriendlyURL = null;
236 
237         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
238             WebKeys.THEME_DISPLAY);
239 
240         if (layout != null) {
241             plid = layout.getPlid();
242 
243             layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
244                 layout, themeDisplay);
245         }
246 
247         String forwardURL = layoutFriendlyURL;
248 
249         if (Validator.isNull(forwardURL)) {
250             forwardURL =
251                 themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
252 
253             if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
254                 forwardURL = HttpUtil.addParameter(
255                     forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
256             }
257 
258             if (Validator.isNotNull(themeDisplay.getDoAsUserLanguageId())) {
259                 forwardURL = HttpUtil.addParameter(
260                     forwardURL, "doAsUserLanguageId",
261                     themeDisplay.getDoAsUserLanguageId());
262             }
263         }
264 
265         if (_log.isDebugEnabled()) {
266             _log.debug("Forward layout to " + forwardURL);
267         }
268 
269         request.setAttribute(WebKeys.FORWARD_URL, forwardURL);
270     }
271 
272     protected List<LayoutTypePortlet> getLayoutTypePortlets(
273             long groupId, boolean privateLayout)
274         throws Exception {
275 
276         List<LayoutTypePortlet> layoutTypePortlets =
277             new ArrayList<LayoutTypePortlet>();
278 
279         List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
280             groupId, privateLayout, LayoutConstants.TYPE_PORTLET);
281 
282         for (Layout layout : layouts) {
283             if (!layout.getType().equals(LayoutConstants.TYPE_PORTLET)) {
284                 continue;
285             }
286 
287             LayoutTypePortlet layoutTypePortlet =
288                 (LayoutTypePortlet)layout.getLayoutType();
289 
290             layoutTypePortlets.add(layoutTypePortlet);
291         }
292 
293         return layoutTypePortlets;
294     }
295 
296     protected void includeLayoutContent(
297             HttpServletRequest request, HttpServletResponse response,
298             ThemeDisplay themeDisplay, Layout layout)
299         throws Exception {
300 
301         ServletContext servletContext = (ServletContext)request.getAttribute(
302             WebKeys.CTX);
303 
304         String path = StrutsUtil.TEXT_HTML_DIR;
305 
306         if (BrowserSnifferUtil.isWap(request)) {
307             path = StrutsUtil.TEXT_WAP_DIR;
308         }
309 
310         // Manually check the p_p_id. See LEP-1724.
311 
312         if (themeDisplay.isStateExclusive() ||
313             Validator.isNotNull(ParamUtil.getString(request, "p_p_id"))) {
314 
315             if (layout.getType().equals(LayoutConstants.TYPE_PANEL)) {
316                 path += "/portal/layout/view/panel.jsp";
317             }
318             else if (layout.getType().equals(
319                         LayoutConstants.TYPE_CONTROL_PANEL)) {
320 
321                 path += "/portal/layout/view/control_panel.jsp";
322             }
323             else {
324                 path += "/portal/layout/view/portlet.jsp";
325             }
326         }
327         else {
328             path += PortalUtil.getLayoutViewPage(layout);
329         }
330 
331         RequestDispatcher requestDispatcher =
332             servletContext.getRequestDispatcher(path);
333 
334         StringServletResponse stringResponse = new StringServletResponse(
335             response);
336 
337         requestDispatcher.include(request, stringResponse);
338 
339         request.setAttribute(
340             WebKeys.LAYOUT_CONTENT, stringResponse.getString());
341     }
342 
343     protected void processEvent(
344             PortletRequestImpl portletRequestImpl,
345             StateAwareResponseImpl stateAwareResponseImpl,
346             List<LayoutTypePortlet> layoutTypePortlets,
347             LayoutTypePortlet layoutTypePortlet, Portlet portlet, Event event)
348         throws Exception {
349 
350         HttpServletRequest request = portletRequestImpl.getHttpServletRequest();
351         HttpServletResponse response =
352             stateAwareResponseImpl.getHttpServletResponse();
353         HttpSession session = request.getSession();
354 
355         String portletId = portlet.getPortletId();
356 
357         ServletContext servletContext =
358             (ServletContext)request.getAttribute(WebKeys.CTX);
359 
360         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
361             portlet, servletContext);
362 
363         PortletConfig portletConfig = PortletConfigFactory.create(
364             portlet, servletContext);
365         PortletContext portletContext = portletConfig.getPortletContext();
366 
367         WindowState windowState = null;
368 
369         if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
370             windowState = WindowState.MAXIMIZED;
371         }
372         else if (layoutTypePortlet.hasStateMinPortletId(portletId)) {
373             windowState = WindowState.MINIMIZED;
374         }
375         else {
376             windowState = WindowState.NORMAL;
377         }
378 
379         PortletMode portletMode = null;
380 
381         if (layoutTypePortlet.hasModeAboutPortletId(portletId)) {
382             portletMode = LiferayPortletMode.ABOUT;
383         }
384         else if (layoutTypePortlet.hasModeConfigPortletId(portletId)) {
385             portletMode = LiferayPortletMode.CONFIG;
386         }
387         else if (layoutTypePortlet.hasModeEditPortletId(portletId)) {
388             portletMode = PortletMode.EDIT;
389         }
390         else if (layoutTypePortlet.hasModeEditDefaultsPortletId(portletId)) {
391             portletMode = LiferayPortletMode.EDIT_DEFAULTS;
392         }
393         else if (layoutTypePortlet.hasModeEditGuestPortletId(portletId)) {
394             portletMode = LiferayPortletMode.EDIT_GUEST;
395         }
396         else if (layoutTypePortlet.hasModeHelpPortletId(portletId)) {
397             portletMode = PortletMode.HELP;
398         }
399         else if (layoutTypePortlet.hasModePreviewPortletId(portletId)) {
400             portletMode = LiferayPortletMode.PREVIEW;
401         }
402         else if (layoutTypePortlet.hasModePrintPortletId(portletId)) {
403             portletMode = LiferayPortletMode.PRINT;
404         }
405         else {
406             portletMode = PortletMode.VIEW;
407         }
408 
409         User user = stateAwareResponseImpl.getUser();
410         Layout layout = stateAwareResponseImpl.getLayout();
411 
412         PortletPreferences portletPreferences =
413             portletRequestImpl.getPreferencesImpl();
414 
415         EventRequestImpl eventRequestImpl = EventRequestFactory.create(
416             request, portlet, invokerPortlet, portletContext, windowState,
417             portletMode, portletPreferences, layout.getPlid());
418 
419         eventRequestImpl.setEvent(event);
420 
421         EventResponseImpl eventResponseImpl = EventResponseFactory.create(
422             eventRequestImpl, response, portletId, user, layout);
423 
424         eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
425 
426         try {
427             try {
428                 InvokerPortletImpl.clearResponse(
429                     session, layout.getPrimaryKey(), portletId,
430                     LanguageUtil.getLanguageId(eventRequestImpl));
431 
432                 invokerPortlet.processEvent(
433                     eventRequestImpl, eventResponseImpl);
434 
435                 if (eventResponseImpl.isCalledSetRenderParameter()) {
436                     Map<String, String[]> renderParameterMap =
437                         new HashMap<String, String[]>();
438 
439                     MapUtil.copy(
440                         eventResponseImpl.getRenderParameterMap(),
441                         renderParameterMap);
442 
443                     RenderParametersPool.put(
444                         request, layout.getPlid(), portletId,
445                         renderParameterMap);
446                 }
447             }
448             catch (UnavailableException ue) {
449                 throw ue;
450             }
451 
452             processEvents(
453                 eventRequestImpl, eventResponseImpl, layoutTypePortlets);
454         }
455         finally {
456             eventRequestImpl.cleanUp();
457         }
458     }
459 
460     protected void processEvents(
461             PortletRequestImpl portletRequestImpl,
462             StateAwareResponseImpl stateAwareResponseImpl,
463             List<LayoutTypePortlet> layoutTypePortlets)
464         throws Exception {
465 
466         List<Event> events = stateAwareResponseImpl.getEvents();
467 
468         if (events.size() == 0) {
469             return;
470         }
471 
472         for (Event event : events) {
473             javax.xml.namespace.QName qName = event.getQName();
474 
475             for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
476                 List<Portlet> portlets = layoutTypePortlet.getPortlets();
477 
478                 for (Portlet portlet : portlets) {
479                     QName processingQName = portlet.getProcessingEvent(
480                         qName.getNamespaceURI(), qName.getLocalPart());
481 
482                     if (processingQName != null) {
483                         processEvent(
484                             portletRequestImpl, stateAwareResponseImpl,
485                             layoutTypePortlets, layoutTypePortlet, portlet,
486                             event);
487                     }
488                 }
489             }
490         }
491     }
492 
493     protected ActionForward processLayout(
494             ActionMapping mapping, HttpServletRequest request,
495             HttpServletResponse response, long plid)
496         throws Exception {
497 
498         HttpSession session = request.getSession();
499 
500         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
501             WebKeys.THEME_DISPLAY);
502 
503         try {
504             Layout layout = themeDisplay.getLayout();
505 
506             boolean resetLayout = ParamUtil.getBoolean(
507                 request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
508 
509             String portletId = ParamUtil.getString(request, "p_p_id");
510 
511             Layout previousLayout = (Layout)session.getAttribute(
512                 WebKeys.PREVIOUS_LAYOUT);
513 
514             if ((previousLayout == null) ||
515                 (layout.getPlid() != previousLayout.getPlid())) {
516 
517                 session.setAttribute(WebKeys.PREVIOUS_LAYOUT, layout);
518             }
519 
520             if (!PropsValues.TCK_URL && resetLayout &&
521                 (Validator.isNull(portletId) ||
522                  ((previousLayout != null) &&
523                   (layout.getPlid() != previousLayout.getPlid())))) {
524 
525                 // Always clear render parameters on a layout url, but do not
526                 // clear on portlet urls invoked on the same layout
527 
528                 RenderParametersPool.clear(request, plid);
529             }
530 
531             if (themeDisplay.isLifecycleAction()) {
532                 Portlet portlet = processPortletRequest(
533                     request, response, PortletRequest.ACTION_PHASE);
534 
535                 if (portlet != null) {
536                     ActionResponseImpl actionResponseImpl =
537                         (ActionResponseImpl)request.getAttribute(
538                             JavaConstants.JAVAX_PORTLET_RESPONSE);
539 
540                     String redirectLocation =
541                         actionResponseImpl.getRedirectLocation();
542 
543                     if (Validator.isNotNull(redirectLocation)) {
544                         response.sendRedirect(redirectLocation);
545 
546                         return null;
547                     }
548 
549                     if (portlet.isActionURLRedirect()) {
550                         redirectActionURL(
551                             request, response, actionResponseImpl, portlet);
552 
553                         return null;
554                     }
555                 }
556             }
557             else if (themeDisplay.isLifecycleRender()) {
558                 processPortletRequest(
559                     request, response, PortletRequest.RENDER_PHASE);
560             }
561 
562             if (themeDisplay.isLifecycleResource()) {
563                 processPortletRequest(
564                     request, response, PortletRequest.RESOURCE_PHASE);
565 
566                 return null;
567             }
568             else {
569                 if (response.isCommitted()) {
570                     return null;
571                 }
572 
573                 if (layout != null) {
574 
575                     // Include layout content before the page loads because
576                     // portlets on the page can set the page title and page
577                     // subtitle
578 
579                     includeLayoutContent(
580                         request, response, themeDisplay, layout);
581 
582                     if (themeDisplay.isStateExclusive()) {
583                         renderExclusive(request, response, themeDisplay);
584 
585                         return null;
586                     }
587                 }
588 
589                 return mapping.findForward("portal.layout");
590             }
591         }
592         catch (Exception e) {
593             PortalUtil.sendError(e, request, response);
594 
595             return null;
596         }
597         finally {
598             PortletRequest portletRequest =
599                 (PortletRequest)request.getAttribute(
600                     JavaConstants.JAVAX_PORTLET_REQUEST);
601 
602             if (portletRequest != null) {
603                 PortletRequestImpl portletRequestImpl =
604                     (PortletRequestImpl)portletRequest;
605 
606                 portletRequestImpl.cleanUp();
607             }
608         }
609     }
610 
611     protected Portlet processPortletRequest(
612             HttpServletRequest request, HttpServletResponse response,
613             String lifecycle)
614         throws Exception {
615 
616         HttpSession session = request.getSession();
617 
618         long companyId = PortalUtil.getCompanyId(request);
619         User user = PortalUtil.getUser(request);
620         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
621 
622         String portletId = ParamUtil.getString(request, "p_p_id");
623 
624         if (Validator.isNull(portletId)) {
625             return null;
626         }
627 
628         Portlet portlet = PortletLocalServiceUtil.getPortletById(
629             companyId, portletId);
630 
631         if (portlet == null) {
632             return null;
633         }
634 
635         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
636             WebKeys.THEME_DISPLAY);
637 
638         themeDisplay.setScopeGroupId(
639             PortalUtil.getScopeGroupId(request, portletId));
640 
641         ServletContext servletContext = (ServletContext)request.getAttribute(
642             WebKeys.CTX);
643 
644         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
645             portlet, servletContext);
646 
647         if (user != null) {
648             InvokerPortletImpl.clearResponse(
649                 session, layout.getPrimaryKey(), portletId,
650                 LanguageUtil.getLanguageId(request));
651         }
652 
653         PortletConfig portletConfig = PortletConfigFactory.create(
654             portlet, servletContext);
655         PortletContext portletContext = portletConfig.getPortletContext();
656 
657         WindowState windowState = WindowStateFactory.getWindowState(
658             ParamUtil.getString(request, "p_p_state"));
659 
660         PortletMode portletMode = PortletModeFactory.getPortletMode(
661             ParamUtil.getString(request, "p_p_mode"));
662 
663         PortletPreferencesIds portletPreferencesIds =
664             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
665                 request, portletId);
666 
667         PortletPreferences portletPreferences =
668             PortletPreferencesLocalServiceUtil.getPreferences(
669                 portletPreferencesIds);
670 
671         processPublicRenderParameters(request, layout, portlet);
672 
673         if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
674             String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
675 
676             if (_log.isDebugEnabled()) {
677                 _log.debug("Content type " + contentType);
678             }
679 
680             UploadServletRequest uploadRequest = null;
681 
682             try {
683                 if ((contentType != null) &&
684                     (contentType.startsWith(
685                         ContentTypes.MULTIPART_FORM_DATA))) {
686 
687                     PortletConfigImpl invokerPortletConfigImpl =
688                         (PortletConfigImpl)invokerPortlet.getPortletConfig();
689 
690                     if (invokerPortlet.isStrutsPortlet() ||
691                         ((invokerPortletConfigImpl != null) &&
692                          (!invokerPortletConfigImpl.isWARFile()))) {
693 
694                         uploadRequest = new UploadServletRequestImpl(request);
695 
696                         request = uploadRequest;
697                     }
698                 }
699 
700                 ActionRequestImpl actionRequestImpl =
701                     ActionRequestFactory.create(
702                         request, portlet, invokerPortlet, portletContext,
703                         windowState, portletMode, portletPreferences,
704                         layout.getPlid());
705 
706                 ActionResponseImpl actionResponseImpl =
707                     ActionResponseFactory.create(
708                         actionRequestImpl, response, portletId, user, layout,
709                         windowState, portletMode);
710 
711                 actionRequestImpl.defineObjects(
712                     portletConfig, actionResponseImpl);
713 
714                 invokerPortlet.processAction(
715                     actionRequestImpl, actionResponseImpl);
716 
717                 actionResponseImpl.transferHeaders(response);
718 
719                 RenderParametersPool.put(
720                     request, layout.getPlid(), portletId,
721                     actionResponseImpl.getRenderParameterMap());
722 
723                 List<LayoutTypePortlet> layoutTypePortlets = null;
724 
725                 if (!actionResponseImpl.getEvents().isEmpty()) {
726                     if (PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
727                         layoutTypePortlets = getLayoutTypePortlets(
728                             layout.getGroupId(), layout.isPrivateLayout());
729                     }
730                     else {
731                         if (layout.getType().equals(
732                                 LayoutConstants.TYPE_PORTLET)) {
733 
734                             LayoutTypePortlet layoutTypePortlet =
735                                 (LayoutTypePortlet)layout.getLayoutType();
736 
737                             layoutTypePortlets =
738                                 new ArrayList<LayoutTypePortlet>();
739 
740                             layoutTypePortlets.add(layoutTypePortlet);
741                         }
742                     }
743 
744                     processEvents(
745                         actionRequestImpl, actionResponseImpl,
746                         layoutTypePortlets);
747 
748                     actionRequestImpl.defineObjects(
749                         portletConfig, actionResponseImpl);
750                 }
751             }
752             finally {
753                 if (uploadRequest != null) {
754                     uploadRequest.cleanUp();
755                 }
756             }
757         }
758         else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
759                  lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
760 
761             PortalUtil.updateWindowState(
762                 portletId, user, layout, windowState, request);
763 
764             PortalUtil.updatePortletMode(
765                 portletId, user, layout, portletMode, request);
766         }
767 
768         if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
769             PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
770 
771             String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
772                 layout.getPlid(), portletId);
773 
774             portletDisplay.setId(portletId);
775             portletDisplay.setRootPortletId(portlet.getRootPortletId());
776             portletDisplay.setInstanceId(portlet.getInstanceId());
777             portletDisplay.setResourcePK(portletPrimaryKey);
778             portletDisplay.setPortletName(portletConfig.getPortletName());
779             portletDisplay.setNamespace(
780                 PortalUtil.getPortletNamespace(portletId));
781 
782             ResourceRequestImpl resourceRequestImpl =
783                 ResourceRequestFactory.create(
784                     request, portlet, invokerPortlet, portletContext,
785                     windowState, portletMode, portletPreferences,
786                     layout.getPlid());
787 
788             ResourceResponseImpl resourceResponseImpl =
789                 ResourceResponseFactory.create(
790                     resourceRequestImpl, response, portletId, companyId);
791 
792             resourceRequestImpl.defineObjects(
793                 portletConfig, resourceResponseImpl);
794 
795             invokerPortlet.serveResource(
796                 resourceRequestImpl, resourceResponseImpl);
797         }
798 
799         return portlet;
800     }
801 
802     protected void processPublicRenderParameters(
803         HttpServletRequest request, Layout layout, Portlet portlet) {
804 
805         Map<String, String[]> publicRenderParameters =
806             PublicRenderParametersPool.get(request, layout.getPlid());
807 
808         Enumeration<String> enu = request.getParameterNames();
809 
810         while (enu.hasMoreElements()) {
811             String name = enu.nextElement();
812 
813             String[] values = request.getParameterValues(name);
814 
815             QName qName = PortletQNameUtil.getQName(name);
816 
817             if (qName == null) {
818                 continue;
819             }
820 
821             PublicRenderParameter publicRenderParameter =
822                 portlet.getPublicRenderParameter(
823                     qName.getNamespaceURI(), qName.getLocalPart());
824 
825             if (publicRenderParameter == null) {
826                 continue;
827             }
828 
829             if (name.startsWith(
830                     PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
831 
832                 publicRenderParameters.put(
833                     PortletQNameUtil.getKey(qName), values);
834             }
835             else {
836                 publicRenderParameters.remove(PortletQNameUtil.getKey(qName));
837             }
838         }
839     }
840 
841     protected void redirectActionURL(
842             HttpServletRequest request, HttpServletResponse response,
843             ActionResponseImpl actionResponseImpl, Portlet portlet)
844         throws Exception {
845 
846         ActionRequestImpl actionRequestImpl =
847             (ActionRequestImpl)request.getAttribute(
848                 JavaConstants.JAVAX_PORTLET_REQUEST);
849 
850         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
851 
852         PortletURL portletURL = new PortletURLImpl(
853             actionRequestImpl, actionRequestImpl.getPortletName(),
854             layout.getLayoutId(), PortletRequest.RENDER_PHASE);
855 
856         Map<String, String[]> renderParameters =
857             actionResponseImpl.getRenderParameterMap();
858 
859         for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
860             String key = entry.getKey();
861             String[] value = entry.getValue();
862 
863             portletURL.setParameter(key, value);
864         }
865 
866         response.sendRedirect(portletURL.toString());
867     }
868 
869     protected void renderExclusive(
870             HttpServletRequest request, HttpServletResponse response,
871             ThemeDisplay themeDisplay)
872         throws Exception {
873 
874         RenderRequestImpl renderRequestImpl =
875             (RenderRequestImpl)request.getAttribute(
876                 JavaConstants.JAVAX_PORTLET_REQUEST);
877 
878         RenderResponseImpl renderResponseImpl =
879             (RenderResponseImpl)request.getAttribute(
880                 JavaConstants.JAVAX_PORTLET_RESPONSE);
881 
882         StringServletResponse stringResponse =
883             (StringServletResponse)renderRequestImpl.getAttribute(
884                 WebKeys.STRING_SERVLET_RESPONSE);
885 
886         renderResponseImpl.transferHeaders(response);
887 
888         if (stringResponse.isCalledGetOutputStream()) {
889             InputStream is = new UnsyncByteArrayInputStream(
890                 stringResponse.getUnsyncByteArrayOutputStream().toByteArray());
891 
892             ServletResponseUtil.sendFile(
893                 response, renderResponseImpl.getResourceName(), is,
894                 renderResponseImpl.getContentType());
895         }
896         else {
897             byte[] content = stringResponse.getString().getBytes(
898                 StringPool.UTF8);
899 
900             ServletResponseUtil.sendFile(
901                 response, renderResponseImpl.getResourceName(), content,
902                 renderResponseImpl.getContentType());
903         }
904 
905         renderRequestImpl.cleanUp();
906     }
907 
908     private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
909 
910 }