1 18 package org.apache.beehive.netui.pageflow; 19 20 import org.apache.beehive.netui.util.internal.InternalStringBuilder; 21 22 import org.apache.beehive.netui.core.urls.URLRewriterService; 23 import org.apache.beehive.netui.pageflow.config.PageFlowActionForward; 24 import org.apache.beehive.netui.pageflow.config.PageFlowActionMapping; 25 import org.apache.beehive.netui.pageflow.handler.ActionForwardHandler; 26 import org.apache.beehive.netui.pageflow.handler.FlowControllerHandlerContext; 27 import org.apache.beehive.netui.pageflow.handler.ForwardRedirectHandler; 28 import org.apache.beehive.netui.pageflow.handler.Handlers; 29 import org.apache.beehive.netui.pageflow.handler.LoginHandler; 30 import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler; 31 import org.apache.beehive.netui.pageflow.interceptor.InterceptorException; 32 import org.apache.beehive.netui.pageflow.interceptor.Interceptors; 33 import org.apache.beehive.netui.pageflow.interceptor.Interceptor; 34 import org.apache.beehive.netui.pageflow.interceptor.action.ActionInterceptorContext; 35 import org.apache.beehive.netui.pageflow.interceptor.action.InterceptorForward; 36 import org.apache.beehive.netui.pageflow.interceptor.action.internal.ActionInterceptors; 37 import org.apache.beehive.netui.pageflow.interceptor.request.RequestInterceptorContext; 38 import org.apache.beehive.netui.pageflow.internal.AdapterManager; 39 import org.apache.beehive.netui.pageflow.internal.DefaultURLRewriter; 40 import org.apache.beehive.netui.pageflow.internal.FlowControllerAction; 41 import org.apache.beehive.netui.pageflow.internal.InternalUtils; 42 import org.apache.beehive.netui.pageflow.internal.JavaControlUtils; 43 import org.apache.beehive.netui.pageflow.internal.LegacySettings; 44 import org.apache.beehive.netui.pageflow.internal.PageFlowRequestWrapper; 45 import org.apache.beehive.netui.pageflow.internal.InternalConstants; 46 import org.apache.beehive.netui.pageflow.scoping.ScopedRequest; 47 import org.apache.beehive.netui.pageflow.scoping.ScopedServletUtils; 48 import org.apache.beehive.netui.script.common.ImplicitObjectUtil; 49 import org.apache.beehive.netui.util.internal.DiscoveryUtils; 50 import org.apache.beehive.netui.util.internal.FileUtils; 51 import org.apache.beehive.netui.util.internal.ServletUtils; 52 import org.apache.beehive.netui.util.config.ConfigUtil; 53 import org.apache.beehive.netui.util.config.bean.PageflowConfig; 54 import org.apache.beehive.netui.util.logging.Logger; 55 import org.apache.struts.Globals; 56 import org.apache.struts.action.Action; 57 import org.apache.struts.action.ActionForm; 58 import org.apache.struts.action.ActionForward; 59 import org.apache.struts.action.ActionMapping; 60 import org.apache.struts.action.ActionServlet; 61 import org.apache.struts.action.DynaActionForm; 62 import org.apache.struts.action.DynaActionFormClass; 63 import org.apache.struts.config.ActionConfig; 64 import org.apache.struts.config.FormBeanConfig; 65 import org.apache.struts.config.ForwardConfig; 66 import org.apache.struts.config.ModuleConfig; 67 import org.apache.struts.tiles.TilesRequestProcessor; 68 import org.apache.struts.tiles.TilesUtil; 69 import org.apache.struts.tiles.TilesUtilImpl; 70 import org.apache.struts.tiles.TilesUtilStrutsImpl; 71 import org.apache.struts.upload.MultipartRequestHandler; 72 import org.apache.struts.upload.MultipartRequestWrapper; 73 import org.apache.struts.util.RequestUtils; 74 import org.apache.struts.util.TokenProcessor; 75 76 import javax.servlet.FilterChain ; 77 import javax.servlet.Servlet ; 78 import javax.servlet.ServletConfig ; 79 import javax.servlet.ServletContext ; 80 import javax.servlet.ServletException ; 81 import javax.servlet.ServletRequest ; 82 import javax.servlet.ServletResponse ; 83 import javax.servlet.http.HttpServletRequest ; 84 import javax.servlet.http.HttpServletResponse ; 85 import javax.servlet.http.HttpSession ; 86 import java.io.IOException ; 87 import java.io.InputStream ; 88 import java.io.Serializable ; 89 import java.lang.reflect.Field ; 90 import java.net.URI ; 91 import java.net.URISyntaxException ; 92 import java.util.ArrayList ; 93 import java.util.Collections ; 94 import java.util.Enumeration ; 95 import java.util.HashMap ; 96 import java.util.Iterator ; 97 import java.util.List ; 98 import java.util.Map ; 99 import java.util.Properties ; 100 import java.util.Set ; 101 import org.apache.beehive.netui.util.internal.concurrent.InternalConcurrentHashMap; 102 103 104 109 public class PageFlowRequestProcessor 110 extends TilesRequestProcessor 111 implements Serializable , InternalConstants, PageFlowConstants 112 { 113 private static int requestCount = 0; 114 115 private static final Logger _log = Logger.getInstance( PageFlowRequestProcessor.class ); 116 117 private static final String ACTION_OVERRIDE_PARAM_PREFIX = "actionOverride:"; 118 private static final int ACTION_OVERRIDE_PARAM_PREFIX_LEN = ACTION_OVERRIDE_PARAM_PREFIX.length(); 119 private static final String SCHEME_UNSECURE = "http"; 120 private static final String SCHEME_SECURE = "https"; 121 private static final String REDIRECT_REQUEST_ATTRS_PREFIX = InternalConstants.ATTR_PREFIX + "requestAttrs:"; 122 private static final String REDIRECT_REQUEST_ATTRS_PARAM = "forceRedirect"; 123 private static final String FLOW_CONTROLLER_ACTION_CLASSNAME = FlowControllerAction.class.getName(); 124 125 private Map _formBeanClasses = new HashMap (); 126 private Map _overloadedActions = new HashMap (); 127 private ServletContainerAdapter _servletContainerAdapter; 128 private Handlers _handlers; 129 private FlowControllerFactory _flowControllerFactory; 130 private LegacySettings _legacySettings; 131 private InternalConcurrentHashMap _pageServletClasses = new InternalConcurrentHashMap(); 132 private PageFlowPageFilter _pageServletFilter; 133 134 135 protected Action processActionCreate( HttpServletRequest request, HttpServletResponse response, 136 ActionMapping actionMapping ) 137 throws IOException 138 { 139 String className = actionMapping.getType(); 140 141 if ( className != null && className.equals( FLOW_CONTROLLER_ACTION_CLASSNAME ) ) 142 { 143 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 144 assert fc != null : "no FlowController for request " + request.getRequestURI(); 145 assert fc.getClass().getName().equals( actionMapping.getParameter() ) 146 : "current page flow type " + fc.getClass().getName() + " does not match type specified in " 147 + FLOW_CONTROLLER_ACTION_CLASSNAME + ": " + actionMapping.getParameter(); 148 149 Action action = new FlowControllerAction( fc ); 150 action.setServlet( servlet ); 151 return action; 152 } 153 154 return super.processActionCreate( request, response, actionMapping ); 155 } 156 157 161 private ActionForm createActionForm( ActionMapping mapping, HttpServletRequest request ) 162 { 163 String name = mapping.getName(); 164 165 assert name != null : mapping.getPath(); 166 if ( name == null ) return null; 167 168 FormBeanConfig config = moduleConfig.findFormBeanConfig( name ); 169 ActionForm instance; 170 171 if ( config.getDynamic() ) 175 { 176 try 177 { 178 DynaActionFormClass dynaClass = DynaActionFormClass.createDynaActionFormClass( config ); 179 instance = ( ActionForm ) dynaClass.newInstance(); 180 ( ( DynaActionForm ) instance ).initialize( mapping ); 181 182 if ( _log.isDebugEnabled() ) 183 { 184 _log.debug( " Creating new DynaActionForm instance " + "of type '" + config.getType() + '\'' ); 185 } 186 } 187 catch ( Exception e ) 188 { 189 _log.error( servlet.getInternal().getMessage( "formBean", config.getType() ), e ); 190 return null; 191 } 192 } 193 else 194 { 195 try 196 { 197 instance = ( ActionForm ) InternalUtils.newReloadableInstance( config.getType(), getServletContext() ); 198 199 if ( _log.isDebugEnabled() ) 200 { 201 _log.debug( " Creating new ActionForm instance " + "of type '" + config.getType() + '\'' ); 202 } 203 } 204 catch ( Exception e ) 205 { 206 _log.error( servlet.getInternal().getMessage( "formBean", config.getType() ), e ); 207 return null; 208 } 209 } 210 211 instance.setServlet( servlet ); 212 return instance; 213 } 214 215 private Field getPageFlowScopedFormMember( ActionMapping mapping, HttpServletRequest request ) 216 { 217 if ( mapping instanceof PageFlowActionMapping ) 218 { 219 PageFlowActionMapping pfam = ( PageFlowActionMapping ) mapping; 220 String formMember = pfam.getFormMember(); 221 222 try 223 { 224 if ( formMember != null ) 225 { 226 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 227 Field field = fc.getClass().getDeclaredField( formMember ); 228 field.setAccessible( true ); 229 return field; 230 } 231 } 232 catch ( Exception e ) 233 { 234 _log.error( "Could not use page flow member " + formMember + " as the form bean.", e ); 235 } 236 } 237 238 return null; 239 } 240 241 protected ActionForm processActionForm( HttpServletRequest request, HttpServletResponse response, 242 ActionMapping mapping ) 243 { 244 Field formMemberField = getPageFlowScopedFormMember( mapping, request ); 248 249 ActionForm previousForm = InternalUtils.getForwardedFormBean( request, false ); 257 258 if ( previousForm != null ) 259 { 260 if ( formMemberField != null ) 265 { 266 try 267 { 268 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 269 assert fc != null : "no FlowController in request " + request.getRequestURI(); 270 formMemberField.set( fc, InternalUtils.unwrapFormBean( previousForm ) ); 271 } 272 catch ( IllegalAccessException e ) 273 { 274 _log.error( "Could not access page flow member " + formMemberField.getName() 275 + " as the form bean.", e ); 276 } 277 } 278 279 previousForm.setServlet( servlet ); 283 return previousForm; 284 } 285 286 String pageFlowScopedFormName = PageFlowRequestWrapper.get( request ).getPageFlowScopedFormName(); 291 if ( pageFlowScopedFormName != null ) 292 { 293 request.removeAttribute( pageFlowScopedFormName ); 294 PageFlowRequestWrapper.get( request ).setPageFlowScopedFormName( null ); 295 } 296 297 if ( formMemberField != null ) 301 { 302 try 303 { 304 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 305 ActionForm form = InternalUtils.wrapFormBean( formMemberField.get( fc ) ); 306 307 if ( form == null ) { 309 form = createActionForm( mapping, request ); 310 form.reset( mapping, request ); 311 formMemberField.set( fc, InternalUtils.unwrapFormBean( form ) ); 312 } 313 314 String formAttrName = mapping.getAttribute(); 321 request.setAttribute( formAttrName, form ); 322 PageFlowRequestWrapper.get( request ).setPageFlowScopedFormName( formAttrName ); 323 return form; 324 } 325 catch ( IllegalAccessException e ) 326 { 327 _log.error( "Could not access page flow member " + formMemberField.getName() + " as the form bean.", e ); 328 } 329 } 330 331 ActionForm bean = super.processActionForm( request, response, mapping ); 332 if ( bean == null ) 333 { 334 bean = InternalUtils.createActionForm( mapping, moduleConfig, servlet, getServletContext() ); 335 } 336 337 return bean; 338 } 339 340 protected void processPopulate( HttpServletRequest request, HttpServletResponse response, ActionForm form, 341 ActionMapping mapping ) 342 throws ServletException 343 { 344 ActionForm previousForm = InternalUtils.getForwardedFormBean( request, true ); 348 349 if ( previousForm != null ) 350 { 351 return; 352 } 353 354 if ( _log.isDebugEnabled() ) 355 { 356 _log.debug( "Populating bean properties from this request" ); 357 } 358 359 if ( form != null ) 361 { 362 form.setServlet( servlet ); 363 form.reset( mapping, request ); 364 } 365 366 if ( mapping.getMultipartClass() != null ) 367 { 368 request.setAttribute( Globals.MULTIPART_KEY, mapping.getMultipartClass() ); 369 } 370 371 PageFlowRequestWrapper requestWrapper = PageFlowRequestWrapper.get( request ); 372 boolean alreadyCalledInRequest = requestWrapper.isProcessPopulateAlreadyCalled(); 373 if ( ! alreadyCalledInRequest ) requestWrapper.setProcessPopulateAlreadyCalled( true ); 374 375 if ( !alreadyCalledInRequest || form != null ) 381 { 382 ProcessPopulate.populate( request, response, form, alreadyCalledInRequest ); 383 } 384 } 385 386 397 protected boolean processActionOverride( HttpServletRequest request, HttpServletResponse response ) 398 throws IOException , ServletException 399 { 400 PageFlowRequestWrapper wrapper = PageFlowRequestWrapper.get( request ); 405 if ( ! wrapper.isForwardedByButton() ) 406 { 407 wrapper.setForwardedByButton( true ); 408 409 HttpServletRequest multipartAwareRequest = processMultipart( request ); 415 416 for ( Enumeration e = multipartAwareRequest.getParameterNames(); e.hasMoreElements(); ) 417 { 418 String paramName = ( String ) e.nextElement(); 419 420 if ( paramName.startsWith( ACTION_OVERRIDE_PARAM_PREFIX ) ) 421 { 422 String actionPath = paramName.substring( ACTION_OVERRIDE_PARAM_PREFIX_LEN ); 423 ServletContext servletContext = getServletContext(); 424 425 String qualifiedAction = InternalUtils.qualifyAction( servletContext,actionPath ); 426 actionPath = InternalUtils.createActionPath(request, qualifiedAction ); 427 428 if ( _log.isDebugEnabled() ) 429 { 430 _log.debug( "A request parameter overrode the action. Forwarding to: " + actionPath ); 431 } 432 433 doForward( actionPath, request, response ); 434 return true; 435 } 436 } 437 } 438 439 return false; 440 } 441 442 private void processInternal( HttpServletRequest request, HttpServletResponse response ) 443 throws IOException , ServletException 444 { 445 request = PageFlowRequestWrapper.wrapRequest( request ); 450 451 String uri = InternalUtils.getDecodedServletPath( request ); 452 ServletContext servletContext = getServletContext(); 453 454 if ( LegacySettings.get( servletContext ).shouldDoSecureForwards() 458 && PageFlowRequestWrapper.get( request ).isForwardedRequest() ) 459 { 460 if ( _servletContainerAdapter.doSecurityRedirect( uri, request, response ) ) 466 { 467 if ( _log.isDebugEnabled() ) 468 { 469 _log.debug( "checkSecurity() caused a redirect. Ending processing for this request " 470 + '(' + uri + ')' ); 471 } 472 473 return; 474 } 475 } 476 477 String hash = request.getParameter( REDIRECT_REQUEST_ATTRS_PARAM ); 482 if ( hash != null ) 483 { 484 HttpSession session = request.getSession( false ); 485 486 if ( session != null ) 487 { 488 String carryoverAttrName = makeRedirectedRequestAttrsKey( uri, hash ); 489 Map attrs = ( Map ) session.getAttribute( carryoverAttrName ); 490 session.removeAttribute( carryoverAttrName ); 491 492 if ( attrs != null ) 493 { 494 for ( Iterator i = attrs.entrySet().iterator(); i.hasNext(); ) 495 { 496 Map.Entry entry = ( Map.Entry ) i.next(); 497 498 String attrName = ( String ) entry.getKey(); 499 if ( request.getAttribute( attrName ) == null ) 500 { 501 request.setAttribute( attrName, entry.getValue() ); 502 } 503 } 504 } 505 } 506 } 507 508 if ( processActionOverride( request, response ) ) return; 513 514 if ( processPageFlowRequest( request, response, uri ) ) return; 518 519 String flowControllerClassName = InternalUtils.getFlowControllerClassName( moduleConfig ); 523 524 if ( flowControllerClassName == null && 525 ! ( moduleConfig instanceof AutoRegisterActionServlet.MissingRootModuleControllerConfig ) ) 526 { 527 _log.warn( "Struts module " + moduleConfig.getPrefix() + " is configured to use " + getClass().getName() 532 + " as the request processor, but the <controller> element does not contain a <set-property>" 533 + " for \"controllerClass\". Page Flow actions in this module may not be handled correctly." ); 534 } 535 536 if ( _log.isInfoEnabled() ) 540 { 541 _log.info( "Attempting to instantiate SharedFlowControllers for request " + request.getRequestURI() ); 542 } 543 544 FlowController currentFlowController = null; 545 546 try 547 { 548 RequestContext requestContext = new RequestContext( request, response ); 549 Map sharedFlows = 550 _flowControllerFactory.getSharedFlowsForRequest( requestContext ); 551 ImplicitObjectUtil.loadSharedFlow( request, sharedFlows ); 552 ImplicitObjectUtil.loadGlobalApp( request, PageFlowUtils.getGlobalApp( request ) ); 553 554 if ( flowControllerClassName != null ) 555 { 556 currentFlowController = getFlowController( requestContext, flowControllerClassName ); 557 PageFlowRequestWrapper.get( request ).setCurrentFlowController( currentFlowController ); 558 } 559 else 560 { 561 PageFlowRequestWrapper.get( request ).setCurrentFlowController( null ); 562 } 563 } 564 catch ( ClassNotFoundException e ) 565 { 566 _log.error( "Could not find FlowController class " + flowControllerClassName, e ); 567 throw new ServletException ( e ); 568 } 569 catch ( InstantiationException e ) 570 { 571 _log.error( "Could not instantiate FlowController of type " + flowControllerClassName, e ); 572 throw new ServletException ( e ); 573 } 574 catch ( IllegalAccessException e ) 575 { 576 _log.error( "Could not instantiate FlowController of type " + flowControllerClassName, e ); 577 throw new ServletException ( e ); 578 } 579 580 PageFlowController jpf = PageFlowUtils.getCurrentPageFlow( request ); 584 585 ImplicitObjectUtil.loadImplicitObjects( request, response, servletContext, jpf ); 589 590 try 591 { 592 super.process( request, response ); 593 } 594 catch ( ServletException servletEx ) 595 { 596 if ( ! handleException( servletEx, currentFlowController, request, response ) ) throw servletEx; 598 } 599 catch ( IOException ioe ) 600 { 601 if ( ! handleException( ioe, currentFlowController, request, response ) ) throw ioe; 603 } 604 catch ( Throwable th ) 605 { 606 if ( ! handleException( th, currentFlowController, request, response ) ) throw new ServletException ( th ); 608 } 609 } 610 611 private FlowController getFlowController( RequestContext requestContext, String fcClassName ) 612 throws ClassNotFoundException , InstantiationException , IllegalAccessException 613 { 614 Class fcClass = _flowControllerFactory.getFlowControllerClass( fcClassName ); 615 HttpServletRequest request = requestContext.getHttpRequest(); 616 HttpServletResponse response = requestContext.getHttpResponse(); 617 618 if ( PageFlowController.class.isAssignableFrom( fcClass ) ) 619 { 620 PageFlowController current = PageFlowUtils.getCurrentPageFlow( request ); 621 622 if ( current != null && current.getClass().equals( fcClass ) ) 623 { 624 if ( _log.isDebugEnabled() ) 625 { 626 _log.debug( "Using current page flow: " + current ); 627 } 628 629 current.reinitialize( request, response, getServletContext() ); 633 return current; 634 } 635 636 return _flowControllerFactory.createPageFlow( new RequestContext( request, response ), fcClass ); 637 } 638 else 639 { 640 assert SharedFlowController.class.isAssignableFrom( fcClass ) : fcClass.getName(); 641 642 SharedFlowController current = PageFlowUtils.getSharedFlow( fcClass.getName(), request ); 643 644 if ( current != null ) 645 { 646 current.reinitialize( request, response, getServletContext() ); 647 return current; 648 } 649 650 return _flowControllerFactory.createSharedFlow( new RequestContext( request, response ), fcClass ); 651 } 652 } 653 654 private boolean handleException( Throwable th, FlowController fc, HttpServletRequest request, 655 HttpServletResponse response ) 656 { 657 if ( fc != null ) 658 { 659 try 660 { 661 ActionMapping mapping = InternalUtils.getCurrentActionMapping( request ); 662 ActionForm form = InternalUtils.getCurrentActionForm( request ); 663 ActionForward fwd = fc.handleException( th, mapping, form, request, response ); 664 processForwardConfig( request, response, fwd ); 665 return true; 666 } 667 catch ( Throwable t ) 668 { 669 _log.error( "Exception while handling exception " + th.getClass().getName() 670 + ". The original exception will be thrown.", th ); 671 return false; 672 } 673 } 674 675 return false; 676 } 677 678 688 protected boolean processPageFlowRequest( HttpServletRequest request, HttpServletResponse response, String uri ) 689 throws IOException , ServletException 690 { 691 if ( FileUtils.osSensitiveEndsWith( uri, PageFlowConstants.PAGEFLOW_EXTENSION ) ) 695 { 696 String modulePath = PageFlowUtils.getModulePath( request ); 701 if ( ! moduleConfig.getPrefix().equals( modulePath ) ) 702 { 703 if ( _log.isErrorEnabled() ) 704 { 705 InternalStringBuilder msg = new InternalStringBuilder( "No module configuration registered for " ); 706 msg.append( uri ).append( " (module path " ).append( modulePath ).append( ")." ); 707 _log.error( msg.toString() ); 708 } 709 710 if ( modulePath.length() == 0 ) modulePath = "/"; 711 InternalUtils.sendDevTimeError( "PageFlow_NoModuleConf", null, 712 HttpServletResponse.SC_INTERNAL_SERVER_ERROR, request, response, 713 getServletContext(), new Object []{ uri, modulePath } ); 714 return true; 715 } 716 717 ActionMapping beginMapping = getBeginMapping(); 721 if ( beginMapping != null ) 722 { 723 String desiredType = beginMapping.getParameter(); 724 desiredType = desiredType.substring( desiredType.lastIndexOf( '.' ) + 1 ) + JPF_EXTENSION; 725 String requestedType = InternalUtils.getDecodedServletPath( request ); 726 requestedType = requestedType.substring( requestedType.lastIndexOf( '/' ) + 1 ); 727 728 if ( ! requestedType.equals( desiredType ) ) 729 { 730 if ( _log.isDebugEnabled() ) 731 { 732 _log.debug( "Wrong .jpf requested for this directory: got " + requestedType 733 + ", expected " + desiredType ); 734 } 735 736 if ( _log.isErrorEnabled() ) 737 { 738 InternalStringBuilder msg = new InternalStringBuilder( "Wrong .jpf requested for this directory: got " ); 739 msg.append( requestedType ).append( ", expected " ).append( desiredType ).append( '.' ); 740 _log.error( msg.toString() ); 741 } 742 743 InternalUtils.sendDevTimeError( "PageFlow_WrongPath", null, 744 HttpServletResponse.SC_INTERNAL_SERVER_ERROR, request, response, 745 getServletContext(), new Object []{ requestedType, desiredType } ); 746 747 return true; 748 } 749 } 750 751 uri = PageFlowUtils.getBeginActionURI( uri ); 752 753 if ( _log.isDebugEnabled() ) 754 { 755 _log.debug( "Got request for " + request.getRequestURI() + ", forwarding to " + uri ); 756 } 757 758 doForward( uri, request, response ); 759 return true; 760 } 761 762 return false; 763 } 764 765 770 private static class RehydratedMultipartRequestWrapper extends MultipartRequestWrapper 771 { 772 public RehydratedMultipartRequestWrapper( HttpServletRequest req ) 773 { 774 super( req ); 775 776 MultipartRequestHandler handler = MultipartRequestUtils.getCachedMultipartHandler( req ); 777 778 if ( handler != null ) 779 { 780 ScopedRequest scopedRequest = ScopedServletUtils.unwrapRequest( req ); 781 Map textElements = handler.getTextElements(); 782 parameters = scopedRequest != null ? scopedRequest.filterParameterMap( textElements ) : textElements; 783 } 784 } 785 } 786 787 public void process( HttpServletRequest request, HttpServletResponse response ) 788 throws IOException , ServletException 789 { 790 int localRequestCount = -1; 791 792 if ( _log.isTraceEnabled() ) 793 { 794 localRequestCount = ++requestCount; 795 _log.trace( "------------------------------- Start Request #" + localRequestCount 796 + " -----------------------------------" ); 797 } 798 799 ServletContext servletContext = getServletContext(); 803 _handlers.getReloadableClassHandler().reloadClasses( new RequestContext( request, response ) ); 804 805 RequestInterceptorContext context = new RequestInterceptorContext( request, response, getServletContext() ); 809 List interceptors = context.getRequestInterceptors(); 810 811 try 812 { 813 Interceptors.doPreIntercept( context, interceptors ); 814 815 if ( context.requestWasCancelled() ) 816 { 817 if ( _log.isDebugEnabled() ) 818 { 819 _log.debug ( "Interceptor " + context.getOverridingInterceptor() + " cancelled the request." ); 820 } 821 822 return; 823 } 824 } 825 catch ( InterceptorException e ) 826 { 827 throw new ServletException ( e ); 828 } 829 830 InternalUtils.setServletContext( request, servletContext ); 835 836 PageFlowEventReporter er = _servletContainerAdapter.getEventReporter(); 840 _servletContainerAdapter.beginRequest( request, response ); 841 er.beginActionRequest( request, response ); 842 long startTime = System.currentTimeMillis(); 843 844 JavaControlUtils.initializeControlContext( request, response, servletContext ); 848 849 URLRewriterService.registerURLRewriter( 0, request, new DefaultURLRewriter() ); 853 854 try 855 { 856 processInternal( request, response ); 857 } 858 finally 859 { 860 JavaControlUtils.uninitializeControlContext( request, response, getServletContext() ); 864 865 _servletContainerAdapter.endRequest( request, response ); 869 long timeTaken = System.currentTimeMillis() - startTime; 870 er.endActionRequest( request, response, timeTaken ); 871 } 872 873 try 877 { 878 Interceptors.doPostIntercept( context, interceptors ); 879 } 880 catch ( InterceptorException e ) 881 { 882 throw new ServletException ( e ); 883 } 884 885 if ( _log.isTraceEnabled() ) 886 { 887 _log.trace( "-------------------------------- End Request #" + localRequestCount 888 + " ------------------------------------" ); 889 } 890 } 891 892 897 protected HttpServletRequest processMultipart( HttpServletRequest request ) 898 { 899 if ( ! "POST".equalsIgnoreCase( request.getMethod() ) ) return request; 900 901 String contentType = request.getContentType(); 902 if ( contentType != null && contentType.startsWith( "multipart/form-data" ) ) 903 { 904 PageFlowRequestWrapper pageFlowRequestWrapper = PageFlowRequestWrapper.get( request ); 905 906 MultipartRequestWrapper cachedWrapper = pageFlowRequestWrapper.getMultipartRequestWrapper(); 910 911 if ( cachedWrapper != null && cachedWrapper.getRequest() == request ) return cachedWrapper; 912 913 try 914 { 915 MultipartRequestUtils.preHandleMultipartRequest( request ); 920 } 921 catch ( ServletException e ) 922 { 923 _log.error( "Could not parse multipart request.", e.getRootCause() ); 924 return request; 925 } 926 927 MultipartRequestWrapper ret = new RehydratedMultipartRequestWrapper( request ); 928 pageFlowRequestWrapper.setMultipartRequestWrapper( ret ); 929 return ret; 930 } 931 else 932 { 933 return request; 934 } 935 936 } 937 938 protected ActionMapping getBeginMapping() 939 { 940 return ( ActionMapping ) moduleConfig.findActionConfig( BEGIN_ACTION_PATH ); 941 } 942 943 private static String makeRedirectedRequestAttrsKey( String webappRelativeURI, String hash ) 944 { 945 return REDIRECT_REQUEST_ATTRS_PREFIX + hash + webappRelativeURI; 946 } 947 948 public ActionForward processException( HttpServletRequest request, HttpServletResponse response, 949 Exception ex, ActionForm form, ActionMapping mapping ) 950 throws IOException , ServletException 951 { 952 958 return super.processException( request, response, ex, form, mapping ); 959 } 960 961 965 protected static class ExceptionHandledActionMapping extends ActionMapping 966 { 967 private ActionForward _fwd; 968 969 public ExceptionHandledActionMapping( String actionPath, ActionForward fwd ) 970 { 971 setPath( actionPath ); 972 _fwd = fwd; 973 } 974 975 public String getType() 976 { 977 return ExceptionHandledAction.class.getName(); 978 } 979 980 public ActionForward getActionForward() 981 { 982 return _fwd; 983 } 984 985 public boolean getValidate() 986 { 987 return false; 988 } 989 } 990 991 995 public static class ExceptionHandledAction extends Action 996 { 997 public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, 998 HttpServletResponse response ) 999 { 1000 assert mapping instanceof ExceptionHandledActionMapping : mapping.getClass().getName(); 1001 1002 return ( ( ExceptionHandledActionMapping ) mapping ).getActionForward(); 1003 } 1004 } 1005 1006 private boolean isCorrectFormType( Class formBeanClass, ActionMapping mapping ) 1007 { 1008 assert mapping.getName() != null : "cannot pass an ActionMapping that has no form bean"; 1009 Class cachedFormBeanClass = ( Class ) _formBeanClasses.get( mapping.getName() ); 1010 return isCorrectFormType( formBeanClass, cachedFormBeanClass, mapping ); 1011 } 1012 1013 private boolean isCorrectFormType( Class formBeanClass, Class actionMappingFormBeanClass, ActionMapping mapping ) 1014 { 1015 if ( actionMappingFormBeanClass != null ) 1016 { 1017 return actionMappingFormBeanClass .isAssignableFrom( formBeanClass ); 1018 } 1019 else 1020 { 1021 FormBeanConfig mappingFormBean = moduleConfig.findFormBeanConfig( mapping.getName() ); 1025 String formClassName = formBeanClass.getName(); 1026 1027 if ( mappingFormBean != null && mappingFormBean.getType().equals( formClassName ) ) return true; 1028 1029 if ( mapping instanceof PageFlowActionMapping ) 1030 { 1031 String desiredType = ( ( PageFlowActionMapping ) mapping ).getFormClass(); 1032 if ( formClassName.equals( desiredType ) ) return true; 1033 } 1034 } 1035 1036 return false; 1037 } 1038 1039 private ActionMapping checkTransaction( HttpServletRequest request, HttpServletResponse response, 1040 ActionMapping mapping, String actionPath ) 1041 throws IOException 1042 { 1043 if ( mapping instanceof PageFlowActionMapping && ( ( PageFlowActionMapping ) mapping ).isPreventDoubleSubmit() ) 1044 { 1045 if ( ! TokenProcessor.getInstance().isTokenValid( request, true ) ) 1046 { 1047 FlowController currentFC = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1048 String actionName = InternalUtils.getActionName( mapping ); 1049 DoubleSubmitException ex = new DoubleSubmitException( actionName, currentFC ); 1050 1051 if ( currentFC != null ) 1052 { 1053 try 1054 { 1055 ActionForward fwd = currentFC.handleException( ex, mapping, null, request, response ); 1056 return new ExceptionHandledActionMapping( actionPath, fwd ); 1057 } 1058 catch ( ServletException servletException) 1059 { 1060 _log.error( "Exception occurred while handling " + ex.getClass().getName(), servletException ); 1061 } 1062 } 1063 1064 ex.sendResponseErrorCode( response ); 1065 return null; 1066 } 1067 } 1068 1069 return mapping; 1070 } 1071 1072 public void init( ActionServlet actionServlet, ModuleConfig mc ) 1073 throws ServletException 1074 { 1075 super.init( actionServlet, mc ); 1076 1077 ServletContext servletContext = getServletContext(); 1078 1079 _servletContainerAdapter = AdapterManager.getServletContainerAdapter( servletContext ); 1083 _legacySettings = LegacySettings.get( servletContext ); 1084 _handlers = Handlers.get( servletContext ); 1085 _flowControllerFactory = FlowControllerFactory.get( servletContext ); 1086 1087 cacheOverloadedActionMappings(); 1091 1092 cacheFormClasses(); 1096 1097 ActionInterceptorContext.init( servletContext ); 1101 RequestInterceptorContext.init( servletContext ); 1102 1103 _pageServletFilter = new PageServletFilter(); 1104 } 1105 1106 private class PageServletFilter extends PageFlowPageFilter 1107 { 1108 public PageServletFilter() 1109 { 1110 super( getServletContext() ); 1111 } 1112 1113 protected Set getValidFileExtensions() 1114 { 1115 return null; } 1117 } 1118 1119 private void cacheOverloadedActionMappings() 1120 { 1121 ActionConfig[] actionConfigs = moduleConfig.findActionConfigs(); 1122 1123 for ( int i = 0; i < actionConfigs.length; i++ ) 1124 { 1125 ActionConfig actionConfig = actionConfigs[i]; 1126 1127 if ( actionConfig instanceof PageFlowActionMapping ) 1128 { 1129 PageFlowActionMapping mapping = ( PageFlowActionMapping ) actionConfig; 1130 String unqualifiedActionPath = ( ( PageFlowActionMapping ) actionConfig ).getUnqualifiedActionPath(); 1131 1132 if ( unqualifiedActionPath != null ) 1133 { 1134 List overloaded = ( List ) _overloadedActions.get( unqualifiedActionPath ); 1135 1136 if ( overloaded == null ) 1137 { 1138 overloaded = new ArrayList (); 1139 _overloadedActions.put( unqualifiedActionPath, overloaded ); 1140 } 1141 1142 overloaded.add( mapping ); 1143 } 1144 } 1145 } 1146 } 1147 1148 private void cacheFormClasses() 1149 { 1150 FormBeanConfig[] formBeans = moduleConfig.findFormBeanConfigs(); 1151 ReloadableClassHandler rch = _handlers.getReloadableClassHandler(); 1152 1153 for ( int i = 0; i < formBeans.length; i++ ) 1154 { 1155 FormBeanConfig formBeanConfig = formBeans[i]; 1156 String formType = InternalUtils.getFormBeanType( formBeanConfig ); 1157 1158 try 1159 { 1160 Class formBeanClass = rch.loadClass( formType ); 1161 _formBeanClasses.put( formBeanConfig.getName(), formBeanClass ); 1162 } 1163 catch ( ClassNotFoundException e ) 1164 { 1165 _log.error( "Could not load class " + formType + " referenced from form bean config " 1166 + formBeanConfig.getName() + " in Struts module " + moduleConfig ); 1167 } 1168 } 1169 } 1170 1171 1175 1176 protected void initDefinitionsMapping() throws ServletException 1177 { 1178 definitionsFactory = null; 1179 TilesUtilImpl tilesUtil = TilesUtil.getTilesUtil(); 1180 1181 if ( tilesUtil instanceof TilesUtilStrutsImpl ) 1182 { 1183 definitionsFactory = 1185 ( ( TilesUtilStrutsImpl ) tilesUtil ).getDefinitionsFactory( getServletContext(), moduleConfig ); 1186 1187 if ( definitionsFactory == null && log.isDebugEnabled() ) 1188 { 1189 log.debug( "Definition Factory not found for module: '" 1190 + moduleConfig.getPrefix() ); 1191 } 1192 } 1193 } 1194 1195 public ActionMapping processMapping( HttpServletRequest request, HttpServletResponse response, String path ) 1196 throws IOException 1197 { 1198 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1199 Object forwardedForm = InternalUtils.unwrapFormBean( InternalUtils.getForwardedFormBean( request, false ) ); 1200 1201 if ( fc != null && ! processSharedFlowMapping( request, response, path, fc ) ) return null; 1206 1207 Class forwardedFormClass = null; 1212 1213 if ( forwardedForm != null ) 1214 { 1215 forwardedFormClass = forwardedForm.getClass(); 1216 List possibleMatches = ( List ) _overloadedActions.get( path ); 1217 ActionMapping bestMatch = null; 1218 1219 for ( int i = 0; possibleMatches != null && i < possibleMatches.size(); ++i ) 1225 { 1226 ActionMapping possibleMatch = ( ActionMapping ) possibleMatches.get( i ); 1227 assert possibleMatch instanceof PageFlowActionMapping : possibleMatch.getClass(); 1228 Class cachedFormBeanClass = ( Class ) _formBeanClasses.get( possibleMatch.getName() ); 1229 1230 if ( forwardedFormClass.equals( cachedFormBeanClass ) ) 1231 { 1232 bestMatch = possibleMatch; 1233 break; 1234 } 1235 if ( bestMatch == null && isCorrectFormType( forwardedFormClass, possibleMatch ) ) 1236 { 1237 bestMatch = possibleMatch; 1238 } 1239 } 1240 1241 if ( bestMatch != null ) 1242 { 1243 request.setAttribute( Globals.MAPPING_KEY, bestMatch ); 1244 1245 if ( _log.isDebugEnabled() ) 1246 { 1247 _log.debug( "Found form-specific action mapping " + bestMatch.getPath() + " for " + path 1248 + ", form " + forwardedFormClass.getName() ); 1249 } 1250 1251 return checkTransaction( request, response, bestMatch, path ); 1252 } 1253 } 1254 1255 ActionMapping mapping = ( ActionMapping ) moduleConfig.findActionConfig( path ); 1259 1260 if ( mapping != null ) 1261 { 1262 boolean wrongForm = false; 1263 1264 if ( forwardedForm != null ) 1268 { 1269 boolean mappingHasNoFormBean = mapping.getName() == null; 1270 wrongForm = mappingHasNoFormBean || ! isCorrectFormType( forwardedFormClass, mapping ); 1271 } 1272 1273 if ( ! wrongForm ) 1274 { 1275 request.setAttribute( Globals.MAPPING_KEY, mapping ); 1276 return checkTransaction( request, response, mapping, path ); 1277 } 1278 } 1279 1280 ActionConfig configs[] = moduleConfig.findActionConfigs(); 1284 for ( int i = 0; i < configs.length; i++ ) 1285 { 1286 if ( configs[i].getUnknown() ) 1287 { 1288 mapping = ( ActionMapping ) configs[i]; 1289 request.setAttribute( Globals.MAPPING_KEY, mapping ); 1290 return checkTransaction( request, response, mapping, path ); 1291 } 1292 } 1293 1294 String errorServletPath = PageFlowRequestWrapper.get( request ).getOriginalServletPath(); 1299 1300 if ( errorServletPath == null 1301 && InternalUtils.getModuleConfig( GLOBALAPP_MODULE_CONTEXT_PATH, getServletContext() ) != null ) 1302 { 1303 if ( _log.isDebugEnabled() ) 1304 { 1305 _log.debug( "Trying Global.app for unhandled action " + path ); 1306 } 1307 1308 errorServletPath = InternalUtils.getDecodedServletPath( request ); 1312 PageFlowRequestWrapper.get( request ).setOriginalServletPath( errorServletPath ); 1313 String globalAppURI = GLOBALAPP_MODULE_CONTEXT_PATH + path + ACTION_EXTENSION; 1314 try 1315 { 1316 doForward( globalAppURI, request, response ); 1317 } 1318 catch ( ServletException e ) 1319 { 1320 _log.error( "Could not forward to Global.app URI " + globalAppURI ); 1321 } 1322 return null; 1323 } 1324 else 1325 { 1326 if ( errorServletPath != null && path.indexOf( '/' ) > 0 ) path = errorServletPath; 1331 return processUnresolvedAction( path, request, response, forwardedForm ); 1332 } 1333 } 1334 1335 protected boolean processSharedFlowMapping( HttpServletRequest request, HttpServletResponse response, 1336 String actionPath, FlowController currentFlowController ) 1337 throws IOException 1338 { 1339 if ( currentFlowController.isPageFlow() ) 1340 { 1341 int dot = actionPath.indexOf( '.' ); 1342 1343 if ( dot != -1 ) 1344 { 1345 Map sharedFlows = PageFlowUtils.getSharedFlows( request ); 1346 if ( sharedFlows == null ) return true; 1347 if ( dot == actionPath.length() - 1 ) return true; assert actionPath.length() > 0 && actionPath.charAt( 0 ) == '/' : actionPath; 1349 String sharedFlowName = actionPath.substring( 1, dot ); 1350 SharedFlowController sf = ( SharedFlowController ) sharedFlows.get( sharedFlowName ); 1351 1352 if ( sf != null ) 1353 { 1354 if ( _log.isDebugEnabled() ) 1355 { 1356 _log.debug( "Forwarding to shared flow " + sf.getDisplayName() + " to handle action \"" 1357 + actionPath + "\"." ); 1358 } 1359 1360 PageFlowRequestWrapper.get( request ).setOriginalServletPath( InternalUtils.getDecodedServletPath( request ) ); 1365 1366 int lastSlash = actionPath.lastIndexOf( '/' ); 1370 assert lastSlash != -1 : actionPath; 1371 InternalStringBuilder uri = new InternalStringBuilder( sf.getModulePath() ); 1372 uri.append( '/' ); 1373 uri.append( actionPath.substring( dot + 1 ) ); 1374 uri.append( ACTION_EXTENSION ); 1375 1376 try 1377 { 1378 doForward( uri.toString(), request, response ); 1379 return false; 1380 } 1381 catch ( ServletException e ) 1382 { 1383 _log.error( "Could not forward to shared flow URI " + uri, e ); 1384 } 1385 } 1386 } 1387 } 1388 1389 return true; 1390 } 1391 1392 protected ActionMapping processUnresolvedAction( String actionPath, HttpServletRequest request, 1393 HttpServletResponse response, Object returningForm ) 1394 throws IOException 1395 { 1396 if ( _log.isInfoEnabled() ) 1397 { 1398 InternalStringBuilder msg = new InternalStringBuilder( "Action \"" ).append( actionPath ); 1399 _log.info( msg.append( "\" was also unhandled by Global.app." ).toString() ); 1400 } 1401 1402 FlowController fc = PageFlowUtils.getCurrentPageFlow( request ); 1408 1409 try 1410 { 1411 if ( fc != null ) 1412 { 1413 Exception ex = new ActionNotFoundException( actionPath, fc, returningForm ); 1414 InternalUtils.setCurrentModule( fc.getModuleConfig(), request ); 1415 ActionForward result = fc.handleException( ex, null, null, request, response ); 1416 return new ExceptionHandledActionMapping( actionPath, result ); 1417 } 1418 } 1419 catch ( ServletException e ) 1420 { 1421 1423 if ( _log.isDebugEnabled() ) 1424 { 1425 _log.debug( e ); 1426 } 1427 } 1428 1429 if ( _log.isDebugEnabled() ) 1430 { 1431 _log.debug( "Couldn't handle an ActionNotFoundException -- delegating to Struts" ); 1432 } 1433 1434 return super.processMapping( request, response, actionPath ); 1435 } 1436 1437 protected boolean processRoles( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping ) 1438 throws IOException , ServletException 1439 { 1440 String roles[] = mapping.getRoleNames(); 1444 if ( roles == null || roles.length < 1 ) 1445 { 1446 return true; 1447 } 1448 1449 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1451 FlowControllerHandlerContext context = new FlowControllerHandlerContext( request, response, fc ); 1452 1453 for ( int i = 0; i < roles.length; i++ ) 1454 { 1455 if ( _handlers.getLoginHandler().isUserInRole( context, roles[i] ) ) 1456 { 1457 if ( _log.isDebugEnabled() ) 1458 { 1459 _log.debug( " User " + request.getRemoteUser() + " has role '" + roles[i] + "', granting access" ); 1460 } 1461 1462 return true; 1463 } 1464 } 1465 1466 if ( _log.isDebugEnabled() ) 1468 { 1469 _log.debug( " User '" + request.getRemoteUser() + "' does not have any required role, denying access" ); 1470 } 1471 1472 LoginHandler loginHandler = _handlers.getLoginHandler(); 1476 String actionName = InternalUtils.getActionName( mapping ); 1477 FlowController currentFC = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1478 PageFlowException ex; 1479 1480 if ( loginHandler.getUserPrincipal( context ) == null ) 1481 { 1482 ex = currentFC.createNotLoggedInException( actionName, request ); 1483 } 1484 else 1485 { 1486 ex = new UnfulfilledRolesException( mapping.getRoleNames(), mapping.getRoles(), actionName, currentFC ); 1487 } 1488 1489 if ( currentFC != null ) 1490 { 1491 ActionForward fwd = currentFC.handleException( ex, mapping, null, request, response ); 1492 processForwardConfig( request, response, fwd ); 1493 } 1494 else 1495 { 1496 ( ( ResponseErrorCodeSender ) ex ).sendResponseErrorCode( response ); 1497 } 1498 1499 return false; 1500 } 1501 1502 private static String addScopeParams( String url, HttpServletRequest request ) 1503 { 1504 String scopeID = request.getParameter( ScopedServletUtils.SCOPE_ID_PARAM ); 1508 if ( scopeID != null ) 1509 { 1510 return InternalUtils.addParam( url, ScopedServletUtils.SCOPE_ID_PARAM, scopeID ); 1511 } 1512 else 1513 { 1514 return url; 1515 } 1516 } 1517 1518 1522 protected void processForwardConfig( HttpServletRequest request, HttpServletResponse response, ForwardConfig fwd ) 1523 throws IOException , ServletException 1524 { 1525 ServletContext servletContext = getServletContext(); 1526 ForwardRedirectHandler fwdRedirectHandler = _handlers.getForwardRedirectHandler(); 1527 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1528 FlowControllerHandlerContext context = new FlowControllerHandlerContext( request, response, fc ); 1529 1530 if ( fc != null ) 1532 { 1533 InternalUtils.setForwardingModule( request, fc.getModulePath() ); 1534 } 1535 1536 if ( fwd != null ) 1541 { 1542 if ( _log.isDebugEnabled() ) _log.debug( "processForwardConfig(" + fwd + ')' ); 1543 1544 if ( processTilesDefinition( fwd.getPath(), fwd.getContextRelative(), request, response ) ) 1549 { 1550 if ( log.isDebugEnabled() ) 1551 { 1552 log.debug( " '" + fwd.getPath() + "' - processed as definition" ); 1553 } 1554 return; 1555 } 1556 1557 if ( fwd instanceof PageFlowActionForward ) 1564 { 1565 ActionMapping mapping = ( ActionMapping ) request.getAttribute( Globals.MAPPING_KEY ); 1566 assert mapping != null; 1567 ActionForm form = InternalUtils.getFormBean( mapping, request ); 1568 Forward pfFwd = new Forward( ( ActionForward ) fwd, servletContext ); 1569 ActionForwardHandler handler = _handlers.getActionForwardHandler(); 1570 fwd = handler.doForward( context, pfFwd, mapping, InternalUtils.getActionName( mapping ), null, form ); 1571 } 1572 1573 String path = fwd.getPath(); 1574 boolean startsWithSlash = path.length() > 0 && path.charAt( 0 ) == '/'; 1575 1576 if ( FileUtils.isAbsoluteURI( path ) ) 1580 { 1581 fwdRedirectHandler.redirect( context, addScopeParams( path, request ) ); 1582 } 1583 else if ( fwd.getRedirect() ) 1584 { 1585 String redirectURI; 1586 1587 if ( startsWithSlash && fwd instanceof Forward && ( ( Forward ) fwd ).isExplicitPath() ) 1588 { 1589 redirectURI = path; 1590 } 1591 else if ( fwd instanceof Forward && ( ( Forward ) fwd ).isExternalRedirect() ) 1592 { 1593 assert startsWithSlash : path; redirectURI = path; 1595 } 1596 else 1597 { 1598 redirectURI = request.getContextPath() + RequestUtils.forwardURL( request, fwd ); 1599 } 1600 1601 fwdRedirectHandler.redirect( context, addScopeParams( redirectURI, request ) ); 1602 } 1603 else 1604 { 1605 String fwdURI; 1606 1607 if ( startsWithSlash && fwd instanceof Forward && ( ( Forward ) fwd ).isExplicitPath() ) 1608 { 1609 fwdURI = path; 1610 } 1611 else 1612 { 1613 fwdURI = RequestUtils.forwardURL( request, fwd ); 1614 1615 ModuleConfig mc = ( ModuleConfig ) request.getAttribute( Globals.MODULE_KEY ); 1621 1622 if ( InternalUtils.isSharedFlowModule( mc ) && ! fwdURI.endsWith( ACTION_EXTENSION ) 1623 && fwdURI.startsWith( SHARED_FLOW_MODULE_PREFIX ) ) 1624 { 1625 fwdURI = '/' + fwdURI.substring( SHARED_FLOW_MODULE_PREFIX_LEN ); 1626 } 1627 } 1628 1629 doForward( fwdURI, request, response ); 1630 } 1631 } 1632 } 1633 1634 protected boolean changeScheme( String webappRelativeURI, String scheme, int port, 1635 FlowControllerHandlerContext context ) 1636 throws URISyntaxException , IOException , ServletException 1637 { 1638 if ( port == -1 ) 1639 { 1640 if ( _log.isWarnEnabled() ) 1641 { 1642 _log.warn( "Could not change the scheme to " + scheme + " because the relevant port was not provided " 1643 + "by the ServletContainerAdapter." ); 1644 return false; 1645 } 1646 } 1647 1648 Map attrs = new HashMap (); 1653 String queryString = null; 1654 ServletContext servletContext = getServletContext(); 1655 HttpServletRequest request = ( ( RequestContext ) context ).getHttpRequest(); 1656 1657 for ( Enumeration e = request.getAttributeNames(); e.hasMoreElements(); ) 1658 { 1659 String name = ( String ) e.nextElement(); 1660 attrs.put( name, request.getAttribute( name ) ); 1661 } 1662 1663 if ( ! attrs.isEmpty() ) 1664 { 1665 String hash = Integer.toString( request.hashCode() ); 1666 String key = makeRedirectedRequestAttrsKey( webappRelativeURI, hash ); 1667 request.getSession().setAttribute( key, attrs ); 1668 queryString = URLRewriterService.getNamePrefix( servletContext, request, REDIRECT_REQUEST_ATTRS_PARAM ) 1669 + REDIRECT_REQUEST_ATTRS_PARAM + '=' + hash; 1670 } 1671 1672 1673 URI redirectURI = new URI ( scheme, null, request.getServerName(), port, 1677 request.getContextPath() + webappRelativeURI, 1678 queryString, null ); 1679 1680 ForwardRedirectHandler fwdRedirectHandler = _handlers.getForwardRedirectHandler(); 1681 fwdRedirectHandler.redirect( context, redirectURI.toString() ); 1682 1683 if ( _log.isDebugEnabled() ) 1684 { 1685 _log.debug( "Redirected to " + redirectURI ); 1686 } 1687 1688 return true; 1689 } 1690 1691 1694 protected boolean shouldDoSecureForwards() 1695 { 1696 return _legacySettings.shouldDoSecureForwards(); 1697 } 1698 1699 protected void doForward( String uri, HttpServletRequest request, HttpServletResponse response ) 1700 throws IOException , ServletException 1701 { 1702 boolean securityRedirected = false; 1703 ServletContext servletContext = getServletContext(); 1704 1705 if ( response.isCommitted() ) 1710 { 1711 doInclude( uri, request, response ); 1712 return; 1713 } 1714 1715 FlowController fc = PageFlowRequestWrapper.get( request ).getCurrentFlowController(); 1716 FlowControllerHandlerContext context = new FlowControllerHandlerContext( request, response, fc ); 1717 1718 if ( _legacySettings.shouldDoSecureForwards() ) 1719 { 1720 SecurityProtocol sp = PageFlowUtils.getSecurityProtocol( uri, servletContext, request ); 1721 1722 if ( ! sp.equals( SecurityProtocol.UNSPECIFIED ) ) 1723 { 1724 try 1725 { 1726 if ( request.isSecure() ) 1727 { 1728 if ( sp.equals( SecurityProtocol.UNSECURE ) ) 1729 { 1730 int listenPort = _servletContainerAdapter.getListenPort( request ); 1731 securityRedirected = changeScheme( uri, SCHEME_UNSECURE, listenPort, context ); 1732 } 1733 } 1734 else 1735 { 1736 if ( sp.equals( SecurityProtocol.SECURE ) ) 1737 { 1738 int secureListenPort = _servletContainerAdapter.getSecureListenPort( request ); 1739 securityRedirected = changeScheme( uri, SCHEME_SECURE, secureListenPort, context ); 1740 } 1741 } 1742 } 1743 catch ( URISyntaxException e ) 1744 { 1745 _log.error( "Bad forward URI " + uri, e ); 1746 } 1747 } 1748 } 1749 1750 if ( ! securityRedirected ) 1751 { 1752 if ( ! processPageForward( uri, request, response ) ) 1753 { 1754 ForwardRedirectHandler fwdRedirectHandler = _handlers.getForwardRedirectHandler(); 1755 fwdRedirectHandler.forward( context, uri ); 1756 } 1757 } 1758 } 1759 1760 1779 private boolean processPageForward( String pagePath, HttpServletRequest request, HttpServletResponse response ) 1780 throws IOException , ServletException 1781 { 1782 Class pageServletClass = ( Class ) _pageServletClasses.get( pagePath ); 1783 1784 if ( pageServletClass == null ) 1785 { 1786 pageServletClass = Void .class; 1787 ClassLoader cl = DiscoveryUtils.getClassLoader(); 1788 String path = "META-INF/pageflow-page-servlets" + pagePath + ".properties"; 1789 InputStream in = cl.getResourceAsStream( path ); 1790 1791 if ( in != null ) 1792 { 1793 String className = null; 1794 1795 try 1796 { 1797 Properties props = new Properties (); 1798 props.load( in ); 1799 className = props.getProperty( _servletContainerAdapter.getPlatformName() ); 1800 if ( className == null ) className = props.getProperty( "default" ); 1801 1802 if ( className != null ) 1803 { 1804 pageServletClass = cl.loadClass( className ); 1805 1806 if ( Servlet.class.isAssignableFrom( pageServletClass ) ) 1807 { 1808 if ( _log.isInfoEnabled() ) 1809 { 1810 _log.info( "Loaded page Servlet class " + className + " for path " + pagePath ); 1811 } 1812 } 1813 else 1814 { 1815 pageServletClass = Void .class; 1816 _log.error( "Page Servlet class " + className + " for path " + pagePath 1817 + " does not extend " + Servlet.class.getName() ); 1818 } 1819 } 1820 } 1821 catch ( IOException e ) 1822 { 1823 _log.error( "Error while reading " + path, e ); 1824 } 1825 catch ( ClassNotFoundException e ) 1826 { 1827 _log.error( "Error while loading page Servlet class " + className, e ); 1828 } 1829 } 1830 1831 _pageServletClasses.put( pagePath, pageServletClass ); 1832 } 1833 1834 if ( pageServletClass.equals( Void .class ) ) 1835 { 1836 return false; 1837 } 1838 1839 try 1840 { 1841 Servlet pageServlet = ( Servlet ) pageServletClass.newInstance(); 1842 pageServlet.init( new PageServletConfig( pagePath ) ); 1843 _pageServletFilter.doFilter( request, response, new PageServletFilterChain( pageServlet ) ); 1844 return true; 1845 } 1846 catch ( InstantiationException e ) 1847 { 1848 _log.error( "Error while instantiating page Servlet of type " + pageServletClass.getName(), e ); 1849 } 1850 catch ( IllegalAccessException e ) 1851 { 1852 _log.error( "Error while instantiating page Servlet of type " + pageServletClass.getName(), e ); 1853 } 1854 1855 return false; 1856 } 1857 1858 1861 private static class PageServletFilterChain implements FilterChain 1862 { 1863 private Servlet _pageServlet; 1864 1865 public PageServletFilterChain( Servlet pageServlet ) 1866 { 1867 _pageServlet= pageServlet; 1868 } 1869 1870 public void doFilter( ServletRequest request, ServletResponse response ) 1871 throws IOException , ServletException 1872 { 1873 _pageServlet.service( request, response ); 1874 } 1875 } 1876 1877 1880 private class PageServletConfig implements ServletConfig 1881 { 1882 private String _pagePath; 1883 1884 public PageServletConfig( String pagePath ) 1885 { 1886 _pagePath = pagePath; 1887 } 1888 1889 public String getServletName() 1890 { 1891 return _pagePath; 1892 } 1893 1894 public ServletContext getServletContext() 1895 { 1896 return PageFlowRequestProcessor.this.getServletContext(); 1897 } 1898 1899 public String getInitParameter( String s ) 1900 { 1901 return null; 1902 } 1903 1904 public Enumeration getInitParameterNames() 1905 { 1906 return Collections.enumeration( Collections.EMPTY_LIST ); 1907 } 1908 } 1909 1910 1913 protected void processNoCache( HttpServletRequest request, HttpServletResponse response ) 1914 { 1915 boolean noCache = moduleConfig.getControllerConfig().getNocache(); 1923 1924 if ( ! noCache ) 1925 { 1926 PageflowConfig pfConfig = ConfigUtil.getConfig().getPageflowConfig(); 1927 1928 if ( pfConfig != null ) 1929 { 1930 PageflowConfig.PreventCache.Enum preventCache = pfConfig.getPreventCache(); 1931 1932 if ( preventCache != null ) 1933 { 1934 switch ( preventCache.intValue() ) 1935 { 1936 case PageflowConfig.PreventCache.INT_ALWAYS: 1937 noCache = true; 1938 break; 1939 case PageflowConfig.PreventCache.INT_IN_DEV_MODE: 1940 noCache = ! _servletContainerAdapter.isInProductionMode(); 1941 break; 1942 } 1943 } 1944 } 1945 } 1946 1947 if ( noCache ) 1948 { 1949 ServletUtils.preventCache( response ); 1955 PageFlowPageFilter.preventCache( request ); 1956 } 1957 } 1958 1959 private class ActionRunner 1960 implements ActionInterceptors.ActionExecutor 1961 { 1962 RequestInterceptorContext _ctxt; 1963 private Action _action; 1964 private ActionForm _formBean; 1965 private ActionMapping _actionMapping; 1966 1967 public ActionRunner( RequestInterceptorContext context, Action action, ActionForm formBean, 1968 ActionMapping actionMapping ) 1969 { 1970 _ctxt = context; 1971 _action = action; 1972 _formBean = formBean; 1973 _actionMapping = actionMapping; 1974 } 1975 1976 public ActionForward execute() 1977 throws InterceptorException, ServletException , IOException 1978 { 1979 return PageFlowRequestProcessor.super.processActionPerform( _ctxt.getRequest(), _ctxt.getResponse(), 1980 _action, _formBean, _actionMapping ); 1981 } 1982 } 1983 1984 protected ActionForward processActionPerform( HttpServletRequest request, HttpServletResponse response, 1985 Action action, ActionForm form, ActionMapping mapping ) 1986 throws IOException , ServletException 1987 { 1988 ServletContext servletContext = getServletContext(); 1989 String actionName = InternalUtils.getActionName( mapping ); 1990 ActionInterceptorContext context = null; 1991 List interceptors = null; 1992 1993 if ( action instanceof FlowControllerAction ) 1994 { 1995 FlowController fc = ( ( FlowControllerAction ) action ).getFlowController(); 1996 1997 if ( fc instanceof PageFlowController ) 1998 { 1999 PageFlowController pfc = ( PageFlowController ) fc; 2000 context = new ActionInterceptorContext( request, response, servletContext, pfc, null, actionName ); 2001 interceptors = context.getActionInterceptors(); 2002 } 2003 } 2004 2005 try 2006 { 2007 if ( interceptors != null && ! PageFlowRequestWrapper.get( request ).isReturningFromActionIntercept() ) 2011 { 2012 Interceptors.doPreIntercept( context, interceptors ); 2013 2014 if ( context.hasInterceptorForward() ) 2015 { 2016 InterceptorForward fwd = context.getInterceptorForward(); 2017 2018 if ( _log.isDebugEnabled() ) 2019 { 2020 2021 Interceptor overridingInterceptor = context.getOverridingInterceptor(); 2022 StringBuffer msg = new StringBuffer (); 2023 msg.append( "Action interceptor " ); 2024 msg.append( overridingInterceptor.getClass().getName() ); 2025 msg.append( " before action " ); 2026 msg.append( actionName ); 2027 msg.append( ": forwarding to " ); 2028 msg.append( fwd != null ? fwd.getPath() : "null [no forward]" ); 2029 _log.debug( msg.toString() ); 2030 } 2031 2032 return fwd; 2033 } 2034 } 2035 else 2036 { 2037 PageFlowRequestWrapper.get( request ).setReturningFromActionIntercept( false ); 2038 } 2039 2040 RequestInterceptorContext requestContext = 2044 context != null ? 2045 context : 2046 new RequestInterceptorContext( request, response, getServletContext() ); 2047 ActionRunner actionExecutor = new ActionRunner( requestContext, action, form, mapping ); 2048 ActionForward ret = ActionInterceptors.wrapAction( context, interceptors, actionExecutor ); 2049 2050 if ( interceptors != null ) 2054 { 2055 context.setOriginalForward( ret ); 2056 Interceptors.doPostIntercept( context, interceptors ); 2057 2058 if ( context.hasInterceptorForward() ) 2059 { 2060 InterceptorForward fwd = context.getInterceptorForward(); 2061 2062 if ( _log.isDebugEnabled() ) 2063 { 2064 _log.debug( "Action interceptor " + context.getOverridingInterceptor().getClass().getName() 2065 + " after action " + actionName + ": forwarding to " 2066 + fwd != null ? fwd.getPath() : "null [no forward]" ); 2067 } 2068 2069 return fwd; 2070 } 2071 } 2072 2073 return ret; 2074 } 2075 catch ( InterceptorException e ) 2076 { 2077 throw new ServletException ( e ); 2078 } 2079 } 2080 2081 void doActionForward( HttpServletRequest request, HttpServletResponse response, ActionForward forward ) 2082 throws IOException , ServletException 2083 { 2084 request = PageFlowRequestWrapper.wrapRequest( request ); 2085 processForwardConfig( request, response, forward ); 2086 } 2087} 2088 | Popular Tags |