001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portal.action;
016    
017    import com.liferay.portal.kernel.audit.AuditMessage;
018    import com.liferay.portal.kernel.audit.AuditRouterUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
023    import com.liferay.portal.kernel.io.unsync.UnsyncStringWriter;
024    import com.liferay.portal.kernel.language.LanguageUtil;
025    import com.liferay.portal.kernel.log.Log;
026    import com.liferay.portal.kernel.log.LogFactoryUtil;
027    import com.liferay.portal.kernel.messaging.DestinationNames;
028    import com.liferay.portal.kernel.messaging.MessageBusUtil;
029    import com.liferay.portal.kernel.portlet.LiferayPortletMode;
030    import com.liferay.portal.kernel.portlet.PortletModeFactory;
031    import com.liferay.portal.kernel.portlet.WindowStateFactory;
032    import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
033    import com.liferay.portal.kernel.servlet.HeaderCacheServletResponse;
034    import com.liferay.portal.kernel.servlet.HttpHeaders;
035    import com.liferay.portal.kernel.servlet.PipingServletResponse;
036    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
037    import com.liferay.portal.kernel.servlet.StringServletResponse;
038    import com.liferay.portal.kernel.upload.UploadServletRequest;
039    import com.liferay.portal.kernel.util.ArrayUtil;
040    import com.liferay.portal.kernel.util.Base64;
041    import com.liferay.portal.kernel.util.ContentTypes;
042    import com.liferay.portal.kernel.util.HttpUtil;
043    import com.liferay.portal.kernel.util.JavaConstants;
044    import com.liferay.portal.kernel.util.MapUtil;
045    import com.liferay.portal.kernel.util.ParamUtil;
046    import com.liferay.portal.kernel.util.PropsKeys;
047    import com.liferay.portal.kernel.util.ServerDetector;
048    import com.liferay.portal.kernel.util.StringPool;
049    import com.liferay.portal.kernel.util.Validator;
050    import com.liferay.portal.kernel.webdav.WebDAVStorage;
051    import com.liferay.portal.kernel.xml.QName;
052    import com.liferay.portal.model.Layout;
053    import com.liferay.portal.model.LayoutConstants;
054    import com.liferay.portal.model.LayoutTypePortlet;
055    import com.liferay.portal.model.Portlet;
056    import com.liferay.portal.model.PortletPreferencesIds;
057    import com.liferay.portal.model.PublicRenderParameter;
058    import com.liferay.portal.model.User;
059    import com.liferay.portal.security.auth.AuthTokenUtil;
060    import com.liferay.portal.security.permission.ActionKeys;
061    import com.liferay.portal.service.LayoutLocalServiceUtil;
062    import com.liferay.portal.service.PortletLocalServiceUtil;
063    import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
064    import com.liferay.portal.service.ServiceContext;
065    import com.liferay.portal.service.ServiceContextFactory;
066    import com.liferay.portal.service.ServiceContextThreadLocal;
067    import com.liferay.portal.service.permission.PortletPermissionUtil;
068    import com.liferay.portal.struts.ActionConstants;
069    import com.liferay.portal.struts.StrutsUtil;
070    import com.liferay.portal.theme.PortletDisplay;
071    import com.liferay.portal.theme.ThemeDisplay;
072    import com.liferay.portal.upload.UploadServletRequestImpl;
073    import com.liferay.portal.util.PortalUtil;
074    import com.liferay.portal.util.PrefsPropsUtil;
075    import com.liferay.portal.util.PropsValues;
076    import com.liferay.portal.util.WebKeys;
077    import com.liferay.portlet.ActionRequestFactory;
078    import com.liferay.portlet.ActionRequestImpl;
079    import com.liferay.portlet.ActionResponseFactory;
080    import com.liferay.portlet.ActionResponseImpl;
081    import com.liferay.portlet.EventImpl;
082    import com.liferay.portlet.EventRequestFactory;
083    import com.liferay.portlet.EventRequestImpl;
084    import com.liferay.portlet.EventResponseFactory;
085    import com.liferay.portlet.EventResponseImpl;
086    import com.liferay.portlet.InvokerPortlet;
087    import com.liferay.portlet.InvokerPortletImpl;
088    import com.liferay.portlet.PortletConfigFactoryUtil;
089    import com.liferay.portlet.PortletConfigImpl;
090    import com.liferay.portlet.PortletInstanceFactoryUtil;
091    import com.liferay.portlet.PortletPreferencesFactoryUtil;
092    import com.liferay.portlet.PortletQName;
093    import com.liferay.portlet.PortletQNameUtil;
094    import com.liferay.portlet.PortletRequestImpl;
095    import com.liferay.portlet.PortletURLImpl;
096    import com.liferay.portlet.PublicRenderParametersPool;
097    import com.liferay.portlet.RenderParametersPool;
098    import com.liferay.portlet.RenderRequestImpl;
099    import com.liferay.portlet.RenderResponseImpl;
100    import com.liferay.portlet.ResourceRequestFactory;
101    import com.liferay.portlet.ResourceRequestImpl;
102    import com.liferay.portlet.ResourceResponseFactory;
103    import com.liferay.portlet.ResourceResponseImpl;
104    import com.liferay.portlet.StateAwareResponseImpl;
105    import com.liferay.portlet.login.util.LoginUtil;
106    import com.liferay.util.servlet.filters.CacheResponseUtil;
107    
108    import java.io.InputStream;
109    import java.io.Serializable;
110    
111    import java.util.ArrayList;
112    import java.util.Enumeration;
113    import java.util.HashMap;
114    import java.util.List;
115    import java.util.Map;
116    
117    import javax.portlet.Event;
118    import javax.portlet.PortletConfig;
119    import javax.portlet.PortletContext;
120    import javax.portlet.PortletMode;
121    import javax.portlet.PortletPreferences;
122    import javax.portlet.PortletRequest;
123    import javax.portlet.PortletURL;
124    import javax.portlet.UnavailableException;
125    import javax.portlet.WindowState;
126    
127    import javax.servlet.RequestDispatcher;
128    import javax.servlet.ServletContext;
129    import javax.servlet.http.HttpServletRequest;
130    import javax.servlet.http.HttpServletResponse;
131    import javax.servlet.http.HttpSession;
132    
133    import org.apache.struts.action.Action;
134    import org.apache.struts.action.ActionForm;
135    import org.apache.struts.action.ActionForward;
136    import org.apache.struts.action.ActionMapping;
137    
138    /**
139     * @author Brian Wing Shun Chan
140     */
141    public class LayoutAction extends Action {
142    
143            @Override
144            public ActionForward execute(
145                            ActionMapping mapping, ActionForm form, HttpServletRequest request,
146                            HttpServletResponse response)
147                    throws Exception {
148    
149                    HeaderCacheServletResponse headerCacheServletResponse = null;
150    
151                    if (response instanceof HeaderCacheServletResponse) {
152                            headerCacheServletResponse = (HeaderCacheServletResponse)response;
153                    }
154                    else {
155                            headerCacheServletResponse = new HeaderCacheServletResponse(
156                                    response);
157                    }
158    
159                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
160                            WebKeys.THEME_DISPLAY);
161    
162                    Layout layout = themeDisplay.getLayout();
163    
164                    Boolean layoutDefault = (Boolean)request.getAttribute(
165                            WebKeys.LAYOUT_DEFAULT);
166    
167                    if ((layoutDefault != null) && (layoutDefault.booleanValue())) {
168                            Layout requestedLayout = (Layout)request.getAttribute(
169                                    WebKeys.REQUESTED_LAYOUT);
170    
171                            if (requestedLayout != null) {
172                                    String redirectParam = "redirect";
173    
174                                    if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME)) {
175                                            redirectParam =
176                                                    PortalUtil.getPortletNamespace(
177                                                            PropsValues.AUTH_LOGIN_PORTLET_NAME) +
178                                                    redirectParam;
179                                    }
180    
181                                    String authLoginURL = null;
182    
183                                    if (PrefsPropsUtil.getBoolean(
184                                                    themeDisplay.getCompanyId(), PropsKeys.CAS_AUTH_ENABLED,
185                                                    PropsValues.CAS_AUTH_ENABLED) ||
186                                            PrefsPropsUtil.getBoolean(
187                                                    themeDisplay.getCompanyId(),
188                                                    PropsKeys.OPEN_SSO_AUTH_ENABLED,
189                                                    PropsValues.OPEN_SSO_AUTH_ENABLED)) {
190    
191                                            authLoginURL = themeDisplay.getURLSignIn();
192                                    }
193    
194                                    if (Validator.isNull(authLoginURL)) {
195                                            authLoginURL = PortalUtil.getSiteLoginURL(themeDisplay);
196                                    }
197    
198                                    if (Validator.isNull(authLoginURL)) {
199                                            authLoginURL = PropsValues.AUTH_LOGIN_URL;
200                                    }
201    
202                                    if (Validator.isNull(authLoginURL)) {
203                                            PortletURL loginURL = LoginUtil.getLoginURL(
204                                                    request, themeDisplay.getPlid());
205    
206                                            authLoginURL = loginURL.toString();
207                                    }
208    
209                                    authLoginURL = HttpUtil.setParameter(
210                                            authLoginURL, "p_p_id",
211                                            PropsValues.AUTH_LOGIN_PORTLET_NAME);
212    
213                                    String currentURL = PortalUtil.getCurrentURL(request);
214    
215                                    authLoginURL = HttpUtil.setParameter(
216                                            authLoginURL, redirectParam, currentURL);
217    
218                                    if (_log.isDebugEnabled()) {
219                                            _log.debug("Redirect requested layout to " + authLoginURL);
220                                    }
221    
222                                    headerCacheServletResponse.sendRedirect(authLoginURL);
223                            }
224                            else {
225                                    String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
226    
227                                    if (_log.isDebugEnabled()) {
228                                            _log.debug("Redirect default layout to " + redirect);
229                                    }
230    
231                                    headerCacheServletResponse.sendRedirect(redirect);
232                            }
233    
234                            return null;
235                    }
236    
237                    long plid = ParamUtil.getLong(request, "p_l_id");
238    
239                    if (_log.isDebugEnabled()) {
240                            _log.debug("p_l_id is " + plid);
241                    }
242    
243                    if (plid > 0) {
244                            ActionForward actionForward = processLayout(
245                                    mapping, request, headerCacheServletResponse, plid);
246    
247                            String contentType = response.getContentType();
248    
249                            CacheResponseUtil.setHeaders(
250                                    response, headerCacheServletResponse.getHeaders());
251    
252                            if (contentType != null) {
253                                    response.setContentType(contentType);
254                            }
255    
256                            return actionForward;
257                    }
258                    else {
259                            try {
260                                    forwardLayout(request);
261    
262                                    return mapping.findForward(ActionConstants.COMMON_FORWARD_JSP);
263                            }
264                            catch (Exception e) {
265                                    PortalUtil.sendError(e, request, headerCacheServletResponse);
266    
267                                    CacheResponseUtil.setHeaders(
268                                            response, headerCacheServletResponse.getHeaders());
269    
270                                    return null;
271                            }
272                    }
273            }
274    
275            protected void forwardLayout(HttpServletRequest request) throws Exception {
276                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
277    
278                    long plid = LayoutConstants.DEFAULT_PLID;
279    
280                    String layoutFriendlyURL = null;
281    
282                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
283                            WebKeys.THEME_DISPLAY);
284    
285                    if (layout != null) {
286                            plid = layout.getPlid();
287    
288                            layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
289                                    layout, themeDisplay);
290                    }
291    
292                    String forwardURL = layoutFriendlyURL;
293    
294                    if (Validator.isNull(forwardURL)) {
295                            forwardURL =
296                                    themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
297                    }
298    
299                    if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
300                            forwardURL = HttpUtil.addParameter(
301                                    forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
302                    }
303    
304                    if (Validator.isNotNull(themeDisplay.getDoAsUserLanguageId())) {
305                            forwardURL = HttpUtil.addParameter(
306                                    forwardURL, "doAsUserLanguageId",
307                                    themeDisplay.getDoAsUserLanguageId());
308                    }
309    
310                    if (_log.isDebugEnabled()) {
311                            _log.debug("Forward layout to " + forwardURL);
312                    }
313    
314                    request.setAttribute(WebKeys.FORWARD_URL, forwardURL);
315            }
316    
317            protected List<LayoutTypePortlet> getLayoutTypePortlets(
318                            long groupId, boolean privateLayout)
319                    throws Exception {
320    
321                    List<LayoutTypePortlet> layoutTypePortlets =
322                            new ArrayList<LayoutTypePortlet>();
323    
324                    List<Layout> layouts = LayoutLocalServiceUtil.getLayouts(
325                            groupId, privateLayout, LayoutConstants.TYPE_PORTLET);
326    
327                    for (Layout layout : layouts) {
328                            if (!layout.isTypePortlet()) {
329                                    continue;
330                            }
331    
332                            LayoutTypePortlet layoutTypePortlet =
333                                    (LayoutTypePortlet)layout.getLayoutType();
334    
335                            layoutTypePortlets.add(layoutTypePortlet);
336                    }
337    
338                    return layoutTypePortlets;
339            }
340    
341            protected long getScopeGroupId(
342                            HttpServletRequest request, LayoutTypePortlet layoutTypePortlet,
343                            String portletId)
344                    throws PortalException, SystemException {
345    
346                    long scopeGroupId = 0;
347    
348                    Layout layoutTypePortletLayout = layoutTypePortlet.getLayout();
349    
350                    Layout requestLayout = (Layout)request.getAttribute(WebKeys.LAYOUT);
351    
352                    try {
353                            request.setAttribute(WebKeys.LAYOUT, layoutTypePortletLayout);
354    
355                            scopeGroupId = PortalUtil.getScopeGroupId(request, portletId);
356                    }
357                    finally {
358                            request.setAttribute(WebKeys.LAYOUT, requestLayout);
359                    }
360    
361                    if (scopeGroupId <= 0) {
362                            scopeGroupId = PortalUtil.getScopeGroupId(
363                                    layoutTypePortletLayout, portletId);
364                    }
365    
366                    return scopeGroupId;
367            }
368    
369            protected void includeLayoutContent(
370                            HttpServletRequest request, HttpServletResponse response,
371                            ThemeDisplay themeDisplay, Layout layout)
372                    throws Exception {
373    
374                    ServletContext servletContext = (ServletContext)request.getAttribute(
375                            WebKeys.CTX);
376    
377                    String path = StrutsUtil.TEXT_HTML_DIR;
378    
379                    if (BrowserSnifferUtil.isWap(request)) {
380                            path = StrutsUtil.TEXT_WAP_DIR;
381                    }
382    
383                    // Manually check the p_p_id. See LEP-1724.
384    
385                    if (themeDisplay.isStateExclusive() ||
386                            Validator.isNotNull(ParamUtil.getString(request, "p_p_id"))) {
387    
388                            if (layout.isTypePanel()) {
389                                    path += "/portal/layout/view/panel.jsp";
390                            }
391                            else if (layout.isTypeControlPanel()) {
392                                    path += "/portal/layout/view/control_panel.jsp";
393                            }
394                            else {
395                                    path += "/portal/layout/view/portlet.jsp";
396                            }
397                    }
398                    else {
399                            path += PortalUtil.getLayoutViewPage(layout);
400                    }
401    
402                    RequestDispatcher requestDispatcher =
403                            servletContext.getRequestDispatcher(path);
404    
405                    UnsyncStringWriter unsyncStringWriter = new UnsyncStringWriter();
406    
407                    PipingServletResponse pipingServletResponse = new PipingServletResponse(
408                            response, unsyncStringWriter);
409    
410                    String contentType = pipingServletResponse.getContentType();
411    
412                    requestDispatcher.include(request, pipingServletResponse);
413    
414                    if (contentType != null) {
415                            pipingServletResponse.setContentType(contentType);
416                    }
417    
418                    request.setAttribute(
419                            WebKeys.LAYOUT_CONTENT, unsyncStringWriter.getStringBundler());
420            }
421    
422            protected void processEvent(
423                            PortletRequestImpl portletRequestImpl,
424                            StateAwareResponseImpl stateAwareResponseImpl,
425                            List<LayoutTypePortlet> layoutTypePortlets,
426                            LayoutTypePortlet layoutTypePortlet, Portlet portlet, Event event)
427                    throws Exception {
428    
429                    HttpServletRequest request = portletRequestImpl.getHttpServletRequest();
430                    HttpServletResponse response =
431                            stateAwareResponseImpl.getHttpServletResponse();
432                    HttpSession session = request.getSession();
433    
434                    String portletId = portlet.getPortletId();
435    
436                    ServletContext servletContext =
437                            (ServletContext)request.getAttribute(WebKeys.CTX);
438    
439                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
440                            portlet, servletContext);
441    
442                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
443                            portlet, servletContext);
444                    PortletContext portletContext = portletConfig.getPortletContext();
445    
446                    WindowState windowState = null;
447    
448                    if (layoutTypePortlet.hasStateMaxPortletId(portletId)) {
449                            windowState = WindowState.MAXIMIZED;
450                    }
451                    else if (layoutTypePortlet.hasStateMinPortletId(portletId)) {
452                            windowState = WindowState.MINIMIZED;
453                    }
454                    else {
455                            windowState = WindowState.NORMAL;
456                    }
457    
458                    PortletMode portletMode = null;
459    
460                    if (layoutTypePortlet.hasModeAboutPortletId(portletId)) {
461                            portletMode = LiferayPortletMode.ABOUT;
462                    }
463                    else if (layoutTypePortlet.hasModeConfigPortletId(portletId)) {
464                            portletMode = LiferayPortletMode.CONFIG;
465                    }
466                    else if (layoutTypePortlet.hasModeEditPortletId(portletId)) {
467                            portletMode = PortletMode.EDIT;
468                    }
469                    else if (layoutTypePortlet.hasModeEditDefaultsPortletId(portletId)) {
470                            portletMode = LiferayPortletMode.EDIT_DEFAULTS;
471                    }
472                    else if (layoutTypePortlet.hasModeEditGuestPortletId(portletId)) {
473                            portletMode = LiferayPortletMode.EDIT_GUEST;
474                    }
475                    else if (layoutTypePortlet.hasModeHelpPortletId(portletId)) {
476                            portletMode = PortletMode.HELP;
477                    }
478                    else if (layoutTypePortlet.hasModePreviewPortletId(portletId)) {
479                            portletMode = LiferayPortletMode.PREVIEW;
480                    }
481                    else if (layoutTypePortlet.hasModePrintPortletId(portletId)) {
482                            portletMode = LiferayPortletMode.PRINT;
483                    }
484                    else {
485                            portletMode = PortletMode.VIEW;
486                    }
487    
488                    long scopeGroupId = getScopeGroupId(
489                            request, layoutTypePortlet, portletId);
490    
491                    Layout layoutTypePortletLayout = layoutTypePortlet.getLayout();
492    
493                    PortletPreferences portletPreferences =
494                            PortletPreferencesFactoryUtil.getPortletSetup(
495                                    scopeGroupId, layoutTypePortletLayout, portletId, null);
496    
497                    EventRequestImpl eventRequestImpl = EventRequestFactory.create(
498                            request, portlet, invokerPortlet, portletContext, windowState,
499                            portletMode, portletPreferences, layoutTypePortletLayout.getPlid());
500    
501                    eventRequestImpl.setEvent(
502                            serializeEvent(event, invokerPortlet.getPortletClassLoader()));
503    
504                    Layout layout = stateAwareResponseImpl.getLayout();
505    
506                    EventResponseImpl eventResponseImpl = EventResponseFactory.create(
507                            eventRequestImpl, response, portletId,
508                            stateAwareResponseImpl.getUser(), layout);
509    
510                    eventRequestImpl.defineObjects(portletConfig, eventResponseImpl);
511    
512                    try {
513                            try {
514                                    InvokerPortletImpl.clearResponse(
515                                            session, layout.getPrimaryKey(), portletId,
516                                            LanguageUtil.getLanguageId(eventRequestImpl));
517    
518                                    invokerPortlet.processEvent(
519                                            eventRequestImpl, eventResponseImpl);
520    
521                                    if (eventResponseImpl.isCalledSetRenderParameter()) {
522                                            Map<String, String[]> renderParameterMap =
523                                                    new HashMap<String, String[]>();
524    
525                                            MapUtil.copy(
526                                                    eventResponseImpl.getRenderParameterMap(),
527                                                    renderParameterMap);
528    
529                                            RenderParametersPool.put(
530                                                    request, layout.getPlid(), portletId,
531                                                    renderParameterMap);
532                                    }
533                            }
534                            catch (UnavailableException ue) {
535                                    throw ue;
536                            }
537    
538                            processEvents(
539                                    eventRequestImpl, eventResponseImpl, layoutTypePortlets);
540                    }
541                    finally {
542                            eventRequestImpl.cleanUp();
543                    }
544            }
545    
546            protected void processEvents(
547                            PortletRequestImpl portletRequestImpl,
548                            StateAwareResponseImpl stateAwareResponseImpl,
549                            List<LayoutTypePortlet> layoutTypePortlets)
550                    throws Exception {
551    
552                    List<Event> events = stateAwareResponseImpl.getEvents();
553    
554                    if (events.size() == 0) {
555                            return;
556                    }
557    
558                    for (Event event : events) {
559                            javax.xml.namespace.QName qName = event.getQName();
560    
561                            for (LayoutTypePortlet layoutTypePortlet : layoutTypePortlets) {
562                                    List<Portlet> portlets = layoutTypePortlet.getAllPortlets();
563    
564                                    for (Portlet portlet : portlets) {
565                                            QName processingQName = portlet.getProcessingEvent(
566                                                    qName.getNamespaceURI(), qName.getLocalPart());
567    
568                                            if (processingQName != null) {
569                                                    processEvent(
570                                                            portletRequestImpl, stateAwareResponseImpl,
571                                                            layoutTypePortlets, layoutTypePortlet, portlet,
572                                                            event);
573                                            }
574                                    }
575                            }
576                    }
577            }
578    
579            protected ActionForward processLayout(
580                            ActionMapping mapping, HttpServletRequest request,
581                            HttpServletResponse response, long plid)
582                    throws Exception {
583    
584                    HttpSession session = request.getSession();
585    
586                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
587                            WebKeys.THEME_DISPLAY);
588    
589                    try {
590                            Layout layout = themeDisplay.getLayout();
591    
592                            boolean resetLayout = ParamUtil.getBoolean(
593                                    request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
594    
595                            String portletId = ParamUtil.getString(request, "p_p_id");
596    
597                            Layout previousLayout = (Layout)session.getAttribute(
598                                    WebKeys.PREVIOUS_LAYOUT);
599    
600                            if ((previousLayout == null) ||
601                                    (layout.getPlid() != previousLayout.getPlid())) {
602    
603                                    session.setAttribute(WebKeys.PREVIOUS_LAYOUT, layout);
604    
605                                    if (themeDisplay.isSignedIn() &&
606                                            PropsValues.
607                                                    AUDIT_MESSAGE_COM_LIFERAY_PORTAL_MODEL_LAYOUT_VIEW &&
608                                            MessageBusUtil.hasMessageListener(DestinationNames.AUDIT)) {
609    
610                                            User user = themeDisplay.getUser();
611    
612                                            AuditMessage auditMessage = new AuditMessage(
613                                                    ActionKeys.VIEW, user.getCompanyId(), user.getUserId(),
614                                                    user.getFullName(), Layout.class.getName(),
615                                                    String.valueOf(layout.getPlid()));
616    
617                                            AuditRouterUtil.route(auditMessage);
618                                    }
619                            }
620    
621                            if (!PropsValues.TCK_URL && resetLayout &&
622                                    (Validator.isNull(portletId) ||
623                                     ((previousLayout != null) &&
624                                      (layout.getPlid() != previousLayout.getPlid())))) {
625    
626                                    // Always clear render parameters on a layout url, but do not
627                                    // clear on portlet urls invoked on the same layout
628    
629                                    RenderParametersPool.clear(request, plid);
630                            }
631    
632                            if (themeDisplay.isLifecycleAction()) {
633                                    Portlet portlet = processPortletRequest(
634                                            request, response, PortletRequest.ACTION_PHASE);
635    
636                                    if (portlet != null) {
637                                            ActionResponseImpl actionResponseImpl =
638                                                    (ActionResponseImpl)request.getAttribute(
639                                                            JavaConstants.JAVAX_PORTLET_RESPONSE);
640    
641                                            String redirectLocation =
642                                                    actionResponseImpl.getRedirectLocation();
643    
644                                            if (Validator.isNotNull(redirectLocation)) {
645                                                    response.sendRedirect(redirectLocation);
646    
647                                                    return null;
648                                            }
649    
650                                            if (portlet.isActionURLRedirect()) {
651                                                    redirectActionURL(
652                                                            request, response, actionResponseImpl, portlet);
653    
654                                                    return null;
655                                            }
656                                    }
657                            }
658                            else if (themeDisplay.isLifecycleRender()) {
659                                    processPortletRequest(
660                                            request, response, PortletRequest.RENDER_PHASE);
661                            }
662    
663                            if (themeDisplay.isLifecycleResource()) {
664                                    processPortletRequest(
665                                            request, response, PortletRequest.RESOURCE_PHASE);
666    
667                                    return null;
668                            }
669                            else {
670                                    if (response.isCommitted()) {
671                                            return null;
672                                    }
673    
674                                    if (layout != null) {
675    
676                                            // Include layout content before the page loads because
677                                            // portlets on the page can set the page title and page
678                                            // subtitle
679    
680                                            includeLayoutContent(
681                                                    request, response, themeDisplay, layout);
682    
683                                            if (themeDisplay.isStateExclusive()) {
684                                                    renderExclusive(request, response, themeDisplay);
685    
686                                                    return null;
687                                            }
688                                    }
689    
690                                    return mapping.findForward("portal.layout");
691                            }
692                    }
693                    catch (Exception e) {
694                            PortalUtil.sendError(e, request, response);
695    
696                            return null;
697                    }
698                    finally {
699                            if (!ServerDetector.isResin()) {
700                                    PortletRequest portletRequest =
701                                            (PortletRequest)request.getAttribute(
702                                                    JavaConstants.JAVAX_PORTLET_REQUEST);
703    
704                                    if (portletRequest != null) {
705                                            PortletRequestImpl portletRequestImpl =
706                                                    (PortletRequestImpl)portletRequest;
707    
708                                            portletRequestImpl.cleanUp();
709                                    }
710                            }
711                    }
712            }
713    
714            protected Portlet processPortletRequest(
715                            HttpServletRequest request, HttpServletResponse response,
716                            String lifecycle)
717                    throws Exception {
718    
719                    HttpSession session = request.getSession();
720    
721                    long companyId = PortalUtil.getCompanyId(request);
722                    User user = PortalUtil.getUser(request);
723                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
724    
725                    String portletId = ParamUtil.getString(request, "p_p_id");
726    
727                    if (Validator.isNull(portletId)) {
728                            return null;
729                    }
730    
731                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
732                            companyId, portletId);
733    
734                    if (portlet == null) {
735                            return null;
736                    }
737    
738                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
739                            WebKeys.THEME_DISPLAY);
740    
741                    themeDisplay.setScopeGroupId(
742                            PortalUtil.getScopeGroupId(request, portletId));
743    
744                    ServletContext servletContext = (ServletContext)request.getAttribute(
745                            WebKeys.CTX);
746    
747                    InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
748                            portlet, servletContext);
749    
750                    if (user != null) {
751                            InvokerPortletImpl.clearResponse(
752                                    session, layout.getPrimaryKey(), portletId,
753                                    LanguageUtil.getLanguageId(request));
754                    }
755    
756                    PortletConfig portletConfig = PortletConfigFactoryUtil.create(
757                            portlet, servletContext);
758                    PortletContext portletContext = portletConfig.getPortletContext();
759    
760                    WindowState windowState = WindowStateFactory.getWindowState(
761                            ParamUtil.getString(request, "p_p_state"));
762    
763                    if (layout.isTypeControlPanel() &&
764                            ((windowState == null) || windowState.equals(WindowState.NORMAL) ||
765                             (Validator.isNull(windowState.toString())))) {
766    
767                            windowState = WindowState.MAXIMIZED;
768                    }
769    
770                    PortletMode portletMode = PortletModeFactory.getPortletMode(
771                            ParamUtil.getString(request, "p_p_mode"));
772    
773                    PortletPreferencesIds portletPreferencesIds =
774                            PortletPreferencesFactoryUtil.getPortletPreferencesIds(
775                                    request, portletId);
776    
777                    PortletPreferences portletPreferences = null;
778    
779                    if (PortalUtil.isAllowAddPortletDefaultResource(request, portlet)) {
780                            portletPreferences =
781                                    PortletPreferencesLocalServiceUtil.getPreferences(
782                                            portletPreferencesIds);
783                    }
784                    else {
785                            portletPreferences =
786                                    PortletPreferencesLocalServiceUtil.getStrictPreferences(
787                                            portletPreferencesIds);
788                    }
789    
790                    processPublicRenderParameters(request, layout, portlet);
791    
792                    if (lifecycle.equals(PortletRequest.ACTION_PHASE)) {
793                            String contentType = request.getHeader(HttpHeaders.CONTENT_TYPE);
794    
795                            if (_log.isDebugEnabled()) {
796                                    _log.debug("Content type " + contentType);
797                            }
798    
799                            UploadServletRequest uploadServletRequest = null;
800    
801                            try {
802                                    if ((contentType != null) &&
803                                            (contentType.startsWith(
804                                                    ContentTypes.MULTIPART_FORM_DATA))) {
805    
806                                            PortletConfigImpl invokerPortletConfigImpl =
807                                                    (PortletConfigImpl)invokerPortlet.getPortletConfig();
808    
809                                            if (invokerPortlet.isStrutsPortlet() ||
810                                                    ((invokerPortletConfigImpl != null) &&
811                                                     (!invokerPortletConfigImpl.isWARFile()))) {
812    
813                                                    uploadServletRequest = new UploadServletRequestImpl(
814                                                            request);
815    
816                                                    request = uploadServletRequest;
817                                            }
818                                    }
819    
820                                    if (PropsValues.AUTH_TOKEN_CHECK_ENABLED &&
821                                            invokerPortlet.isCheckAuthToken()) {
822    
823                                            AuthTokenUtil.check(request);
824                                    }
825    
826                                    ActionRequestImpl actionRequestImpl =
827                                            ActionRequestFactory.create(
828                                                    request, portlet, invokerPortlet, portletContext,
829                                                    windowState, portletMode, portletPreferences,
830                                                    layout.getPlid());
831    
832                                    ActionResponseImpl actionResponseImpl =
833                                            ActionResponseFactory.create(
834                                                    actionRequestImpl, response, portletId, user, layout,
835                                                    windowState, portletMode);
836    
837                                    actionRequestImpl.defineObjects(
838                                            portletConfig, actionResponseImpl);
839    
840                                    ServiceContext serviceContext =
841                                            ServiceContextFactory.getInstance(actionRequestImpl);
842    
843                                    ServiceContextThreadLocal.pushServiceContext(serviceContext);
844    
845                                    invokerPortlet.processAction(
846                                            actionRequestImpl, actionResponseImpl);
847    
848                                    actionResponseImpl.transferHeaders(response);
849    
850                                    RenderParametersPool.put(
851                                            request, layout.getPlid(), portletId,
852                                            actionResponseImpl.getRenderParameterMap());
853    
854                                    List<LayoutTypePortlet> layoutTypePortlets = null;
855    
856                                    if (!actionResponseImpl.getEvents().isEmpty()) {
857                                            if (PropsValues.PORTLET_EVENT_DISTRIBUTION_LAYOUT_SET) {
858                                                    layoutTypePortlets = getLayoutTypePortlets(
859                                                            layout.getGroupId(), layout.isPrivateLayout());
860                                            }
861                                            else {
862                                                    if (layout.isTypePortlet()) {
863                                                            LayoutTypePortlet layoutTypePortlet =
864                                                                    (LayoutTypePortlet)layout.getLayoutType();
865    
866                                                            layoutTypePortlets =
867                                                                    new ArrayList<LayoutTypePortlet>();
868    
869                                                            layoutTypePortlets.add(layoutTypePortlet);
870                                                    }
871                                            }
872    
873                                            processEvents(
874                                                    actionRequestImpl, actionResponseImpl,
875                                                    layoutTypePortlets);
876    
877                                            actionRequestImpl.defineObjects(
878                                                    portletConfig, actionResponseImpl);
879                                    }
880                            }
881                            finally {
882                                    if (uploadServletRequest != null) {
883                                            uploadServletRequest.cleanUp();
884                                    }
885    
886                                    ServiceContextThreadLocal.popServiceContext();
887                            }
888                    }
889                    else if (lifecycle.equals(PortletRequest.RENDER_PHASE) ||
890                                     lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
891    
892                            PortalUtil.updateWindowState(
893                                    portletId, user, layout, windowState, request);
894    
895                            PortalUtil.updatePortletMode(
896                                    portletId, user, layout, portletMode, request);
897                    }
898    
899                    if (lifecycle.equals(PortletRequest.RESOURCE_PHASE)) {
900                            PortletDisplay portletDisplay = themeDisplay.getPortletDisplay();
901    
902                            String portletPrimaryKey = PortletPermissionUtil.getPrimaryKey(
903                                    layout.getPlid(), portletId);
904    
905                            portletDisplay.setId(portletId);
906                            portletDisplay.setRootPortletId(portlet.getRootPortletId());
907                            portletDisplay.setInstanceId(portlet.getInstanceId());
908                            portletDisplay.setResourcePK(portletPrimaryKey);
909                            portletDisplay.setPortletName(portletConfig.getPortletName());
910                            portletDisplay.setNamespace(
911                                    PortalUtil.getPortletNamespace(portletId));
912    
913                            WebDAVStorage webDAVStorage = portlet.getWebDAVStorageInstance();
914    
915                            if (webDAVStorage != null) {
916                                    portletDisplay.setWebDAVEnabled(true);
917                            }
918                            else {
919                                    portletDisplay.setWebDAVEnabled(false);
920                            }
921    
922                            ResourceRequestImpl resourceRequestImpl =
923                                    ResourceRequestFactory.create(
924                                            request, portlet, invokerPortlet, portletContext,
925                                            windowState, portletMode, portletPreferences,
926                                            layout.getPlid());
927    
928                            ResourceResponseImpl resourceResponseImpl =
929                                    ResourceResponseFactory.create(
930                                            resourceRequestImpl, response, portletId, companyId);
931    
932                            resourceRequestImpl.defineObjects(
933                                    portletConfig, resourceResponseImpl);
934    
935                            try {
936                                    ServiceContext serviceContext =
937                                            ServiceContextFactory.getInstance(resourceRequestImpl);
938    
939                                    ServiceContextThreadLocal.pushServiceContext(serviceContext);
940    
941                                    invokerPortlet.serveResource(
942                                            resourceRequestImpl, resourceResponseImpl);
943                            }
944                            finally {
945                                    ServiceContextThreadLocal.popServiceContext();
946                            }
947                    }
948    
949                    return portlet;
950            }
951    
952            protected void processPublicRenderParameters(
953                    HttpServletRequest request, Layout layout, Portlet portlet) {
954    
955                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
956                            WebKeys.THEME_DISPLAY);
957    
958                    Map<String, String[]> publicRenderParameters =
959                            PublicRenderParametersPool.get(request, layout.getPlid());
960    
961                    Enumeration<String> enu = request.getParameterNames();
962    
963                    while (enu.hasMoreElements()) {
964                            String name = enu.nextElement();
965    
966                            String[] values = request.getParameterValues(name);
967    
968                            QName qName = PortletQNameUtil.getQName(name);
969    
970                            if (qName == null) {
971                                    continue;
972                            }
973    
974                            PublicRenderParameter publicRenderParameter =
975                                    portlet.getPublicRenderParameter(
976                                            qName.getNamespaceURI(), qName.getLocalPart());
977    
978                            if (publicRenderParameter == null) {
979                                    continue;
980                            }
981    
982                            String publicRenderParameterName =
983                                    PortletQNameUtil.getPublicRenderParameterName(qName);
984    
985                            if (name.startsWith(
986                                            PortletQName.PUBLIC_RENDER_PARAMETER_NAMESPACE)) {
987    
988                                    if (themeDisplay.isLifecycleAction()) {
989                                            String[] oldValues = publicRenderParameters.get(
990                                                    publicRenderParameterName);
991    
992                                            if ((oldValues != null) && (oldValues.length != 0)) {
993                                                    values = ArrayUtil.append(values, oldValues);
994                                            }
995                                    }
996    
997                                    publicRenderParameters.put(publicRenderParameterName, values);
998                            }
999                            else {
1000                                    publicRenderParameters.remove(publicRenderParameterName);
1001                            }
1002                    }
1003            }
1004    
1005            protected void redirectActionURL(
1006                            HttpServletRequest request, HttpServletResponse response,
1007                            ActionResponseImpl actionResponseImpl, Portlet portlet)
1008                    throws Exception {
1009    
1010                    ActionRequestImpl actionRequestImpl =
1011                            (ActionRequestImpl)request.getAttribute(
1012                                    JavaConstants.JAVAX_PORTLET_REQUEST);
1013    
1014                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
1015    
1016                    PortletURL portletURL = new PortletURLImpl(
1017                            actionRequestImpl, actionRequestImpl.getPortletName(),
1018                            layout.getPlid(), PortletRequest.RENDER_PHASE);
1019    
1020                    Map<String, String[]> renderParameters =
1021                            actionResponseImpl.getRenderParameterMap();
1022    
1023                    for (Map.Entry<String, String[]> entry : renderParameters.entrySet()) {
1024                            String key = entry.getKey();
1025                            String[] value = entry.getValue();
1026    
1027                            portletURL.setParameter(key, value);
1028                    }
1029    
1030                    response.sendRedirect(portletURL.toString());
1031            }
1032    
1033            protected void renderExclusive(
1034                            HttpServletRequest request, HttpServletResponse response,
1035                            ThemeDisplay themeDisplay)
1036                    throws Exception {
1037    
1038                    RenderRequestImpl renderRequestImpl =
1039                            (RenderRequestImpl)request.getAttribute(
1040                                    JavaConstants.JAVAX_PORTLET_REQUEST);
1041    
1042                    RenderResponseImpl renderResponseImpl =
1043                            (RenderResponseImpl)request.getAttribute(
1044                                    JavaConstants.JAVAX_PORTLET_RESPONSE);
1045    
1046                    StringServletResponse stringResponse =
1047                            (StringServletResponse)renderRequestImpl.getAttribute(
1048                                    WebKeys.STRING_SERVLET_RESPONSE);
1049    
1050                    if (stringResponse == null) {
1051                            stringResponse = (StringServletResponse)
1052                                    renderResponseImpl.getHttpServletResponse();
1053    
1054                            Portlet portlet = processPortletRequest(
1055                                    request, response, PortletRequest.RENDER_PHASE);
1056    
1057                            InvokerPortlet invokerPortlet = PortletInstanceFactoryUtil.create(
1058                                    portlet, null);
1059    
1060                            invokerPortlet.render(renderRequestImpl, renderResponseImpl);
1061    
1062                            if (Validator.isNull(stringResponse.getString())) {
1063                                    stringResponse.setString(null);
1064                            }
1065                    }
1066    
1067                    renderResponseImpl.transferHeaders(response);
1068    
1069                    if (stringResponse.isCalledGetOutputStream()) {
1070                            UnsyncByteArrayOutputStream ubaos =
1071                                    stringResponse.getUnsyncByteArrayOutputStream();
1072    
1073                            InputStream is = new UnsyncByteArrayInputStream(
1074                                    ubaos.unsafeGetByteArray(), 0, ubaos.size());
1075    
1076                            ServletResponseUtil.sendFile(
1077                                    request, response, renderResponseImpl.getResourceName(), is,
1078                                    renderResponseImpl.getContentType());
1079                    }
1080                    else if (stringResponse.isCalledGetWriter()) {
1081                            byte[] content = stringResponse.getString().getBytes(
1082                                    StringPool.UTF8);
1083    
1084                            ServletResponseUtil.sendFile(
1085                                    request, response, renderResponseImpl.getResourceName(),
1086                                    content, renderResponseImpl.getContentType());
1087                    }
1088    
1089                    renderRequestImpl.cleanUp();
1090            }
1091    
1092            protected Event serializeEvent(
1093                    Event event, ClassLoader portletClassLoader) {
1094    
1095                    Serializable value = event.getValue();
1096    
1097                    if (value == null) {
1098                            return event;
1099                    }
1100    
1101                    Class<?> valueClass = value.getClass();
1102    
1103                    String valueClassName = valueClass.getName();
1104    
1105                    try {
1106                            Class<?> loadedValueClass = portletClassLoader.loadClass(
1107                                    valueClassName);
1108    
1109                            if (loadedValueClass.equals(valueClass)) {
1110                                    return event;
1111                            }
1112                    }
1113                    catch (ClassNotFoundException cnfe) {
1114                            if (_log.isWarnEnabled()) {
1115                                    _log.warn(
1116                                            portletClassLoader.toString() + " does not contain " +
1117                                                    valueClassName,
1118                                            cnfe);
1119                            }
1120                    }
1121    
1122                    EventImpl eventImpl = (EventImpl)event;
1123    
1124                    String base64Value = eventImpl.getBase64Value();
1125    
1126                    value = (Serializable)Base64.stringToObject(
1127                            base64Value, portletClassLoader);
1128    
1129                    return new EventImpl(event.getName(), event.getQName(), value);
1130            }
1131    
1132            private static Log _log = LogFactoryUtil.getLog(LayoutAction.class);
1133    
1134    }