001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
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.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.portlet.PortletContainerUtil;
022    import com.liferay.portal.kernel.servlet.MetaInfoCacheServletResponse;
023    import com.liferay.portal.kernel.util.HttpUtil;
024    import com.liferay.portal.kernel.util.JavaConstants;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.util.ServerDetector;
027    import com.liferay.portal.kernel.util.Validator;
028    import com.liferay.portal.kernel.util.WebKeys;
029    import com.liferay.portal.model.Layout;
030    import com.liferay.portal.model.LayoutConstants;
031    import com.liferay.portal.model.Portlet;
032    import com.liferay.portal.model.User;
033    import com.liferay.portal.security.permission.ActionKeys;
034    import com.liferay.portal.security.sso.SSOUtil;
035    import com.liferay.portal.service.PortletLocalServiceUtil;
036    import com.liferay.portal.struts.ActionConstants;
037    import com.liferay.portal.theme.ThemeDisplay;
038    import com.liferay.portal.util.PortalUtil;
039    import com.liferay.portal.util.PortletKeys;
040    import com.liferay.portal.util.PropsValues;
041    import com.liferay.portlet.PortletRequestImpl;
042    import com.liferay.portlet.PortletURLFactoryUtil;
043    import com.liferay.portlet.RenderParametersPool;
044    
045    import javax.portlet.PortletMode;
046    import javax.portlet.PortletRequest;
047    import javax.portlet.PortletURL;
048    import javax.portlet.WindowState;
049    
050    import javax.servlet.http.HttpServletRequest;
051    import javax.servlet.http.HttpServletResponse;
052    import javax.servlet.http.HttpSession;
053    
054    import org.apache.struts.action.Action;
055    import org.apache.struts.action.ActionForm;
056    import org.apache.struts.action.ActionForward;
057    import org.apache.struts.action.ActionMapping;
058    
059    /**
060     * @author Brian Wing Shun Chan
061     * @author Shuyang Zhou
062     */
063    public class LayoutAction extends Action {
064    
065            @Override
066            public ActionForward execute(
067                            ActionMapping actionMapping, ActionForm actionForm,
068                            HttpServletRequest request, HttpServletResponse response)
069                    throws Exception {
070    
071                    MetaInfoCacheServletResponse metaInfoCacheServletResponse =
072                            new MetaInfoCacheServletResponse(response);
073    
074                    try {
075                            return doExecute(
076                                    actionMapping, actionForm, request,
077                                    metaInfoCacheServletResponse);
078                    }
079                    finally {
080                            metaInfoCacheServletResponse.finishResponse(false);
081                    }
082            }
083    
084            protected ActionForward doExecute(
085                            ActionMapping actionMapping, ActionForm actionForm,
086                            HttpServletRequest request, HttpServletResponse response)
087                    throws Exception {
088    
089                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
090                            WebKeys.THEME_DISPLAY);
091    
092                    Boolean layoutDefault = (Boolean)request.getAttribute(
093                            WebKeys.LAYOUT_DEFAULT);
094    
095                    if (Boolean.TRUE.equals(layoutDefault)) {
096                            Layout requestedLayout = (Layout)request.getAttribute(
097                                    WebKeys.REQUESTED_LAYOUT);
098    
099                            if (requestedLayout != null) {
100                                    String redirectParam = "redirect";
101    
102                                    if (Validator.isNotNull(PropsValues.AUTH_LOGIN_PORTLET_NAME)) {
103                                            redirectParam =
104                                                    PortalUtil.getPortletNamespace(
105                                                            PropsValues.AUTH_LOGIN_PORTLET_NAME) +
106                                                                    redirectParam;
107                                    }
108    
109                                    String authLoginURL = SSOUtil.getSignInURL(
110                                            themeDisplay.getCompanyId(), themeDisplay.getURLSignIn());
111    
112                                    if (Validator.isNull(authLoginURL)) {
113                                            authLoginURL = PortalUtil.getSiteLoginURL(themeDisplay);
114                                    }
115    
116                                    if (Validator.isNull(authLoginURL)) {
117                                            authLoginURL = PropsValues.AUTH_LOGIN_URL;
118                                    }
119    
120                                    if (Validator.isNull(authLoginURL)) {
121                                            PortletURL loginURL = PortletURLFactoryUtil.create(
122                                                    request, PortletKeys.LOGIN, themeDisplay.getPlid(),
123                                                    PortletRequest.RENDER_PHASE);
124    
125                                            loginURL.setParameter(
126                                                    "saveLastPath", Boolean.FALSE.toString());
127                                            loginURL.setParameter(
128                                                    "mvcRenderCommandName", "/login/login");
129                                            loginURL.setPortletMode(PortletMode.VIEW);
130                                            loginURL.setWindowState(WindowState.MAXIMIZED);
131    
132                                            authLoginURL = loginURL.toString();
133                                    }
134    
135                                    authLoginURL = HttpUtil.setParameter(
136                                            authLoginURL, "p_p_id",
137                                            PropsValues.AUTH_LOGIN_PORTLET_NAME);
138    
139                                    String currentURL = PortalUtil.getCurrentURL(request);
140    
141                                    authLoginURL = HttpUtil.setParameter(
142                                            authLoginURL, redirectParam, currentURL);
143    
144                                    if (_log.isDebugEnabled()) {
145                                            _log.debug("Redirect requested layout to " + authLoginURL);
146                                    }
147    
148                                    response.sendRedirect(authLoginURL);
149                            }
150                            else {
151                                    Layout layout = themeDisplay.getLayout();
152    
153                                    String redirect = PortalUtil.getLayoutURL(layout, themeDisplay);
154    
155                                    if (_log.isDebugEnabled()) {
156                                            _log.debug("Redirect default layout to " + redirect);
157                                    }
158    
159                                    response.sendRedirect(redirect);
160                            }
161    
162                            return null;
163                    }
164    
165                    long plid = ParamUtil.getLong(request, "p_l_id");
166    
167                    if (_log.isDebugEnabled()) {
168                            _log.debug("p_l_id is " + plid);
169                    }
170    
171                    if (plid > 0) {
172                            Layout layout = themeDisplay.getLayout();
173    
174                            if (layout != null) {
175                                    plid = layout.getPlid();
176                            }
177    
178                            ActionForward actionForward = processLayout(
179                                    actionMapping, request, response, plid);
180    
181                            return actionForward;
182                    }
183    
184                    try {
185                            forwardLayout(request);
186    
187                            return actionMapping.findForward(
188                                    ActionConstants.COMMON_FORWARD_JSP);
189                    }
190                    catch (Exception e) {
191                            PortalUtil.sendError(e, request, response);
192    
193                            return null;
194                    }
195            }
196    
197            protected void forwardLayout(HttpServletRequest request) throws Exception {
198                    Layout layout = (Layout)request.getAttribute(WebKeys.LAYOUT);
199    
200                    long plid = LayoutConstants.DEFAULT_PLID;
201    
202                    String layoutFriendlyURL = null;
203    
204                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
205                            WebKeys.THEME_DISPLAY);
206    
207                    if (layout != null) {
208                            plid = layout.getPlid();
209    
210                            layoutFriendlyURL = PortalUtil.getLayoutFriendlyURL(
211                                    layout, themeDisplay);
212                    }
213    
214                    String forwardURL = layoutFriendlyURL;
215    
216                    if (Validator.isNull(forwardURL)) {
217                            forwardURL =
218                                    themeDisplay.getPathMain() + "/portal/layout?p_l_id=" + plid;
219                    }
220    
221                    if (Validator.isNotNull(themeDisplay.getDoAsUserId())) {
222                            forwardURL = HttpUtil.addParameter(
223                                    forwardURL, "doAsUserId", themeDisplay.getDoAsUserId());
224                    }
225    
226                    if (Validator.isNotNull(themeDisplay.getDoAsUserLanguageId())) {
227                            forwardURL = HttpUtil.addParameter(
228                                    forwardURL, "doAsUserLanguageId",
229                                    themeDisplay.getDoAsUserLanguageId());
230                    }
231    
232                    if (_log.isDebugEnabled()) {
233                            _log.debug("Forward layout to " + forwardURL);
234                    }
235    
236                    request.setAttribute(WebKeys.FORWARD_URL, forwardURL);
237            }
238    
239            protected ActionForward processLayout(
240                            ActionMapping actionMapping, HttpServletRequest request,
241                            HttpServletResponse response, long plid)
242                    throws Exception {
243    
244                    HttpSession session = request.getSession();
245    
246                    ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
247                            WebKeys.THEME_DISPLAY);
248    
249                    try {
250                            Layout layout = themeDisplay.getLayout();
251    
252                            if ((layout != null) && layout.isTypeURL()) {
253                                    String redirect = PortalUtil.getLayoutActualURL(layout);
254    
255                                    response.sendRedirect(redirect);
256    
257                                    return null;
258                            }
259    
260                            Long previousLayoutPlid = (Long)session.getAttribute(
261                                    WebKeys.PREVIOUS_LAYOUT_PLID);
262    
263                            if ((previousLayoutPlid == null) ||
264                                    (layout.getPlid() != previousLayoutPlid.longValue())) {
265    
266                                    session.setAttribute(
267                                            WebKeys.PREVIOUS_LAYOUT_PLID, layout.getPlid());
268    
269                                    if (themeDisplay.isSignedIn() &&
270                                            PropsValues.
271                                                    AUDIT_MESSAGE_COM_LIFERAY_PORTAL_MODEL_LAYOUT_VIEW &&
272                                            AuditRouterUtil.isDeployed()) {
273    
274                                            User user = themeDisplay.getUser();
275    
276                                            AuditMessage auditMessage = new AuditMessage(
277                                                    ActionKeys.VIEW, user.getCompanyId(), user.getUserId(),
278                                                    user.getFullName(), Layout.class.getName(),
279                                                    String.valueOf(layout.getPlid()));
280    
281                                            AuditRouterUtil.route(auditMessage);
282                                    }
283                            }
284    
285                            boolean resetLayout = ParamUtil.getBoolean(
286                                    request, "p_l_reset", PropsValues.LAYOUT_DEFAULT_P_L_RESET);
287    
288                            String portletId = ParamUtil.getString(request, "p_p_id");
289    
290                            if (resetLayout &&
291                                    (Validator.isNull(portletId) ||
292                                     ((previousLayoutPlid != null) &&
293                                      (layout.getPlid() != previousLayoutPlid.longValue())))) {
294    
295                                    // Always clear render parameters on a layout url, but do not
296                                    // clear on portlet urls invoked on the same layout
297    
298                                    RenderParametersPool.clear(request, plid);
299                            }
300    
301                            Portlet portlet = null;
302    
303                            if (Validator.isNotNull(portletId)) {
304                                    long companyId = PortalUtil.getCompanyId(request);
305    
306                                    portlet = PortletLocalServiceUtil.getPortletById(
307                                            companyId, portletId);
308                            }
309    
310                            if (portlet != null) {
311                                    PortletContainerUtil.preparePortlet(request, portlet);
312    
313                                    if (themeDisplay.isLifecycleAction()) {
314                                            PortletContainerUtil.processAction(
315                                                    request, response, portlet);
316    
317                                            if (response.isCommitted()) {
318                                                    return null;
319                                            }
320                                    }
321                                    else if (themeDisplay.isLifecycleResource()) {
322                                            PortletContainerUtil.serveResource(
323                                                    request, response, portlet);
324    
325                                            return null;
326                                    }
327                            }
328    
329                            if (layout != null) {
330                                    if (themeDisplay.isStateExclusive()) {
331                                            PortletContainerUtil.render(request, response, portlet);
332    
333                                            return null;
334                                    }
335    
336                                    // Include layout content before the page loads because portlets
337                                    // on the page can set the page title and page subtitle
338    
339                                    if (layout.includeLayoutContent(request, response)) {
340                                            return null;
341                                    }
342                            }
343    
344                            return actionMapping.findForward("portal.layout");
345                    }
346                    catch (Exception e) {
347                            PortalUtil.sendError(e, request, response);
348    
349                            return null;
350                    }
351                    finally {
352                            if (!ServerDetector.isResin()) {
353                                    PortletRequest portletRequest =
354                                            (PortletRequest)request.getAttribute(
355                                                    JavaConstants.JAVAX_PORTLET_REQUEST);
356    
357                                    if (portletRequest != null) {
358                                            PortletRequestImpl portletRequestImpl =
359                                                    PortletRequestImpl.getPortletRequestImpl(
360                                                            portletRequest);
361    
362                                            portletRequestImpl.cleanUp();
363                                    }
364                            }
365                    }
366            }
367    
368            private static final Log _log = LogFactoryUtil.getLog(LayoutAction.class);
369    
370    }