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