001    /**
002     * Copyright (c) 2000-2013 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.struts;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
022    import com.liferay.portal.kernel.portlet.PortletResponseUtil;
023    import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
024    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
025    import com.liferay.portal.kernel.servlet.SessionErrors;
026    import com.liferay.portal.kernel.servlet.SessionMessages;
027    import com.liferay.portal.kernel.util.ContentTypes;
028    import com.liferay.portal.kernel.util.GetterUtil;
029    import com.liferay.portal.kernel.util.HttpUtil;
030    import com.liferay.portal.kernel.util.JavaConstants;
031    import com.liferay.portal.kernel.util.ParamUtil;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.kernel.util.Validator;
035    import com.liferay.portal.model.Layout;
036    import com.liferay.portal.model.LayoutTypePortlet;
037    import com.liferay.portal.model.Portlet;
038    import com.liferay.portal.security.auth.PrincipalException;
039    import com.liferay.portal.service.PortletLocalServiceUtil;
040    import com.liferay.portal.theme.ThemeDisplay;
041    import com.liferay.portal.util.PortalUtil;
042    import com.liferay.portal.util.WebKeys;
043    
044    import java.io.IOException;
045    
046    import javax.portlet.ActionRequest;
047    import javax.portlet.ActionResponse;
048    import javax.portlet.MimeResponse;
049    import javax.portlet.PortletConfig;
050    import javax.portlet.PortletContext;
051    import javax.portlet.PortletRequest;
052    import javax.portlet.PortletRequestDispatcher;
053    import javax.portlet.PortletResponse;
054    import javax.portlet.RenderRequest;
055    import javax.portlet.RenderResponse;
056    import javax.portlet.ResourceRequest;
057    import javax.portlet.ResourceResponse;
058    
059    import javax.servlet.ServletContext;
060    import javax.servlet.http.HttpServletRequest;
061    import javax.servlet.http.HttpServletResponse;
062    
063    import org.apache.struts.Globals;
064    import org.apache.struts.action.Action;
065    import org.apache.struts.action.ActionForm;
066    import org.apache.struts.action.ActionForward;
067    import org.apache.struts.action.ActionMapping;
068    import org.apache.struts.config.ModuleConfig;
069    import org.apache.struts.util.MessageResources;
070    
071    /**
072     * @author Brian Wing Shun Chan
073     */
074    public class PortletAction extends Action {
075    
076            public static String getForwardKey(HttpServletRequest request) {
077                    String portletId = (String)request.getAttribute(WebKeys.PORTLET_ID);
078    
079                    String portletNamespace = PortalUtil.getPortletNamespace(portletId);
080    
081                    return portletNamespace.concat(WebKeys.PORTLET_STRUTS_FORWARD);
082            }
083    
084            public static String getForwardKey(PortletRequest portletRequest) {
085                    String portletId = (String)portletRequest.getAttribute(
086                            WebKeys.PORTLET_ID);
087    
088                    String portletNamespace = PortalUtil.getPortletNamespace(portletId);
089    
090                    return portletNamespace.concat(WebKeys.PORTLET_STRUTS_FORWARD);
091            }
092    
093            @Override
094            public ActionForward execute(
095                            ActionMapping actionMapping, ActionForm actionForm,
096                            HttpServletRequest request, HttpServletResponse response)
097                    throws Exception {
098    
099                    PortletConfig portletConfig = (PortletConfig)request.getAttribute(
100                            JavaConstants.JAVAX_PORTLET_CONFIG);
101    
102                    PortletRequest portletRequest = (PortletRequest)request.getAttribute(
103                            JavaConstants.JAVAX_PORTLET_REQUEST);
104    
105                    PortletResponse portletResponse = (PortletResponse)request.getAttribute(
106                            JavaConstants.JAVAX_PORTLET_RESPONSE);
107    
108                    Boolean strutsExecute = (Boolean)request.getAttribute(
109                            WebKeys.PORTLET_STRUTS_EXECUTE);
110    
111                    if ((strutsExecute != null) && strutsExecute.booleanValue()) {
112                            return strutsExecute(actionMapping, actionForm, request, response);
113                    }
114                    else if (portletRequest instanceof RenderRequest) {
115                            return render(
116                                    actionMapping, actionForm, portletConfig,
117                                    (RenderRequest)portletRequest, (RenderResponse)portletResponse);
118                    }
119                    else {
120                            serveResource(
121                                    actionMapping, actionForm, portletConfig,
122                                    (ResourceRequest)portletRequest,
123                                    (ResourceResponse)portletResponse);
124    
125                            return actionMapping.findForward(ActionConstants.COMMON_NULL);
126                    }
127            }
128    
129            public void processAction(
130                            ActionMapping actionMapping, ActionForm actionForm,
131                            PortletConfig portletConfig, ActionRequest actionRequest,
132                            ActionResponse actionResponse)
133                    throws Exception {
134            }
135    
136            public ActionForward render(
137                            ActionMapping actionMapping, ActionForm actionForm,
138                            PortletConfig portletConfig, RenderRequest renderRequest,
139                            RenderResponse renderResponse)
140                    throws Exception {
141    
142                    if (_log.isDebugEnabled()) {
143                            _log.debug("Forward to " + getForward(renderRequest));
144                    }
145    
146                    return actionMapping.findForward(getForward(renderRequest));
147            }
148    
149            public void serveResource(
150                            ActionMapping actionMapping, ActionForm actionForm,
151                            PortletConfig portletConfig, ResourceRequest resourceRequest,
152                            ResourceResponse resourceResponse)
153                    throws Exception {
154    
155                    String resourceId = resourceRequest.getResourceID();
156    
157                    if (Validator.isNull(resourceId)) {
158                            return;
159                    }
160    
161                    PortletContext portletContext = portletConfig.getPortletContext();
162    
163                    PortletRequestDispatcher portletRequestDispatcher =
164                            portletContext.getRequestDispatcher(resourceId);
165    
166                    if (portletRequestDispatcher == null) {
167                            return;
168                    }
169    
170                    portletRequestDispatcher.forward(resourceRequest, resourceResponse);
171            }
172    
173            public ActionForward strutsExecute(
174                            ActionMapping actionMapping, ActionForm actionForm,
175                            HttpServletRequest request, HttpServletResponse response)
176                    throws Exception {
177    
178                    return super.execute(actionMapping, actionForm, request, response);
179            }
180    
181            protected void addSuccessMessage(
182                    ActionRequest actionRequest, ActionResponse actionResponse) {
183    
184                    PortletConfig portletConfig = (PortletConfig)actionRequest.getAttribute(
185                            JavaConstants.JAVAX_PORTLET_CONFIG);
186    
187                    boolean addProcessActionSuccessMessage = GetterUtil.getBoolean(
188                            portletConfig.getInitParameter("add-process-action-success-action"),
189                            true);
190    
191                    if (!addProcessActionSuccessMessage) {
192                            return;
193                    }
194    
195                    String successMessage = ParamUtil.getString(
196                            actionRequest, "successMessage");
197    
198                    SessionMessages.add(actionRequest, "request_processed", successMessage);
199            }
200    
201            protected String getForward(PortletRequest portletRequest) {
202                    return getForward(portletRequest, null);
203            }
204    
205            protected String getForward(
206                    PortletRequest portletRequest, String defaultValue) {
207    
208                    String forward = (String)portletRequest.getAttribute(
209                            getForwardKey(portletRequest));
210    
211                    if (forward == null) {
212                            return defaultValue;
213                    }
214                    else {
215                            return forward;
216                    }
217            }
218    
219            protected ModuleConfig getModuleConfig(PortletRequest portletRequest) {
220                    return (ModuleConfig)portletRequest.getAttribute(Globals.MODULE_KEY);
221            }
222    
223            protected MessageResources getResources() {
224                    ServletContext servletContext = getServlet().getServletContext();
225    
226                    return (MessageResources)servletContext.getAttribute(
227                            Globals.MESSAGES_KEY);
228            }
229    
230            @Override
231            protected MessageResources getResources(HttpServletRequest request) {
232                    return getResources();
233            }
234    
235            protected MessageResources getResources(PortletRequest portletRequest) {
236                    return getResources();
237            }
238    
239            protected boolean isCheckMethodOnProcessAction() {
240                    return _CHECK_METHOD_ON_PROCESS_ACTION;
241            }
242    
243            protected boolean isDisplaySuccessMessage(PortletRequest portletRequest)
244                    throws SystemException {
245    
246                    if (!SessionErrors.isEmpty(portletRequest)) {
247                            return false;
248                    }
249    
250                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
251                            WebKeys.THEME_DISPLAY);
252    
253                    Layout layout = themeDisplay.getLayout();
254    
255                    if (layout.isTypeControlPanel()) {
256                            return true;
257                    }
258    
259                    String portletId = (String)portletRequest.getAttribute(
260                            WebKeys.PORTLET_ID);
261    
262                    try {
263                            LayoutTypePortlet layoutTypePortlet =
264                                    themeDisplay.getLayoutTypePortlet();
265    
266                            if (layoutTypePortlet.hasPortletId(portletId)) {
267                                    return true;
268                            }
269                    }
270                    catch (PortalException pe) {
271                            if (_log.isDebugEnabled()) {
272                                    _log.debug(pe, pe);
273                            }
274                    }
275    
276                    Portlet portlet = PortletLocalServiceUtil.getPortletById(
277                            themeDisplay.getCompanyId(), portletId);
278    
279                    if (portlet.isAddDefaultResource()) {
280                            return true;
281                    }
282    
283                    return false;
284            }
285    
286            protected boolean redirectToLogin(
287                            ActionRequest actionRequest, ActionResponse actionResponse)
288                    throws IOException {
289    
290                    if (actionRequest.getRemoteUser() == null) {
291                            HttpServletRequest request = PortalUtil.getHttpServletRequest(
292                                    actionRequest);
293    
294                            SessionErrors.add(request, PrincipalException.class.getName());
295    
296                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
297                                    WebKeys.THEME_DISPLAY);
298    
299                            actionResponse.sendRedirect(themeDisplay.getURLSignIn());
300    
301                            return true;
302                    }
303                    else {
304                            return false;
305                    }
306            }
307    
308            protected void sendRedirect(
309                            ActionRequest actionRequest, ActionResponse actionResponse)
310                    throws IOException, SystemException {
311    
312                    sendRedirect(actionRequest, actionResponse, null);
313            }
314    
315            protected void sendRedirect(
316                            ActionRequest actionRequest, ActionResponse actionResponse,
317                            String redirect)
318                    throws IOException, SystemException {
319    
320                    sendRedirect(null, actionRequest, actionResponse, redirect, null);
321            }
322    
323            protected void sendRedirect(
324                            PortletConfig portletConfig, ActionRequest actionRequest,
325                            ActionResponse actionResponse, String redirect,
326                            String closeRedirect)
327                    throws IOException, SystemException {
328    
329                    if (isDisplaySuccessMessage(actionRequest)) {
330                            addSuccessMessage(actionRequest, actionResponse);
331                    }
332    
333                    if (Validator.isNull(redirect)) {
334                            redirect = (String)actionRequest.getAttribute(WebKeys.REDIRECT);
335                    }
336    
337                    if (Validator.isNull(redirect)) {
338                            redirect = ParamUtil.getString(actionRequest, "redirect");
339                    }
340    
341                    if ((portletConfig != null) && Validator.isNotNull(redirect) &&
342                            Validator.isNotNull(closeRedirect)) {
343    
344                            redirect = HttpUtil.setParameter(
345                                    redirect, "closeRedirect", closeRedirect);
346    
347                            LiferayPortletConfig liferayPortletConfig =
348                                    (LiferayPortletConfig)portletConfig;
349    
350                            SessionMessages.add(
351                                    actionRequest,
352                                    liferayPortletConfig.getPortletId() +
353                                            SessionMessages.KEY_SUFFIX_CLOSE_REDIRECT,
354                                    closeRedirect);
355                    }
356    
357                    if (Validator.isNull(redirect)) {
358                            return;
359                    }
360    
361                    // LPS-1928
362    
363                    HttpServletRequest request = PortalUtil.getHttpServletRequest(
364                            actionRequest);
365    
366                    if (BrowserSnifferUtil.isIe(request) &&
367                            (BrowserSnifferUtil.getMajorVersion(request) == 6.0) &&
368                            redirect.contains(StringPool.POUND)) {
369    
370                            String redirectToken = "&#";
371    
372                            if (!redirect.contains(StringPool.QUESTION)) {
373                                    redirectToken = StringPool.QUESTION + redirectToken;
374                            }
375    
376                            redirect = StringUtil.replace(
377                                    redirect, StringPool.POUND, redirectToken);
378                    }
379    
380                    redirect = PortalUtil.escapeRedirect(redirect);
381    
382                    if (Validator.isNotNull(redirect)) {
383                            actionResponse.sendRedirect(redirect);
384                    }
385            }
386    
387            protected void setForward(PortletRequest portletRequest, String forward) {
388                    portletRequest.setAttribute(getForwardKey(portletRequest), forward);
389            }
390    
391            protected void writeJSON(
392                            PortletRequest portletRequest, ActionResponse actionResponse,
393                            Object json)
394                    throws IOException {
395    
396                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
397                            actionResponse);
398    
399                    response.setContentType(ContentTypes.APPLICATION_JSON);
400    
401                    ServletResponseUtil.write(response, json.toString());
402    
403                    response.flushBuffer();
404    
405                    setForward(portletRequest, ActionConstants.COMMON_NULL);
406            }
407    
408            protected void writeJSON(
409                            PortletRequest portletRequest, MimeResponse mimeResponse,
410                            Object json)
411                    throws IOException {
412    
413                    mimeResponse.setContentType(ContentTypes.APPLICATION_JSON);
414    
415                    PortletResponseUtil.write(mimeResponse, json.toString());
416    
417                    mimeResponse.flushBuffer();
418            }
419    
420            private static final boolean _CHECK_METHOD_ON_PROCESS_ACTION = true;
421    
422            private static Log _log = LogFactoryUtil.getLog(PortletAction.class);
423    
424    }