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