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