001    /**
002     * Copyright (c) 2000-2013 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.kernel.portlet;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.language.LanguageUtil;
019    import com.liferay.portal.kernel.servlet.ServletResponseUtil;
020    import com.liferay.portal.kernel.servlet.SessionErrors;
021    import com.liferay.portal.kernel.servlet.SessionMessages;
022    import com.liferay.portal.kernel.util.ContentTypes;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.JavaConstants;
025    import com.liferay.portal.kernel.util.ParamUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.kernel.util.WebKeys;
028    import com.liferay.portal.theme.ThemeDisplay;
029    import com.liferay.portal.util.PortalUtil;
030    
031    import java.io.IOException;
032    
033    import java.lang.reflect.InvocationTargetException;
034    import java.lang.reflect.Method;
035    
036    import java.util.Map;
037    import java.util.concurrent.ConcurrentHashMap;
038    
039    import javax.portlet.ActionRequest;
040    import javax.portlet.ActionResponse;
041    import javax.portlet.GenericPortlet;
042    import javax.portlet.MimeResponse;
043    import javax.portlet.PortletConfig;
044    import javax.portlet.PortletException;
045    import javax.portlet.PortletMode;
046    import javax.portlet.PortletRequest;
047    import javax.portlet.RenderRequest;
048    import javax.portlet.RenderResponse;
049    import javax.portlet.ResourceRequest;
050    import javax.portlet.ResourceResponse;
051    import javax.portlet.WindowState;
052    
053    import javax.servlet.http.HttpServletResponse;
054    
055    /**
056     * @author Brian Wing Shun Chan
057     */
058    public class LiferayPortlet extends GenericPortlet {
059    
060            @Override
061            public void init() throws PortletException {
062                    super.init();
063    
064                    addProcessActionSuccessMessage = GetterUtil.getBoolean(
065                            getInitParameter("add-process-action-success-action"), true);
066            }
067    
068            @Override
069            public void processAction(
070                            ActionRequest actionRequest, ActionResponse actionResponse)
071                    throws IOException, PortletException {
072    
073                    try {
074                            if (!isProcessActionRequest(actionRequest)) {
075                                    return;
076                            }
077    
078                            if (!callActionMethod(actionRequest, actionResponse)) {
079                                    return;
080                            }
081    
082                            if (!SessionErrors.isEmpty(actionRequest)) {
083                                    return;
084                            }
085    
086                            if (!SessionMessages.isEmpty(actionRequest)) {
087                                    return;
088                            }
089    
090                            addSuccessMessage(actionRequest, actionResponse);
091    
092                            sendRedirect(actionRequest, actionResponse);
093                    }
094                    catch (PortletException pe) {
095                            Throwable cause = pe.getCause();
096    
097                            if (isSessionErrorException(cause)) {
098                                    SessionErrors.add(actionRequest, cause.getClass(), cause);
099                            }
100                            else {
101                                    throw pe;
102                            }
103                    }
104            }
105    
106            @Override
107            public void serveResource(
108                            ResourceRequest resourceRequest, ResourceResponse resourceResponse)
109                    throws IOException, PortletException {
110    
111                    if (!isProcessResourceRequest(resourceRequest)) {
112                            return;
113                    }
114    
115                    super.serveResource(resourceRequest, resourceResponse);
116            }
117    
118            protected void addSuccessMessage(
119                    ActionRequest actionRequest, ActionResponse actionResponse) {
120    
121                    if (!addProcessActionSuccessMessage) {
122                            return;
123                    }
124    
125                    String successMessage = ParamUtil.getString(
126                            actionRequest, "successMessage");
127    
128                    SessionMessages.add(actionRequest, "request_processed", successMessage);
129            }
130    
131            protected boolean callActionMethod(
132                            ActionRequest actionRequest, ActionResponse actionResponse)
133                    throws PortletException {
134    
135                    String actionName = ParamUtil.getString(
136                            actionRequest, ActionRequest.ACTION_NAME);
137    
138                    if (Validator.isNull(actionName) ||
139                            actionName.equals("callActionMethod") ||
140                            actionName.equals("processAction")) {
141    
142                            return false;
143                    }
144    
145                    try {
146                            Method method = getActionMethod(actionName);
147    
148                            method.invoke(this, actionRequest, actionResponse);
149    
150                            return true;
151                    }
152                    catch (NoSuchMethodException nsme) {
153                            try {
154                                    super.processAction(actionRequest, actionResponse);
155    
156                                    return true;
157                            }
158                            catch (Exception e) {
159                                    throw new PortletException(nsme);
160                            }
161                    }
162                    catch (InvocationTargetException ite) {
163                            Throwable cause = ite.getCause();
164    
165                            if (cause != null) {
166                                    throw new PortletException(cause);
167                            }
168                            else {
169                                    throw new PortletException(ite);
170                            }
171                    }
172                    catch (Exception e) {
173                            throw new PortletException(e);
174                    }
175            }
176    
177            @SuppressWarnings("unused")
178            protected void doAbout(
179                            RenderRequest renderRequest, RenderResponse renderResponse)
180                    throws IOException, PortletException {
181    
182                    throw new PortletException("doAbout method not implemented");
183            }
184    
185            @SuppressWarnings("unused")
186            protected void doConfig(
187                            RenderRequest renderRequest, RenderResponse renderResponse)
188                    throws IOException, PortletException {
189    
190                    throw new PortletException("doConfig method not implemented");
191            }
192    
193            @Override
194            protected void doDispatch(
195                            RenderRequest renderRequest, RenderResponse renderResponse)
196                    throws IOException, PortletException {
197    
198                    if (!isProcessRenderRequest(renderRequest)) {
199                            renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.FALSE);
200    
201                            return;
202                    }
203    
204                    WindowState windowState = renderRequest.getWindowState();
205    
206                    if (windowState.equals(WindowState.MINIMIZED)) {
207                            return;
208                    }
209    
210                    PortletMode portletMode = renderRequest.getPortletMode();
211    
212                    if (portletMode.equals(PortletMode.VIEW)) {
213                            doView(renderRequest, renderResponse);
214                    }
215                    else if (portletMode.equals(LiferayPortletMode.ABOUT)) {
216                            doAbout(renderRequest, renderResponse);
217                    }
218                    else if (portletMode.equals(LiferayPortletMode.CONFIG)) {
219                            doConfig(renderRequest, renderResponse);
220                    }
221                    else if (portletMode.equals(PortletMode.EDIT)) {
222                            doEdit(renderRequest, renderResponse);
223                    }
224                    else if (portletMode.equals(LiferayPortletMode.EDIT_DEFAULTS)) {
225                            doEditDefaults(renderRequest, renderResponse);
226                    }
227                    else if (portletMode.equals(LiferayPortletMode.EDIT_GUEST)) {
228                            doEditGuest(renderRequest, renderResponse);
229                    }
230                    else if (portletMode.equals(PortletMode.HELP)) {
231                            doHelp(renderRequest, renderResponse);
232                    }
233                    else if (portletMode.equals(LiferayPortletMode.PREVIEW)) {
234                            doPreview(renderRequest, renderResponse);
235                    }
236                    else if (portletMode.equals(LiferayPortletMode.PRINT)) {
237                            doPrint(renderRequest, renderResponse);
238                    }
239                    else {
240                            throw new PortletException(portletMode.toString());
241                    }
242            }
243    
244            @SuppressWarnings("unused")
245            protected void doEditDefaults(
246                            RenderRequest renderRequest, RenderResponse renderResponse)
247                    throws IOException, PortletException {
248    
249                    throw new PortletException("doEditDefaults method not implemented");
250            }
251    
252            @SuppressWarnings("unused")
253            protected void doEditGuest(
254                            RenderRequest renderRequest, RenderResponse renderResponse)
255                    throws IOException, PortletException {
256    
257                    throw new PortletException("doEditGuest method not implemented");
258            }
259    
260            @SuppressWarnings("unused")
261            protected void doPreview(
262                            RenderRequest renderRequest, RenderResponse renderResponse)
263                    throws IOException, PortletException {
264    
265                    throw new PortletException("doPreview method not implemented");
266            }
267    
268            @SuppressWarnings("unused")
269            protected void doPrint(
270                            RenderRequest renderRequest, RenderResponse renderResponse)
271                    throws IOException, PortletException {
272    
273                    throw new PortletException("doPrint method not implemented");
274            }
275    
276            protected Method getActionMethod(String actionName)
277                    throws NoSuchMethodException {
278    
279                    Method method = _actionMethods.get(actionName);
280    
281                    if (method != null) {
282                            return method;
283                    }
284    
285                    Class<?> clazz = getClass();
286    
287                    method = clazz.getMethod(
288                            actionName, ActionRequest.class, ActionResponse.class);
289    
290                    _actionMethods.put(actionName, method);
291    
292                    return method;
293            }
294    
295            protected String getRedirect(
296                    ActionRequest actionRequest, ActionResponse actionResponse) {
297    
298                    String redirect = (String)actionRequest.getAttribute(WebKeys.REDIRECT);
299    
300                    if (Validator.isNull(redirect)) {
301                            redirect = ParamUtil.getString(actionRequest, "redirect");
302                    }
303    
304                    return redirect;
305            }
306    
307            protected boolean isProcessActionRequest(ActionRequest actionRequest) {
308                    return isProcessPortletRequest(actionRequest);
309            }
310    
311            protected boolean isProcessPortletRequest(PortletRequest portletRequest) {
312                    return _PROCESS_PORTLET_REQUEST;
313            }
314    
315            protected boolean isProcessRenderRequest(RenderRequest renderRequest) {
316                    return isProcessPortletRequest(renderRequest);
317            }
318    
319            protected boolean isProcessResourceRequest(
320                    ResourceRequest resourceRequest) {
321    
322                    return isProcessPortletRequest(resourceRequest);
323            }
324    
325            protected boolean isSessionErrorException(Throwable cause) {
326                    if (cause instanceof PortalException) {
327                            return true;
328                    }
329    
330                    return false;
331            }
332    
333            protected void sendRedirect(
334                            ActionRequest actionRequest, ActionResponse actionResponse)
335                    throws IOException {
336    
337                    String redirect = getRedirect(actionRequest, actionResponse);
338    
339                    if (Validator.isNotNull(redirect)) {
340                            actionResponse.sendRedirect(redirect);
341                    }
342            }
343    
344            protected String translate(PortletRequest portletRequest, String key) {
345                    PortletConfig portletConfig =
346                            (PortletConfig)portletRequest.getAttribute(
347                                    JavaConstants.JAVAX_PORTLET_CONFIG);
348    
349                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
350                            WebKeys.THEME_DISPLAY);
351    
352                    return LanguageUtil.get(portletConfig, themeDisplay.getLocale(), key);
353            }
354    
355            protected String translate(
356                    PortletRequest portletRequest, String key, Object argument) {
357    
358                    PortletConfig portletConfig =
359                            (PortletConfig)portletRequest.getAttribute(
360                                    JavaConstants.JAVAX_PORTLET_CONFIG);
361    
362                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
363                            WebKeys.THEME_DISPLAY);
364    
365                    return LanguageUtil.format(
366                            portletConfig, themeDisplay.getLocale(), key, argument);
367            }
368    
369            protected String translate(
370                    PortletRequest portletRequest, String key, Object[] arguments) {
371    
372                    PortletConfig portletConfig =
373                            (PortletConfig)portletRequest.getAttribute(
374                                    JavaConstants.JAVAX_PORTLET_CONFIG);
375    
376                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
377                            WebKeys.THEME_DISPLAY);
378    
379                    return LanguageUtil.format(
380                            portletConfig, themeDisplay.getLocale(), key, arguments);
381            }
382    
383            protected void writeJSON(
384                            PortletRequest portletRequest, ActionResponse actionResponse,
385                            Object json)
386                    throws IOException {
387    
388                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
389                            actionResponse);
390    
391                    response.setContentType(ContentTypes.APPLICATION_JSON);
392    
393                    ServletResponseUtil.write(response, json.toString());
394    
395                    response.flushBuffer();
396            }
397    
398            protected void writeJSON(
399                            PortletRequest portletRequest, MimeResponse mimeResponse,
400                            Object json)
401                    throws IOException {
402    
403                    mimeResponse.setContentType(ContentTypes.APPLICATION_JSON);
404    
405                    PortletResponseUtil.write(mimeResponse, json.toString());
406    
407                    mimeResponse.flushBuffer();
408            }
409    
410            protected boolean addProcessActionSuccessMessage;
411    
412            private static final boolean _PROCESS_PORTLET_REQUEST = true;
413    
414            private Map<String, Method> _actionMethods =
415                    new ConcurrentHashMap<String, Method>();
416    
417    }