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