001
014
015 package com.liferay.portal.struts;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.portlet.LiferayPortletConfig;
020 import com.liferay.portal.kernel.portlet.LiferayPortletRequestDispatcher;
021 import com.liferay.portal.kernel.portlet.LiferayPortletURL;
022 import com.liferay.portal.kernel.util.CharPool;
023 import com.liferay.portal.kernel.util.JavaConstants;
024 import com.liferay.portal.kernel.util.StringPool;
025 import com.liferay.portal.kernel.util.Validator;
026 import com.liferay.portal.model.Layout;
027 import com.liferay.portal.model.Portlet;
028 import com.liferay.portal.security.auth.PrincipalException;
029 import com.liferay.portal.security.permission.ActionKeys;
030 import com.liferay.portal.security.permission.PermissionChecker;
031 import com.liferay.portal.service.PortletLocalServiceUtil;
032 import com.liferay.portal.service.permission.PortletPermissionUtil;
033 import com.liferay.portal.theme.ThemeDisplay;
034 import com.liferay.portal.util.PortalUtil;
035 import com.liferay.portal.util.PropsValues;
036 import com.liferay.portal.util.WebKeys;
037 import com.liferay.portlet.ActionResponseImpl;
038
039 import java.io.IOException;
040
041 import java.lang.reflect.Constructor;
042
043 import javax.portlet.ActionRequest;
044 import javax.portlet.ActionResponse;
045 import javax.portlet.EventRequest;
046 import javax.portlet.EventResponse;
047 import javax.portlet.PortletContext;
048 import javax.portlet.PortletException;
049 import javax.portlet.PortletRequest;
050 import javax.portlet.PortletResponse;
051 import javax.portlet.RenderRequest;
052 import javax.portlet.RenderResponse;
053 import javax.portlet.ResourceRequest;
054 import javax.portlet.ResourceResponse;
055
056 import javax.servlet.ServletException;
057 import javax.servlet.http.HttpServletRequest;
058 import javax.servlet.http.HttpServletResponse;
059
060 import org.apache.struts.Globals;
061 import org.apache.struts.action.Action;
062 import org.apache.struts.action.ActionErrors;
063 import org.apache.struts.action.ActionForm;
064 import org.apache.struts.action.ActionForward;
065 import org.apache.struts.action.ActionMapping;
066 import org.apache.struts.action.ActionServlet;
067 import org.apache.struts.config.ActionConfig;
068 import org.apache.struts.config.ForwardConfig;
069 import org.apache.struts.config.ModuleConfig;
070 import org.apache.struts.tiles.TilesRequestProcessor;
071 import org.apache.struts.util.MessageResources;
072
073
077 public class PortletRequestProcessor extends TilesRequestProcessor {
078
079 public static PortletRequestProcessor getInstance(
080 ActionServlet servlet, ModuleConfig moduleConfig)
081 throws ServletException {
082
083 try {
084 String className = PropsValues.STRUTS_PORTLET_REQUEST_PROCESSOR;
085
086 Class<?> clazz = Class.forName(className);
087
088 Constructor<?> constructor = clazz.getConstructor(
089 ActionServlet.class, ModuleConfig.class);
090
091 PortletRequestProcessor portletReqProcessor =
092 (PortletRequestProcessor)constructor.newInstance(
093 servlet, moduleConfig);
094
095 return portletReqProcessor;
096 }
097 catch (Exception e) {
098 _log.error(e);
099
100 return new PortletRequestProcessor(servlet, moduleConfig);
101 }
102 }
103
104 public PortletRequestProcessor(
105 ActionServlet actionServlet, ModuleConfig moduleConfig)
106 throws ServletException {
107
108 init(actionServlet, moduleConfig);
109 }
110
111 public void process(
112 ActionRequest actionRequest, ActionResponse actionResponse,
113 String path)
114 throws IOException, ServletException {
115
116 ActionResponseImpl actionResponseImpl =
117 (ActionResponseImpl)actionResponse;
118
119 HttpServletRequest request = PortalUtil.getHttpServletRequest(
120 actionRequest);
121 HttpServletResponse response = PortalUtil.getHttpServletResponse(
122 actionResponse);
123
124 ActionMapping actionMapping = processMapping(request, response, path);
125
126 if (actionMapping == null) {
127 return;
128 }
129
130 if (!processRoles(request, response, actionMapping, true)) {
131 return;
132 }
133
134 ActionForm actionForm = processActionForm(
135 request, response, actionMapping);
136
137 processPopulate(request, response, actionForm, actionMapping);
138
139 if (!processValidateAction(
140 request, response, actionForm, actionMapping)) {
141
142 return;
143 }
144
145 PortletAction portletAction = (PortletAction)processActionCreate(
146 request, response, actionMapping);
147
148 if (portletAction == null) {
149 return;
150 }
151
152 LiferayPortletConfig liferayPortletConfig =
153 (LiferayPortletConfig)actionRequest.getAttribute(
154 JavaConstants.JAVAX_PORTLET_CONFIG);
155
156 try {
157 if (portletAction.isCheckMethodOnProcessAction()) {
158 if (!PortalUtil.isMethodPost(actionRequest)) {
159 String currentURL = PortalUtil.getCurrentURL(actionRequest);
160
161 if (_log.isWarnEnabled()) {
162 _log.warn(
163 "This URL can only be invoked using POST: " +
164 currentURL);
165 }
166
167 throw new PrincipalException(currentURL);
168 }
169 }
170
171 portletAction.processAction(
172 actionMapping, actionForm, liferayPortletConfig, actionRequest,
173 actionResponse);
174 }
175 catch (Exception e) {
176 String exceptionId =
177 WebKeys.PORTLET_STRUTS_EXCEPTION + StringPool.PERIOD +
178 liferayPortletConfig.getPortletId();
179
180 actionRequest.setAttribute(exceptionId, e);
181 }
182
183 String forward = (String)actionRequest.getAttribute(
184 PortletAction.getForwardKey(actionRequest));
185
186 if (forward != null) {
187 String queryString = StringPool.BLANK;
188
189 int pos = forward.indexOf(CharPool.QUESTION);
190
191 if (pos != -1) {
192 queryString = forward.substring(pos + 1);
193 forward = forward.substring(0, pos);
194 }
195
196 ActionForward actionForward = actionMapping.findForward(forward);
197
198 if ((actionForward != null) && actionForward.getRedirect()) {
199 String forwardPath = actionForward.getPath();
200
201 if (forwardPath.startsWith(StringPool.SLASH)) {
202 LiferayPortletURL forwardURL =
203 (LiferayPortletURL)actionResponseImpl.createRenderURL();
204
205 forwardURL.setParameter("struts_action", forwardPath);
206
207 StrutsURLEncoder.setParameters(forwardURL, queryString);
208
209 forwardPath = forwardURL.toString();
210 }
211
212 actionResponse.sendRedirect(forwardPath);
213 }
214 }
215 }
216
217 public void process(EventRequest eventRequest, EventResponse eventResponse)
218 throws IOException, ServletException {
219
220 HttpServletRequest request = PortalUtil.getHttpServletRequest(
221 eventRequest);
222 HttpServletResponse response = PortalUtil.getHttpServletResponse(
223 eventResponse);
224
225 process(request, response);
226 }
227
228 public void process(
229 RenderRequest renderRequest, RenderResponse renderResponse)
230 throws IOException, ServletException {
231
232 HttpServletRequest request = PortalUtil.getHttpServletRequest(
233 renderRequest);
234 HttpServletResponse response = PortalUtil.getHttpServletResponse(
235 renderResponse);
236
237 process(request, response);
238 }
239
240 public void process(
241 ResourceRequest resourceRequest, ResourceResponse resourceResponse)
242 throws IOException, ServletException {
243
244 HttpServletRequest request = PortalUtil.getHttpServletRequest(
245 resourceRequest);
246 HttpServletResponse response = PortalUtil.getHttpServletResponse(
247 resourceResponse);
248
249 process(request, response);
250 }
251
252 @Override
253 public ActionMapping processMapping(
254 HttpServletRequest request, HttpServletResponse response, String path) {
255
256 if (path == null) {
257 return null;
258 }
259
260 ActionMapping actionMapping = null;
261
262 long companyId = PortalUtil.getCompanyId(request);
263
264 LiferayPortletConfig liferayPortletConfig =
265 (LiferayPortletConfig)request.getAttribute(
266 JavaConstants.JAVAX_PORTLET_CONFIG);
267
268 try {
269 Portlet portlet = PortletLocalServiceUtil.getPortletById(
270 companyId, liferayPortletConfig.getPortletId());
271
272 if (StrutsActionRegistryUtil.getAction(path) != null) {
273 actionMapping = (ActionMapping)moduleConfig.findActionConfig(
274 path);
275
276 if (actionMapping == null) {
277 actionMapping = new ActionMapping();
278
279 actionMapping.setModuleConfig(moduleConfig);
280 actionMapping.setPath(path);
281
282 request.setAttribute(Globals.MAPPING_KEY, actionMapping);
283 }
284 }
285 else if (moduleConfig.findActionConfig(path) != null) {
286 actionMapping = super.processMapping(request, response, path);
287 }
288 else if (Validator.isNotNull(portlet.getParentStrutsPath())) {
289 int pos = path.indexOf(StringPool.SLASH, 1);
290
291 String parentPath =
292 StringPool.SLASH + portlet.getParentStrutsPath() +
293 path.substring(pos);
294
295 if (StrutsActionRegistryUtil.getAction(parentPath) != null) {
296 actionMapping =
297 (ActionMapping)moduleConfig.findActionConfig(
298 parentPath);
299
300 if (actionMapping == null) {
301 actionMapping = new ActionMapping();
302
303 actionMapping.setModuleConfig(moduleConfig);
304 actionMapping.setPath(parentPath);
305
306 request.setAttribute(
307 Globals.MAPPING_KEY, actionMapping);
308 }
309 }
310 else if (moduleConfig.findActionConfig(parentPath) != null) {
311 actionMapping = super.processMapping(
312 request, response, parentPath);
313 }
314 }
315 }
316 catch (Exception e) {
317 }
318
319 if (actionMapping == null) {
320 MessageResources messageResources = getInternal();
321
322 String msg = messageResources.getMessage("processInvalid");
323
324 _log.error("User ID " + request.getRemoteUser());
325 _log.error("Current URL " + PortalUtil.getCurrentURL(request));
326 _log.error("Referer " + request.getHeader("Referer"));
327 _log.error("Remote address " + request.getRemoteAddr());
328
329 _log.error(msg + " " + path);
330 }
331
332 return actionMapping;
333 }
334
335 @Override
336 protected void doForward(
337 String uri, HttpServletRequest request,
338 HttpServletResponse response)
339 throws IOException, ServletException {
340
341 doInclude(uri, request, response);
342 }
343
344 @Override
345 protected void doInclude(
346 String uri, HttpServletRequest request,
347 HttpServletResponse response)
348 throws IOException, ServletException {
349
350 LiferayPortletConfig liferayPortletConfig =
351 (LiferayPortletConfig)request.getAttribute(
352 JavaConstants.JAVAX_PORTLET_CONFIG);
353
354 PortletContext portletContext =
355 liferayPortletConfig.getPortletContext();
356
357 PortletRequest portletRequest = (PortletRequest)request.getAttribute(
358 JavaConstants.JAVAX_PORTLET_REQUEST);
359
360 PortletResponse portletResponse = (PortletResponse)request.getAttribute(
361 JavaConstants.JAVAX_PORTLET_RESPONSE);
362
363 LiferayPortletRequestDispatcher liferayPortletRequestDispatcher =
364 (LiferayPortletRequestDispatcher)
365 portletContext.getRequestDispatcher(
366 StrutsUtil.TEXT_HTML_DIR + uri);
367
368 try {
369 if (liferayPortletRequestDispatcher == null) {
370 _log.error(uri + " is not a valid include");
371 }
372 else {
373 liferayPortletRequestDispatcher.include(
374 portletRequest, portletResponse, true);
375 }
376 }
377 catch (PortletException pe) {
378 Throwable cause = pe.getCause();
379
380 if (cause instanceof ServletException) {
381 throw (ServletException)cause;
382 }
383 else {
384 _log.error(cause, cause);
385 }
386 }
387 }
388
389 @Override
390 protected Action processActionCreate(
391 HttpServletRequest request, HttpServletResponse response,
392 ActionMapping actionMapping)
393 throws IOException {
394
395 PortletActionAdapter portletActionAdapter =
396 (PortletActionAdapter)StrutsActionRegistryUtil.getAction(
397 actionMapping.getPath());
398
399 if (portletActionAdapter != null) {
400 ActionConfig actionConfig = moduleConfig.findActionConfig(
401 actionMapping.getPath());
402
403 if (actionConfig != null) {
404 PortletAction originalPortletAction =
405 (PortletAction)super.processActionCreate(
406 request, response, actionMapping);
407
408 portletActionAdapter.setOriginalPortletAction(
409 originalPortletAction);
410 }
411
412 return portletActionAdapter;
413 }
414
415 return super.processActionCreate(request, response, actionMapping);
416 }
417
418 @Override
419 protected ActionForm processActionForm(
420 HttpServletRequest request, HttpServletResponse response,
421 ActionMapping actionMapping) {
422
423 ActionForm actionForm = super.processActionForm(
424 request, response, actionMapping);
425
426 if (actionForm instanceof InitializableActionForm) {
427 InitializableActionForm initializableActionForm =
428 (InitializableActionForm)actionForm;
429
430 initializableActionForm.init(request, response, actionMapping);
431 }
432
433 return actionForm;
434 }
435
436 @Override
437 protected ActionForward processActionPerform(
438 HttpServletRequest request, HttpServletResponse response,
439 Action action, ActionForm actionForm, ActionMapping actionMapping)
440 throws IOException, ServletException {
441
442 LiferayPortletConfig liferayPortletConfig =
443 (LiferayPortletConfig)request.getAttribute(
444 JavaConstants.JAVAX_PORTLET_CONFIG);
445
446 String exceptionId =
447 WebKeys.PORTLET_STRUTS_EXCEPTION + StringPool.PERIOD +
448 liferayPortletConfig.getPortletId();
449
450 Exception e = (Exception)request.getAttribute(exceptionId);
451
452 if (e != null) {
453 return processException(
454 request, response, e, actionForm, actionMapping);
455 }
456 else {
457 return super.processActionPerform(
458 request, response, action, actionForm, actionMapping);
459 }
460 }
461
462 @Override
463 protected void processForwardConfig(
464 HttpServletRequest request, HttpServletResponse response,
465 ForwardConfig forward)
466 throws IOException, ServletException {
467
468 if (forward == null) {
469 _log.error("Forward does not exist");
470 }
471 else {
472
473
474
475
476 if (forward.getPath().equals(ActionConstants.COMMON_NULL)) {
477 return;
478 }
479 }
480
481 super.processForwardConfig(request, response, forward);
482 }
483
484 @Override
485 protected HttpServletRequest processMultipart(HttpServletRequest request) {
486
487
488
489 return request;
490 }
491
492 @Override
493 protected String processPath(
494 HttpServletRequest request, HttpServletResponse response) {
495
496 String path = request.getParameter("struts_action");
497
498 if (_log.isDebugEnabled()) {
499 _log.debug("Getting request parameter path " + path);
500 }
501
502 if (Validator.isNull(path)) {
503 if (_log.isDebugEnabled()) {
504 _log.debug("Getting request attribute path " + path);
505 }
506
507 path = (String)request.getAttribute(WebKeys.PORTLET_STRUTS_ACTION);
508 }
509
510 if (path == null) {
511 LiferayPortletConfig liferayPortletConfig =
512 (LiferayPortletConfig)request.getAttribute(
513 JavaConstants.JAVAX_PORTLET_CONFIG);
514
515 _log.error(
516 liferayPortletConfig.getPortletName() +
517 " does not have any paths specified");
518 }
519 else {
520 if (_log.isDebugEnabled()) {
521 _log.debug("Processing path " + path);
522 }
523
524 request.removeAttribute(WebKeys.PORTLET_STRUTS_ACTION);
525 }
526
527 return path;
528 }
529
530 @Override
531 protected boolean processRoles(
532 HttpServletRequest request, HttpServletResponse response,
533 ActionMapping actionMapping)
534 throws IOException, ServletException {
535
536 return processRoles(request, response, actionMapping, false);
537 }
538
539 protected boolean processRoles(
540 HttpServletRequest request, HttpServletResponse response,
541 ActionMapping actionMapping, boolean action)
542 throws IOException, ServletException {
543
544 long companyId = PortalUtil.getCompanyId(request);
545
546 String path = actionMapping.getPath();
547
548 try {
549 LiferayPortletConfig liferayPortletConfig =
550 (LiferayPortletConfig)request.getAttribute(
551 JavaConstants.JAVAX_PORTLET_CONFIG);
552
553 Portlet portlet = PortletLocalServiceUtil.getPortletById(
554 companyId, liferayPortletConfig.getPortletId());
555
556 if (portlet == null) {
557 return false;
558 }
559
560 String strutsPath = path.substring(
561 1, path.lastIndexOf(CharPool.SLASH));
562
563 if (!strutsPath.equals(portlet.getStrutsPath()) &&
564 !strutsPath.equals(portlet.getParentStrutsPath())) {
565
566 if (_log.isWarnEnabled()) {
567 _log.warn(
568 "The struts path " + strutsPath + " does not belong " +
569 "to portlet " + portlet.getPortletId() + ". " +
570 "Check the definition in liferay-portlet.xml");
571 }
572
573 throw new PrincipalException();
574 }
575 else if (portlet.isActive()) {
576 if (PortalUtil.isAllowAddPortletDefaultResource(
577 request, portlet)) {
578
579 PortalUtil.addPortletDefaultResource(request, portlet);
580 }
581
582 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
583 WebKeys.THEME_DISPLAY);
584
585 Layout layout = themeDisplay.getLayout();
586 PermissionChecker permissionChecker =
587 themeDisplay.getPermissionChecker();
588
589 if (!PortletPermissionUtil.contains(
590 permissionChecker, layout, portlet, ActionKeys.VIEW)) {
591
592 throw new PrincipalException();
593 }
594 }
595 else if (!portlet.isActive()) {
596 ForwardConfig forwardConfig = actionMapping.findForward(
597 _PATH_PORTAL_PORTLET_INACTIVE);
598
599 if (!action) {
600 processForwardConfig(request, response, forwardConfig);
601 }
602
603 return false;
604 }
605 }
606 catch (Exception e) {
607 if (_log.isWarnEnabled()) {
608 _log.warn(e.getMessage());
609 }
610
611 ForwardConfig forwardConfig = actionMapping.findForward(
612 _PATH_PORTAL_PORTLET_ACCESS_DENIED);
613
614 if (!action) {
615 processForwardConfig(request, response, forwardConfig);
616 }
617
618 return false;
619 }
620
621 return true;
622 }
623
624 protected boolean processValidateAction(
625 HttpServletRequest request, HttpServletResponse response,
626 ActionForm actionForm, ActionMapping actionMapping) {
627
628 if (actionForm == null) {
629 return true;
630 }
631
632 if (request.getAttribute(Globals.CANCEL_KEY) != null) {
633 return true;
634 }
635
636 if (!actionMapping.getValidate()) {
637 return true;
638 }
639
640 ActionErrors errors = actionForm.validate(actionMapping, request);
641
642 if ((errors == null) || errors.isEmpty()) {
643 return true;
644 }
645
646 if (actionForm.getMultipartRequestHandler() != null) {
647 actionForm.getMultipartRequestHandler().rollback();
648 }
649
650 String input = actionMapping.getInput();
651
652 if (input == null) {
653 _log.error("Validation failed but no input form is available");
654
655 return false;
656 }
657
658 request.setAttribute(Globals.ERROR_KEY, errors);
659
660
661
662
663 request.setAttribute(PortletAction.getForwardKey(request), input);
664
665 return false;
666 }
667
668 private static final String _PATH_PORTAL_PORTLET_ACCESS_DENIED =
669 "/portal/portlet_access_denied";
670
671 private static final String _PATH_PORTAL_PORTLET_INACTIVE =
672 "/portal/portlet_inactive";
673
674 private static Log _log = LogFactoryUtil.getLog(
675 PortletRequestProcessor.class);
676
677 }