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             if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
256                 forwardURL = HttpUtil.addParameter(
257                     forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
258             }
259 
260             if (Validator.isNotNull(themeDisplay.getDoAsUserLanguageId())) {
261                 forwardURL = HttpUtil.addParameter(
262                     forwardURL, "doAsUserLanguageId",
263                     themeDisplay.getDoAsUserLanguageId());
264             }
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                     MessageBusUtil.hasMessageListener(DestinationNames.AUDIT)) {
523 
524                     User user = themeDisplay.getUser();
525 
526                     AuditMessage auditMessage = new AuditMessage(
527                         ActionKeys.VIEW, user.getCompanyId(), user.getUserId(),
528                         user.getFullName(), Layout.class.getName(),
529                         String.valueOf(layout.getPlid()));
530 
531                     AuditRouterUtil.route(auditMessage);
532                 }
533             }
534 
535             if (!PropsValues.TCK_URL && resetLayout &&
536                 (Validator.isNull(portletId) ||
537                  ((previousLayout != null) &&
538                   (layout.getPlid() != previousLayout.getPlid())))) {
539 
540                 // Always clear render parameters on a layout url, but do not
541                 // clear on portlet urls invoked on the same layout
542 
543                 RenderParametersPool.clear(request, plid);
544             }
545 
546             if (themeDisplay.isLifecycleAction()) {
547                 Portlet portlet = processPortletRequest(
548                     request, response, PortletRequest.ACTION_PHASE);
549 
550                 if (portlet != null) {
551                     ActionResponseImpl actionResponseImpl =
552                         (ActionResponseImpl)request.getAttribute(
553                             JavaConstants.JAVAX_PORTLET_RESPONSE);
554 
555                     String redirectLocation =
556                         actionResponseImpl.getRedirectLocation();
557 
558                     if (Validator.isNotNull(redirectLocation)) {
559                         response.sendRedirect(redirectLocation);
560 
561                         return null;
562                     }
563 
564                     if (portlet.isActionURLRedirect()) {
565                         redirectActionURL(
566                             request, response, actionResponseImpl, portlet);
567 
568                         return null;
569                     }
570                 }
571             }
572             else if (themeDisplay.isLifecycleRender()) {
573                 processPortletRequest(
574                     request, response, PortletRequest.RENDER_PHASE);
575             }
576 
577             if (themeDisplay.isLifecycleResource()) {
578                 processPortletRequest(
579                     request, response, PortletRequest.RESOURCE_PHASE);
580 
581                 return null;
582             }
583             else {
584                 if (response.isCommitted()) {
585                     return null;
586                 }
587 
588                 if (layout != null) {
589 
590                     // Include layout content before the page loads because
591                     // portlets on the page can set the page title and page
592                     // subtitle
593 
594                     includeLayoutContent(
595                         request, response, themeDisplay, layout);
596 
597                     if (themeDisplay.isStateExclusive()) {
598                         renderExclusive(request, response, themeDisplay);
599 
600                         return null;
601                     }
602                 }
603 
604                 return mapping.findForward("portal.layout");
605             }
606         }
607         catch (Exception e) {
608             PortalUtil.sendError(e, request, response);
609 
610             return null;
611         }
612         finally {
613             PortletRequest portletRequest =
614                 (PortletRequest)request.getAttribute(
615                     JavaConstants.JAVAX_PORTLET_REQUEST);
616 
617             if (portletRequest != null) {
618                 PortletRequestImpl portletRequestImpl =
619                     (PortletRequestImpl)portletRequest;
620 
621                 portletRequestImpl.cleanUp();
622             }
623         }
624     }
625 
626     protected Portlet processPortletRequest(
627             HttpServletRequest request, HttpServletResponse response,
628             String lifecycle)
629         throws Exception {
630 
631         HttpSession session = request.getSession();
632 
633         long companyId = PortalUtil.getCompanyId(request);
634         User user = PortalUtil.getUser(request);
635         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
636 
637         String portletId = ParamUtil.getString(request, "p_p_id");
638 
639         if (Validator.isNull(portletId)) {
640             return null;
641         }
642 
643         Portlet portlet = PortletLocalServiceUtil.getPortletById(
644             companyId, portletId);
645 
646         if (portlet == null) {
647             return null;
648         }
649 
650         ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
651             WebKeys.THEME_DISPLAY);
652 
653         themeDisplay.setScopeGroupId(
654             PortalUtil.getScopeGroupId(request, portletId));
655 
656         ServletContext servletContext = (ServletContext)request.getAttribute(
657             WebKeys.CTX);
658 
659         InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
660             portlet, servletContext);
661 
662         if (user != null) {
663             InvokerPortletImpl.clearResponse(
664                 session, layout.getPrimaryKey(), portletId,
665                 LanguageUtil.getLanguageId(request));
666         }
667 
668         PortletConfig portletConfig = PortletConfigFactory.create(
669             portlet, servletContext);
670         PortletContext portletContext = portletConfig.getPortletContext();
671 
672         WindowState windowState = WindowStateFactory.getWindowState(
673             ParamUtil.getString(request, "p_p_state"));
674 
675         PortletMode portletMode = PortletModeFactory.getPortletMode(
676             ParamUtil.getString(request, "p_p_mode"));
677 
678         PortletPreferencesIds portletPreferencesIds =
679             PortletPreferencesFactoryUtil.getPortletPreferencesIds(
680                 request, portletId);
681 
682         PortletPreferences portletPreferences =
683             PortletPreferencesLocalServiceUtil.getPreferences(
684                 portletPreferencesIds);
685 
686         processPublicRenderParameters(request, layout, portlet);
687 
688         if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
689             String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
690 
691             if (_log.isDebugEnabled()) {
692                 _log.debug("Content type " + contentType);
693             }
694 
695             UploadServletRequest uploadRequest = null;
696 
697             try {
698                 if ((contentType != null) &&
699                     (contentType.startsWith(
700                         ContentTypes.MULTIPART_FORM_DATA))) {
701 
702                     PortletConfigImpl invokerPortletConfigImpl =
703                         (PortletConfigImpl)invokerPortlet.getPortletConfig();
704 
705                     if (invokerPortlet.isStrutsPortlet() ||
706                         ((invokerPortletConfigImpl != null) &&
707                          (!invokerPortletConfigImpl.isWARFile()))) {
708 
709                         uploadRequest = new UploadServletRequestImpl(request);
710 
711                         request = uploadRequest;
712                     }
713                 }
714 
715                 if (PropsValues.AUTH_TOKEN_CHECK_ENABLED &&
716                     invokerPortlet.isCheckAuthToken()) {
717 
718                     AuthTokenUtil.check(request);
719                 }
720 
721                 ActionRequestImpl actionRequestImpl =
722                     ActionRequestFactory.create(
723                         request, portlet, invokerPortlet, portletContext,
724                         windowState, portletMode, portletPreferences,
725                         layout.getPlid());
726 
727                 ActionResponseImpl actionResponseImpl =
728                     ActionResponseFactory.create(
729                         actionRequestImpl, response, portletId, user, layout,
730                         windowState, portletMode);
731 
732                 actionRequestImpl.defineObjects(
733                     portletConfig, actionResponseImpl);
734 
735                 invokerPortlet.processAction(
736                     actionRequestImpl, actionResponseImpl);
737 
738                 actionResponseImpl.transferHeaders(response);
739 
740                 RenderParametersPool.put(
741                     request, layout.getPlid(), portletId,
742                     actionResponseImpl.getRenderParameterMap());
743 
744                 List<LayoutTypePortlet> layoutTypePortlets = null;
745 
746                 if (!actionResponseImpl.getEvents().isEmpty()) {
747                     if (PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
748                         layoutTypePortlets = getLayoutTypePortlets(
749                             layout.getGroupId(), layout.isPrivateLayout());
750                     }
751                     else {
752                         if (layout.isTypePortlet()) {
753                             LayoutTypePortlet layoutTypePortlet =
754                                 (LayoutTypePortlet)layout.getLayoutType();
755 
756                             layoutTypePortlets =
757                                 new ArrayList<LayoutTypePortlet>();
758 
759                             layoutTypePortlets.add(layoutTypePortlet);
760                         }
761                     }
762 
763                     processEvents(
764                         actionRequestImpl, actionResponseImpl,
765                         layoutTypePortlets);
766 
767                     actionRequestImpl.defineObjects(
768                         portletConfig, actionResponseImpl);
769                 }
770             }
771             finally {
772                 if (uploadRequest != null) {
773                     uploadRequest.cleanUp();
774                 }
775             }
776         }
777         else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
778                  lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
779 
780             PortalUtil.updateWindowState(
781                 portletId, user, layout, windowState, request);
782 
783             PortalUtil.updatePortletMode(
784                 portletId, user, layout, portletMode, request);
785         }
786 
787         if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
788             PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
789 
790             String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
791                 layout.getPlid(), portletId);
792 
793             portletDisplay.setId(portletId);
794             portletDisplay.setRootPortletId(portlet.getRootPortletId());
795             portletDisplay.setInstanceId(portlet.getInstanceId());
796             portletDisplay.setResourcePK(portletPrimaryKey);
797             portletDisplay.setPortletName(portletConfig.getPortletName());
798             portletDisplay.setNamespace(
799                 PortalUtil.getPortletNamespace(portletId));
800 
801             ResourceRequestImpl resourceRequestImpl =
802                 ResourceRequestFactory.create(
803                     request, portlet, invokerPortlet, portletContext,
804                     windowState, portletMode, portletPreferences,
805                     layout.getPlid());
806 
807             ResourceResponseImpl resourceResponseImpl =
808                 ResourceResponseFactory.create(
809                     resourceRequestImpl, response, portletId, companyId);
810 
811             resourceRequestImpl.defineObjects(
812                 portletConfig, resourceResponseImpl);
813 
814             invokerPortlet.serveResource(
815                 resourceRequestImpl, resourceResponseImpl);
816         }
817 
818         return portlet;
819     }
820 
821     protected void processPublicRenderParameters(
822         HttpServletRequest request, Layout layout, Portlet portlet) {
823 
824         Map<String, String[]> publicRenderParameters =
825             PublicRenderParametersPool.get(request, layout.getPlid());
826 
827         Enumeration<String> enu = request.getParameterNames();
828 
829         while (enu.hasMoreElements()) {
830             String name = enu.nextElement();
831 
832             String[] values = request.getParameterValues(name);
833 
834             QName qName = PortletQNameUtil.getQName(name);
835 
836             if (qName == null) {
837                 continue;
838             }
839 
840             PublicRenderParameter publicRenderParameter =
841                 portlet.getPublicRenderParameter(
842                     qName.getNamespaceURI(), qName.getLocalPart());
843 
844             if (publicRenderParameter == null) {
845                 continue;
846             }
847 
848             if (name.startsWith(
849                     PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
850 
851                 publicRenderParameters.put(
852                     PortletQNameUtil.getKey(qName), values);
853             }
854             else {
855                 publicRenderParameters.remove(PortletQNameUtil.getKey(qName));
856             }
857         }
858     }
859 
860     protected void redirectActionURL(
861             HttpServletRequest request, HttpServletResponse response,
862             ActionResponseImpl actionResponseImpl, Portlet portlet)
863         throws Exception {
864 
865         ActionRequestImpl actionRequestImpl =
866             (ActionRequestImpl)request.getAttribute(
867                 JavaConstants.JAVAX_PORTLET_REQUEST);
868 
869         Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
870 
871         PortletURL portletURL = new PortletURLImpl(
872             actionRequestImpl, actionRequestImpl.getPortletName(),
873             layout.getLayoutId(), PortletRequest.RENDER_PHASE);
874 
875         Map<String, String[]> renderParameters =
876             actionResponseImpl.getRenderParameterMap();
877 
878         for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
879             String key = entry.getKey();
880             String[] value = entry.getValue();
881 
882             portletURL.setParameter(key, value);
883         }
884 
885         response.sendRedirect(portletURL.toString());
886     }
887 
888     protected void renderExclusive(
889             HttpServletRequest request, HttpServletResponse response,
890             ThemeDisplay themeDisplay)
891         throws Exception {
892 
893         RenderRequestImpl renderRequestImpl =
894             (RenderRequestImpl)request.getAttribute(
895                 JavaConstants.JAVAX_PORTLET_REQUEST);
896 
897         RenderResponseImpl renderResponseImpl =
898             (RenderResponseImpl)request.getAttribute(
899                 JavaConstants.JAVAX_PORTLET_RESPONSE);
900 
901         StringServletResponse stringResponse =
902             (StringServletResponse)renderRequestImpl.getAttribute(
903                 WebKeys.STRING_SERVLET_RESPONSE);
904 
905         renderResponseImpl.transferHeaders(response);
906 
907         if (stringResponse.isCalledGetOutputStream()) {
908             UnsyncByteArrayOutputStream ubaos =
909                 stringResponse.getUnsyncByteArrayOutputStream();
910 
911             InputStream is = new UnsyncByteArrayInputStream(
912                 ubaos.unsafeGetByteArray(), 0, ubaos.size());
913 
914             ServletResponseUtil.sendFile(
915                 request, response, renderResponseImpl.getResourceName(), is,
916                 renderResponseImpl.getContentType());
917         }
918         else {
919             byte[] content = stringResponse.getString().getBytes(
920                 StringPool.UTF8);
921 
922             ServletResponseUtil.sendFile(
923                 request, response, renderResponseImpl.getResourceName(),
924                 content, renderResponseImpl.getContentType());
925         }
926 
927         renderRequestImpl.cleanUp();
928     }
929 
930     protected Event serializeEvent(
931         Event event, ClassLoader portletClassLoader) {
932 
933         Serializable value = event.getValue();
934 
935         if (value == null) {
936             return event;
937         }
938 
939         ClassLoader eventClassLoader = value.getClass().getClassLoader();
940 
941         if (portletClassLoader == eventClassLoader) {
942             return event;
943         }
944 
945         EventImpl eventImpl = (EventImpl)event;
946 
947         String base64Value = eventImpl.getBase64Value();
948 
949         value = (Serializable)Base64.stringToObject(
950             base64Value, portletClassLoader);
951 
952         return new EventImpl(event.getName(), event.getQName(), value);
953     }
954 
955     private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
956 
957 }