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