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