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