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