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