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