001
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.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.servlet.BrowserSnifferUtil;
022 import com.liferay.portal.kernel.servlet.ServletResponseUtil;
023 import com.liferay.portal.kernel.servlet.SessionErrors;
024 import com.liferay.portal.kernel.servlet.SessionMessages;
025 import com.liferay.portal.kernel.util.ContentTypes;
026 import com.liferay.portal.kernel.util.GetterUtil;
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.Map;
039 import java.util.ResourceBundle;
040 import java.util.concurrent.ConcurrentHashMap;
041
042 import javax.portlet.ActionRequest;
043 import javax.portlet.ActionResponse;
044 import javax.portlet.GenericPortlet;
045 import javax.portlet.MimeResponse;
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.HttpServletRequest;
056 import javax.servlet.http.HttpServletResponse;
057
058
061 public class LiferayPortlet extends GenericPortlet {
062
063 @Override
064 public void init() throws PortletException {
065 super.init();
066
067 addProcessActionSuccessMessage = GetterUtil.getBoolean(
068 getInitParameter("add-process-action-success-action"), true);
069 alwaysSendRedirect = GetterUtil.getBoolean(
070 getInitParameter("always-send-redirect"));
071 }
072
073 @Override
074 public void processAction(
075 ActionRequest actionRequest, ActionResponse actionResponse)
076 throws IOException, PortletException {
077
078 try {
079 if (!isProcessActionRequest(actionRequest)) {
080 return;
081 }
082
083 if (!callActionMethod(actionRequest, actionResponse)) {
084 return;
085 }
086
087 if (!SessionErrors.isEmpty(actionRequest)) {
088 return;
089 }
090
091 boolean emptySessionMessages = SessionMessages.isEmpty(
092 actionRequest);
093
094 if (emptySessionMessages) {
095 addSuccessMessage(actionRequest, actionResponse);
096 }
097
098 if (emptySessionMessages || isAlwaysSendRedirect()) {
099 sendRedirect(actionRequest, actionResponse);
100 }
101 }
102 catch (PortletException pe) {
103 Throwable cause = pe.getCause();
104
105 if (isSessionErrorException(cause)) {
106 SessionErrors.add(actionRequest, cause.getClass(), cause);
107 }
108 else {
109 throw pe;
110 }
111 }
112 }
113
114 @Override
115 public void serveResource(
116 ResourceRequest resourceRequest, ResourceResponse resourceResponse)
117 throws IOException, PortletException {
118
119 if (!isProcessResourceRequest(resourceRequest)) {
120 return;
121 }
122
123 if (!callResourceMethod(resourceRequest, resourceResponse)) {
124 return;
125 }
126
127 if (!SessionErrors.isEmpty(resourceRequest)) {
128 return;
129 }
130
131 if (!SessionMessages.isEmpty(resourceRequest)) {
132 return;
133 }
134
135 super.serveResource(resourceRequest, resourceResponse);
136 }
137
138 protected void addSuccessMessage(
139 ActionRequest actionRequest, ActionResponse actionResponse) {
140
141 if (!addProcessActionSuccessMessage) {
142 return;
143 }
144
145 String successMessage = ParamUtil.getString(
146 actionRequest, "successMessage");
147
148 SessionMessages.add(actionRequest, "requestProcessed", successMessage);
149 }
150
151 protected boolean callActionMethod(
152 ActionRequest actionRequest, ActionResponse actionResponse)
153 throws PortletException {
154
155 String actionName = ParamUtil.getString(
156 actionRequest, ActionRequest.ACTION_NAME);
157
158 if (Validator.isNull(actionName) ||
159 actionName.equals("callActionMethod") ||
160 actionName.equals("processAction")) {
161
162 return false;
163 }
164
165 try {
166 Method method = getActionMethod(actionName);
167
168 method.invoke(this, actionRequest, actionResponse);
169
170 return true;
171 }
172 catch (NoSuchMethodException nsme) {
173 try {
174 super.processAction(actionRequest, actionResponse);
175
176 return true;
177 }
178 catch (Exception e) {
179 throw new PortletException(nsme);
180 }
181 }
182 catch (InvocationTargetException ite) {
183 Throwable cause = ite.getCause();
184
185 if (cause != null) {
186 throw new PortletException(cause);
187 }
188 else {
189 throw new PortletException(ite);
190 }
191 }
192 catch (Exception e) {
193 throw new PortletException(e);
194 }
195 }
196
197 protected boolean callResourceMethod(
198 ResourceRequest resourceRequest, ResourceResponse resourceResponse)
199 throws PortletException {
200
201 String actionName = ParamUtil.getString(
202 resourceRequest, ActionRequest.ACTION_NAME);
203
204 if (Validator.isNull(actionName) ||
205 actionName.equals("callResourceMethod") ||
206 actionName.equals("serveResource")) {
207
208 return false;
209 }
210
211 try {
212 Method method = getResourceMethod(actionName);
213
214 method.invoke(this, resourceRequest, resourceResponse);
215
216 return true;
217 }
218 catch (NoSuchMethodException nsme) {
219 try {
220 super.serveResource(resourceRequest, resourceResponse);
221
222 return true;
223 }
224 catch (Exception e) {
225 throw new PortletException(nsme);
226 }
227 }
228 catch (InvocationTargetException ite) {
229 Throwable cause = ite.getCause();
230
231 if (cause != null) {
232 throw new PortletException(cause);
233 }
234 else {
235 throw new PortletException(ite);
236 }
237 }
238 catch (Exception e) {
239 throw new PortletException(e);
240 }
241 }
242
243 @SuppressWarnings("unused")
244 protected void doAbout(
245 RenderRequest renderRequest, RenderResponse renderResponse)
246 throws IOException, PortletException {
247
248 throw new PortletException("doAbout method not implemented");
249 }
250
251 @SuppressWarnings("unused")
252 protected void doConfig(
253 RenderRequest renderRequest, RenderResponse renderResponse)
254 throws IOException, PortletException {
255
256 throw new PortletException("doConfig method not implemented");
257 }
258
259 @Override
260 protected void doDispatch(
261 RenderRequest renderRequest, RenderResponse renderResponse)
262 throws IOException, PortletException {
263
264 if (!isProcessRenderRequest(renderRequest)) {
265 renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.FALSE);
266
267 return;
268 }
269
270 WindowState windowState = renderRequest.getWindowState();
271
272 if (windowState.equals(WindowState.MINIMIZED)) {
273 return;
274 }
275
276 PortletMode portletMode = renderRequest.getPortletMode();
277
278 if (portletMode.equals(PortletMode.VIEW)) {
279 doView(renderRequest, renderResponse);
280 }
281 else if (portletMode.equals(LiferayPortletMode.ABOUT)) {
282 doAbout(renderRequest, renderResponse);
283 }
284 else if (portletMode.equals(LiferayPortletMode.CONFIG)) {
285 doConfig(renderRequest, renderResponse);
286 }
287 else if (portletMode.equals(PortletMode.EDIT)) {
288 doEdit(renderRequest, renderResponse);
289 }
290 else if (portletMode.equals(LiferayPortletMode.EDIT_DEFAULTS)) {
291 doEditDefaults(renderRequest, renderResponse);
292 }
293 else if (portletMode.equals(LiferayPortletMode.EDIT_GUEST)) {
294 doEditGuest(renderRequest, renderResponse);
295 }
296 else if (portletMode.equals(PortletMode.HELP)) {
297 doHelp(renderRequest, renderResponse);
298 }
299 else if (portletMode.equals(LiferayPortletMode.PREVIEW)) {
300 doPreview(renderRequest, renderResponse);
301 }
302 else if (portletMode.equals(LiferayPortletMode.PRINT)) {
303 doPrint(renderRequest, renderResponse);
304 }
305 else {
306 throw new PortletException(portletMode.toString());
307 }
308 }
309
310 @SuppressWarnings("unused")
311 protected void doEditDefaults(
312 RenderRequest renderRequest, RenderResponse renderResponse)
313 throws IOException, PortletException {
314
315 throw new PortletException("doEditDefaults method not implemented");
316 }
317
318 @SuppressWarnings("unused")
319 protected void doEditGuest(
320 RenderRequest renderRequest, RenderResponse renderResponse)
321 throws IOException, PortletException {
322
323 throw new PortletException("doEditGuest method not implemented");
324 }
325
326 @SuppressWarnings("unused")
327 protected void doPreview(
328 RenderRequest renderRequest, RenderResponse renderResponse)
329 throws IOException, PortletException {
330
331 throw new PortletException("doPreview method not implemented");
332 }
333
334 @SuppressWarnings("unused")
335 protected void doPrint(
336 RenderRequest renderRequest, RenderResponse renderResponse)
337 throws IOException, PortletException {
338
339 throw new PortletException("doPrint method not implemented");
340 }
341
342 protected Method getActionMethod(String actionName)
343 throws NoSuchMethodException {
344
345 Method method = _actionMethods.get(actionName);
346
347 if (method != null) {
348 return method;
349 }
350
351 Class<?> clazz = getClass();
352
353 method = clazz.getMethod(
354 actionName, ActionRequest.class, ActionResponse.class);
355
356 _actionMethods.put(actionName, method);
357
358 return method;
359 }
360
361 protected String getJSONContentType(PortletRequest portletRequest) {
362 HttpServletRequest request = PortalUtil.getHttpServletRequest(
363 portletRequest);
364
365 if (BrowserSnifferUtil.isIe(request)) {
366 return ContentTypes.TEXT_HTML;
367 }
368
369 return ContentTypes.APPLICATION_JSON;
370 }
371
372 protected String getRedirect(
373 ActionRequest actionRequest, ActionResponse actionResponse) {
374
375 String redirect = (String)actionRequest.getAttribute(WebKeys.REDIRECT);
376
377 if (Validator.isNull(redirect)) {
378 redirect = ParamUtil.getString(actionRequest, "redirect");
379 }
380
381 return redirect;
382 }
383
384 protected Method getResourceMethod(String actionName)
385 throws NoSuchMethodException {
386
387 Method method = _resourceMethods.get(actionName);
388
389 if (method != null) {
390 return method;
391 }
392
393 Class<?> clazz = getClass();
394
395 method = clazz.getMethod(
396 actionName, ResourceRequest.class, ResourceResponse.class);
397
398 _resourceMethods.put(actionName, method);
399
400 return method;
401 }
402
403 @Override
404 protected String getTitle(RenderRequest renderRequest) {
405 try {
406 return PortalUtil.getPortletTitle(renderRequest);
407 }
408 catch (Exception e) {
409 return super.getTitle(renderRequest);
410 }
411 }
412
413 protected boolean isAlwaysSendRedirect() {
414 return alwaysSendRedirect;
415 }
416
417 protected boolean isProcessActionRequest(ActionRequest actionRequest) {
418 return isProcessPortletRequest(actionRequest);
419 }
420
421 protected boolean isProcessPortletRequest(PortletRequest portletRequest) {
422 return _PROCESS_PORTLET_REQUEST;
423 }
424
425 protected boolean isProcessRenderRequest(RenderRequest renderRequest) {
426 return isProcessPortletRequest(renderRequest);
427 }
428
429 protected boolean isProcessResourceRequest(
430 ResourceRequest resourceRequest) {
431
432 return isProcessPortletRequest(resourceRequest);
433 }
434
435 protected boolean isSessionErrorException(Throwable cause) {
436 if (_log.isDebugEnabled()) {
437 _log.debug(cause, cause);
438 }
439
440 if (cause instanceof PortalException) {
441 return true;
442 }
443
444 return false;
445 }
446
447 protected void sendRedirect(
448 ActionRequest actionRequest, ActionResponse actionResponse)
449 throws IOException {
450
451 String redirect = getRedirect(actionRequest, actionResponse);
452
453 if (Validator.isNotNull(redirect)) {
454 actionResponse.sendRedirect(redirect);
455 }
456 }
457
458 protected String translate(PortletRequest portletRequest, String key) {
459 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
460 WebKeys.THEME_DISPLAY);
461
462 ResourceBundle resourceBundle = getResourceBundle(
463 themeDisplay.getLocale());
464
465 return LanguageUtil.get(resourceBundle, key);
466 }
467
468 protected String translate(
469 PortletRequest portletRequest, String key, Object... arguments) {
470
471 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
472 WebKeys.THEME_DISPLAY);
473
474 ResourceBundle resourceBundle = getResourceBundle(
475 themeDisplay.getLocale());
476
477 return LanguageUtil.format(resourceBundle, key, arguments);
478 }
479
480 protected void writeJSON(
481 PortletRequest portletRequest, ActionResponse actionResponse,
482 Object json)
483 throws IOException {
484
485 HttpServletResponse response = PortalUtil.getHttpServletResponse(
486 actionResponse);
487
488 response.setContentType(getJSONContentType(portletRequest));
489
490 ServletResponseUtil.write(response, json.toString());
491
492 response.flushBuffer();
493 }
494
495 protected void writeJSON(
496 PortletRequest portletRequest, MimeResponse mimeResponse,
497 Object json)
498 throws IOException {
499
500 mimeResponse.setContentType(getJSONContentType(portletRequest));
501
502 PortletResponseUtil.write(mimeResponse, json.toString());
503
504 mimeResponse.flushBuffer();
505 }
506
507 protected boolean addProcessActionSuccessMessage;
508 protected boolean alwaysSendRedirect;
509
510 private static final boolean _PROCESS_PORTLET_REQUEST = true;
511
512 private static final Log _log = LogFactoryUtil.getLog(LiferayPortlet.class);
513
514 private final Map<String, Method> _actionMethods =
515 new ConcurrentHashMap<String, Method>();
516 private final Map<String, Method> _resourceMethods =
517 new ConcurrentHashMap<String, Method>();
518
519 }