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