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