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