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