001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
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            protected boolean isProcessActionRequest(ActionRequest actionRequest) {
294                    return isProcessPortletRequest(actionRequest);
295            }
296    
297            protected boolean isProcessPortletRequest(PortletRequest portletRequest) {
298                    return _PROCESS_PORTLET_REQUEST;
299            }
300    
301            protected boolean isProcessRenderRequest(RenderRequest renderRequest) {
302                    return isProcessPortletRequest(renderRequest);
303            }
304    
305            protected boolean isProcessResourceRequest(
306                    ResourceRequest resourceRequest) {
307    
308                    return isProcessPortletRequest(resourceRequest);
309            }
310    
311            protected boolean isSessionErrorException(Throwable cause) {
312                    if (cause instanceof PortalException) {
313                            return true;
314                    }
315                    else {
316                            return false;
317                    }
318            }
319    
320            protected void sendRedirect(
321                            ActionRequest actionRequest, ActionResponse actionResponse)
322                    throws IOException {
323    
324                    String redirect = getRedirect(actionRequest, actionResponse);
325    
326                    if (Validator.isNotNull(redirect)) {
327                            actionResponse.sendRedirect(redirect);
328                    }
329            }
330    
331            protected String translate(PortletRequest portletRequest, String key) {
332                    PortletConfig portletConfig =
333                            (PortletConfig)portletRequest.getAttribute(
334                                    JavaConstants.JAVAX_PORTLET_CONFIG);
335    
336                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
337                            WebKeys.THEME_DISPLAY);
338    
339                    return LanguageUtil.get(portletConfig, themeDisplay.getLocale(), key);
340            }
341    
342            protected String translate(
343                    PortletRequest portletRequest, String key, Object argument) {
344    
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.format(
353                            portletConfig, themeDisplay.getLocale(), key, argument);
354            }
355    
356            protected String translate(
357                    PortletRequest portletRequest, String key, Object[] arguments) {
358    
359                    PortletConfig portletConfig =
360                            (PortletConfig)portletRequest.getAttribute(
361                                    JavaConstants.JAVAX_PORTLET_CONFIG);
362    
363                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
364                            WebKeys.THEME_DISPLAY);
365    
366                    return LanguageUtil.format(
367                            portletConfig, themeDisplay.getLocale(), key, arguments);
368            }
369    
370            protected void writeJSON(
371                            PortletRequest portletRequest, ActionResponse actionResponse,
372                            Object json)
373                    throws IOException {
374    
375                    HttpServletResponse response = PortalUtil.getHttpServletResponse(
376                            actionResponse);
377    
378                    response.setContentType(ContentTypes.TEXT_JAVASCRIPT);
379    
380                    ServletResponseUtil.write(response, json.toString());
381            }
382    
383            protected void writeJSON(
384                            PortletRequest portletRequest, MimeResponse mimeResponse,
385                            Object json)
386                    throws IOException {
387    
388                    mimeResponse.setContentType(ContentTypes.TEXT_JAVASCRIPT);
389    
390                    PortletResponseUtil.write(mimeResponse, json.toString());
391            }
392    
393            protected boolean addProcessActionSuccessMessage;
394    
395            private static final boolean _PROCESS_PORTLET_REQUEST = true;
396    
397            private Map<String, Class<?>> _classesMap = new HashMap<String, Class<?>>();
398            private Map<MethodKey, Method> _methodsMap =
399                    new HashMap<MethodKey, Method>();
400    
401    }