1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.portlet;
16  
17  import com.liferay.portal.PortalException;
18  import com.liferay.portal.kernel.servlet.SessionErrors;
19  import com.liferay.portal.kernel.servlet.SessionMessages;
20  import com.liferay.portal.kernel.util.GetterUtil;
21  import com.liferay.portal.kernel.util.MethodCache;
22  import com.liferay.portal.kernel.util.MethodKey;
23  import com.liferay.portal.kernel.util.ParamUtil;
24  import com.liferay.portal.kernel.util.PropsKeys;
25  import com.liferay.portal.kernel.util.PropsUtil;
26  import com.liferay.portal.kernel.util.Validator;
27  import com.liferay.portal.kernel.util.WebKeys;
28  
29  import java.io.IOException;
30  
31  import java.lang.reflect.InvocationTargetException;
32  import java.lang.reflect.Method;
33  
34  import java.util.HashMap;
35  import java.util.Map;
36  import java.util.regex.Matcher;
37  import java.util.regex.Pattern;
38  
39  import javax.portlet.ActionRequest;
40  import javax.portlet.ActionResponse;
41  import javax.portlet.GenericPortlet;
42  import javax.portlet.PortletException;
43  import javax.portlet.PortletMode;
44  import javax.portlet.PortletRequest;
45  import javax.portlet.RenderRequest;
46  import javax.portlet.RenderResponse;
47  import javax.portlet.ResourceRequest;
48  import javax.portlet.ResourceResponse;
49  import javax.portlet.WindowState;
50  
51  /**
52   * <a href="LiferayPortlet.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Brian Wing Shun Chan
55   */
56  public class LiferayPortlet extends GenericPortlet {
57  
58      public void init() throws PortletException {
59          super.init();
60  
61          addProcessActionSuccessMessage = GetterUtil.getBoolean(
62              getInitParameter("add-process-action-success-action"), true);
63      }
64  
65      public void processAction(
66              ActionRequest actionRequest, ActionResponse actionResponse)
67          throws IOException, PortletException {
68  
69          try {
70              if (!isProcessActionRequest(actionRequest)) {
71                  return;
72              }
73  
74              if (!callActionMethod(actionRequest, actionResponse)) {
75                  return;
76              }
77  
78              if (!SessionErrors.isEmpty(actionRequest)) {
79                  return;
80              }
81  
82              if (!SessionMessages.isEmpty(actionRequest)) {
83                  return;
84              }
85  
86              addSuccessMessage(actionRequest, actionResponse);
87  
88              sendRedirect(actionRequest, actionResponse);
89          }
90          catch (PortletException pe) {
91              Throwable cause = pe.getCause();
92  
93              if (isSessionErrorException(cause)) {
94                  SessionErrors.add(
95                      actionRequest, cause.getClass().getName(), cause);
96              }
97              else {
98                  throw pe;
99              }
100         }
101     }
102 
103     public void serveResource(
104             ResourceRequest resourceRequest, ResourceResponse resourceResponse)
105         throws IOException, PortletException {
106 
107         if (!isProcessResourceRequest(resourceRequest)) {
108             return;
109         }
110 
111         super.serveResource(resourceRequest, resourceResponse);
112     }
113 
114     protected void addSuccessMessage(
115         ActionRequest actionRequest, ActionResponse actionResponse) {
116 
117         if (!addProcessActionSuccessMessage) {
118             return;
119         }
120 
121         String successMessage = ParamUtil.getString(
122             actionRequest, "successMessage");
123 
124         SessionMessages.add(actionRequest, "request_processed", successMessage);
125     }
126 
127     protected boolean callActionMethod(
128             ActionRequest actionRequest, ActionResponse actionResponse)
129         throws PortletException {
130 
131         String actionName = ParamUtil.getString(
132             actionRequest, ActionRequest.ACTION_NAME);
133 
134         if (Validator.isNull(actionName)) {
135             return false;
136         }
137 
138         try {
139             Method method = MethodCache.get(
140                 _classesMap, _methodsMap, getClass().getName(), actionName,
141                 new Class[] {ActionRequest.class, ActionResponse.class});
142 
143             method.invoke(this, actionRequest, actionResponse);
144 
145             return true;
146         }
147         catch (NoSuchMethodException nsme) {
148             try {
149                 super.processAction(actionRequest, actionResponse);
150 
151                 return true;
152             }
153             catch (Exception e) {
154                 throw new PortletException(nsme);
155             }
156         }
157         catch (InvocationTargetException ite) {
158             Throwable cause = ite.getCause();
159 
160             if (cause != null) {
161                 throw new PortletException(cause);
162             }
163             else {
164                 throw new PortletException(ite);
165             }
166         }
167         catch (Exception e) {
168             throw new PortletException(e);
169         }
170     }
171 
172     /**
173      * @throws IOException
174      */
175     protected void doAbout(
176             RenderRequest renderRequest, RenderResponse renderResponse)
177         throws IOException, PortletException {
178 
179         throw new PortletException("doAbout method not implemented");
180     }
181 
182     /**
183      * @throws IOException
184      */
185     protected void doConfig(
186             RenderRequest renderRequest, RenderResponse renderResponse)
187         throws IOException, PortletException {
188 
189         throw new PortletException("doConfig method not implemented");
190     }
191 
192     protected void doDispatch(
193             RenderRequest renderRequest, RenderResponse renderResponse)
194         throws IOException, PortletException {
195 
196         if (!isProcessRenderRequest(renderRequest)) {
197             renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.FALSE);
198 
199             return;
200         }
201 
202         WindowState windowState = renderRequest.getWindowState();
203 
204         if (windowState.equals(WindowState.MINIMIZED)) {
205             return;
206         }
207 
208         PortletMode portletMode = renderRequest.getPortletMode();
209 
210         if (portletMode.equals(PortletMode.VIEW)) {
211             doView(renderRequest, renderResponse);
212         }
213         else if (portletMode.equals(LiferayPortletMode.ABOUT)) {
214             doAbout(renderRequest, renderResponse);
215         }
216         else if (portletMode.equals(LiferayPortletMode.CONFIG)) {
217             doConfig(renderRequest, renderResponse);
218         }
219         else if (portletMode.equals(PortletMode.EDIT)) {
220             doEdit(renderRequest, renderResponse);
221         }
222         else if (portletMode.equals(LiferayPortletMode.EDIT_DEFAULTS)) {
223             doEditDefaults(renderRequest, renderResponse);
224         }
225         else if (portletMode.equals(LiferayPortletMode.EDIT_GUEST)) {
226             doEditGuest(renderRequest, renderResponse);
227         }
228         else if (portletMode.equals(PortletMode.HELP)) {
229             doHelp(renderRequest, renderResponse);
230         }
231         else if (portletMode.equals(LiferayPortletMode.PREVIEW)) {
232             doPreview(renderRequest, renderResponse);
233         }
234         else if (portletMode.equals(LiferayPortletMode.PRINT)) {
235             doPrint(renderRequest, renderResponse);
236         }
237         else {
238             throw new PortletException(portletMode.toString());
239         }
240     }
241 
242     /**
243      * @throws IOException
244      */
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     /**
253      * @throws IOException
254      */
255     protected void doEditGuest(
256             RenderRequest renderRequest, RenderResponse renderResponse)
257         throws IOException, PortletException {
258 
259         throw new PortletException("doEditGuest method not implemented");
260     }
261 
262     /**
263      * @throws IOException
264      */
265     protected void doPreview(
266             RenderRequest renderRequest, RenderResponse renderResponse)
267         throws IOException, PortletException {
268 
269         throw new PortletException("doPreview method not implemented");
270     }
271 
272     /**
273      * @throws IOException
274      */
275     protected void doPrint(
276             RenderRequest renderRequest, RenderResponse renderResponse)
277         throws IOException, PortletException {
278 
279         throw new PortletException("doPrint method not implemented");
280     }
281 
282     protected String getRedirect(
283         ActionRequest actionRequest, ActionResponse actionResponse) {
284 
285         String redirect = (String)actionRequest.getAttribute(WebKeys.REDIRECT);
286 
287         if (Validator.isNull(redirect)) {
288             redirect = ParamUtil.getString(actionRequest, "redirect");
289         }
290 
291         return redirect;
292     }
293 
294     protected boolean isProcessActionRequest(ActionRequest actionRequest) {
295         return isProcessPortletRequest(actionRequest);
296     }
297 
298     protected boolean isProcessPortletRequest(PortletRequest portletRequest) {
299         return _PROCESS_PORTLET_REQUEST;
300     }
301 
302     protected boolean isProcessRenderRequest(RenderRequest renderRequest) {
303         return isProcessPortletRequest(renderRequest);
304     }
305 
306     protected boolean isProcessResourceRequest(
307         ResourceRequest resourceRequest) {
308 
309         String resourceId = resourceRequest.getResourceID();
310 
311         if (Validator.isNotNull(resourceId)) {
312             Matcher matcher = _bannedRresourceIdPattern.matcher(resourceId);
313 
314             if (matcher.matches()) {
315                 return false;
316             }
317         }
318 
319         return isProcessPortletRequest(resourceRequest);
320     }
321 
322     protected boolean isSessionErrorException(Throwable cause) {
323         if (cause instanceof PortalException) {
324             return true;
325         }
326         else {
327             return false;
328         }
329     }
330 
331     protected void sendRedirect(
332             ActionRequest actionRequest, ActionResponse actionResponse)
333         throws IOException {
334 
335         String redirect = getRedirect(actionRequest, actionResponse);
336 
337         if (Validator.isNotNull(redirect)) {
338             actionResponse.sendRedirect(redirect);
339         }
340     }
341 
342     protected boolean addProcessActionSuccessMessage;
343 
344     private static final boolean _PROCESS_PORTLET_REQUEST = true;
345 
346     private Pattern _bannedRresourceIdPattern = Pattern.compile(
347         PropsUtil.get(PropsKeys.PORTLET_RESOURCE_ID_BANNED_PATHS_REGEXP));
348     private Map<String, Class<?>> _classesMap = new HashMap<String, Class<?>>();
349     private Map<MethodKey, Method> _methodsMap =
350         new HashMap<MethodKey, Method>();
351 
352 }