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