1 18 package org.apache.beehive.netui.pageflow; 19 20 import org.apache.beehive.netui.util.logging.Logger; 21 import org.apache.beehive.netui.util.config.ConfigUtil; 22 import org.apache.beehive.netui.util.config.bean.PageflowConfig; 23 import org.apache.beehive.netui.util.config.bean.DefaultSharedFlowRefs; 24 import org.apache.beehive.netui.util.config.bean.SharedFlowRef; 25 import org.apache.beehive.netui.pageflow.internal.InternalUtils; 26 import org.apache.beehive.netui.pageflow.config.PageFlowControllerConfig; 27 import org.apache.beehive.netui.pageflow.handler.ReloadableClassHandler; 28 import org.apache.beehive.netui.pageflow.handler.Handlers; 29 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 import javax.servlet.ServletContext ; 33 import javax.servlet.ServletException ; 34 import javax.servlet.ServletRequest ; 35 36 import org.apache.struts.config.ModuleConfig; 37 import org.apache.struts.config.ControllerConfig; 38 import org.apache.struts.action.ActionServlet; 39 40 import java.io.IOException ; 41 import java.util.Map ; 42 import java.util.LinkedHashMap ; 43 import java.util.Iterator ; 44 45 46 49 public class FlowControllerFactory 50 extends Factory 51 { 52 private static final Logger _log = Logger.getInstance( FlowControllerFactory.class ); 53 54 private ReloadableClassHandler _rch; 55 56 protected FlowControllerFactory( ServletContext servletContext ) 57 { 58 super( servletContext ); 59 _rch = Handlers.get( servletContext ).getReloadableClassHandler(); 60 } 61 62 68 public static FlowControllerFactory get( ServletContext servletContext ) 69 { 70 return new FlowControllerFactory( servletContext ); 71 } 72 73 81 public PageFlowController getPageFlowForRequest( RequestContext context ) 82 throws InstantiationException , IllegalAccessException 83 { 84 String servletPath = InternalUtils.getDecodedServletPath( context.getHttpRequest() ); 85 return getPageFlowForPath( context, servletPath ); 86 } 87 88 97 public PageFlowController getPageFlowForPath( RequestContext context, String path ) 98 throws InstantiationException , IllegalAccessException 99 { 100 HttpServletRequest request = context.getHttpRequest(); 101 HttpServletResponse response = context.getHttpResponse(); 102 PageFlowController cur = PageFlowUtils.getCurrentPageFlow( request ); 103 String parentDir = PageFlowUtils.getModulePathForRelativeURI( path ); 104 105 if ( cur != null ) cur.reinitialize( request, response, getServletContext() ); 109 110 if ( cur == null || ! PageFlowUtils.getModulePathForRelativeURI( cur.getURI() ).equals( parentDir ) ) 115 { 116 try 117 { 118 String className = InternalUtils.getFlowControllerClassName( parentDir, request, getServletContext() ); 119 return className != null ? createPageFlow( context, className ) : null; 120 } 121 catch ( ClassNotFoundException e ) 122 { 123 if ( _log.isInfoEnabled() ) _log.info( "No page flow exists for path " + path ); 124 return null; 125 } 126 } 127 128 return cur; 129 } 130 131 139 public PageFlowController createPageFlow( RequestContext context, String pageFlowClassName ) 140 throws ClassNotFoundException , InstantiationException , IllegalAccessException 141 { 142 Class pageFlowClass = getFlowControllerClass( pageFlowClassName ); 143 return createPageFlow( context, pageFlowClass ); 144 } 145 146 155 public PageFlowController createPageFlow( RequestContext context, Class pageFlowClass ) 156 throws InstantiationException , IllegalAccessException 157 { 158 if ( ! PageFlowController.class.isAssignableFrom( pageFlowClass ) ) return null; 159 160 HttpServletRequest request = context.getHttpRequest(); 165 HttpServletResponse response = context.getHttpResponse(); 166 ServletContext servletContext = getServletContext(); 167 PageFlowController retVal = null; 168 String modulePath = InternalUtils.inferModulePathFromClassName( pageFlowClass.getName() ); 169 ModuleConfig mc = ensureModule( modulePath, request, servletContext ); 170 171 if ( mc == null ) 172 { 173 _log.error( "Struts module " + modulePath + " not found for " + pageFlowClass.getName() 174 + "; cannot create page flow."); 175 return null; 176 } 177 178 if ( InternalUtils.isLongLived( mc ) ) 179 { 180 retVal = PageFlowUtils.getLongLivedPageFlow( modulePath, request ); 181 182 if ( _log.isDebugEnabled() ) 183 { 184 if ( retVal != null ) 185 { 186 _log.debug( "Using long lived PageFlowController of type " + pageFlowClass.getName() ); 187 } 188 } 189 } 190 191 boolean createdNew = false; 204 boolean isNestable = InternalUtils.isNestable( mc ); 205 PageFlowStack pfStack = PageFlowStack.get( request, false ); 206 207 if ( isNestable && pfStack != null ) 208 { 209 PageflowConfig options = ConfigUtil.getConfig().getPageflowConfig(); 210 211 if ( options == null || ! options.getEnableSelfNesting() ) 212 { 213 int lastIndexOfJpfClass = pfStack.lastIndexOf( request, pageFlowClass ); 214 215 if ( lastIndexOfJpfClass != -1 ) 216 { 217 retVal = pfStack.popUntil( request, lastIndexOfJpfClass ); 218 retVal.persistInSession( request, response ); 219 return retVal; 220 } 221 } 222 } 223 224 if ( retVal == null ) 229 { 230 if ( _log.isDebugEnabled() ) 231 { 232 _log.debug( "Creating PageFlowController of type " + pageFlowClass.getName() ); 233 } 234 235 retVal = ( PageFlowController ) pageFlowClass.newInstance(); 236 createdNew = true; 237 } 238 239 if ( isNestable ) 244 { 245 if ( createdNew ) retVal.create( request, response, servletContext ); 249 PageFlowController current = PageFlowUtils.getCurrentPageFlow( request ); 250 251 if ( current != null ) 252 { 253 if ( _log.isDebugEnabled() ) 254 { 255 _log.debug( "Pushing PageFlowController " + current + " onto the nesting stack" ); 256 } 257 258 if ( pfStack == null ) pfStack = PageFlowStack.get( request, true ); 259 pfStack.push( current, request ); 260 } 261 262 retVal.reinitialize( request, response, servletContext ); 263 retVal.persistInSession( request, response ); 264 } 265 else 266 { 267 if ( pfStack != null ) 271 { 272 if ( _log.isDebugEnabled() ) 273 { 274 _log.debug( "Destroying the PageFlowController stack." ); 275 } 276 277 PageFlowController onStackAlready = pfStack.popUntil( request, retVal.getClass() ); 284 285 if ( onStackAlready != null ) 286 { 287 if ( _log.isDebugEnabled() ) 288 { 289 _log.debug( "Found a page flow of type " + retVal.getClass() + " in the stack; " 290 + "using that instance and stopping destruction of the nesting stack." ); 291 } 292 293 retVal = onStackAlready; 294 retVal.persistInSession( request, response ); 295 } 296 else 297 { 298 retVal.reinitialize( request, response, servletContext ); 304 retVal.persistInSession( request, response ); 305 retVal.create( request, response, servletContext ); 306 } 307 } 308 else 309 { 310 retVal.reinitialize( request, response, servletContext ); 316 retVal.persistInSession( request, response ); 317 if ( createdNew ) retVal.create( request, response, servletContext ); 318 } 319 } 320 321 return retVal; 322 } 323 324 331 public SharedFlowController createSharedFlow( RequestContext context, String sharedFlowClassName ) 332 throws ClassNotFoundException , InstantiationException , IllegalAccessException 333 { 334 Class sharedFlowClass = getFlowControllerClass( sharedFlowClassName ); 335 return createSharedFlow( context, sharedFlowClass ); 336 } 337 338 345 public SharedFlowController createSharedFlow( RequestContext context, Class sharedFlowClass ) 346 throws InstantiationException , IllegalAccessException 347 { 348 assert SharedFlowController.class.isAssignableFrom( sharedFlowClass ) : sharedFlowClass.getName(); 349 350 if ( _log.isDebugEnabled() ) 351 { 352 _log.debug( "Creating SharedFlowController of type " + sharedFlowClass.getName() ); 353 } 354 355 SharedFlowController retVal = ( SharedFlowController ) sharedFlowClass.newInstance(); 356 HttpServletRequest request = context.getHttpRequest(); 357 HttpServletResponse response = context.getHttpResponse(); 358 retVal.create( request, response, getServletContext() ); 359 360 if ( _log.isDebugEnabled() ) 361 { 362 _log.debug( "Storing " + retVal + " in the session..." ); 363 } 364 365 retVal.persistInSession( request, response ); 366 return retVal; 367 } 368 369 380 public Map getSharedFlowsForRequest( RequestContext context ) 381 throws ClassNotFoundException , InstantiationException , IllegalAccessException 382 { 383 String path = InternalUtils.getDecodedServletPath( context.getHttpRequest() ); 384 return getSharedFlowsForPath( context, path ); 385 } 386 387 399 public Map getSharedFlowsForPath( RequestContext context, String path ) 400 throws ClassNotFoundException , InstantiationException , IllegalAccessException 401 { 402 String parentDir = PageFlowUtils.getModulePathForRelativeURI( path ); 403 HttpServletRequest request = context.getHttpRequest(); 404 HttpServletResponse response = context.getHttpResponse(); 405 ModuleConfig mc = InternalUtils.ensureModuleConfig( parentDir, request, getServletContext() ); 406 LinkedHashMap sharedFlows = getDefaultSharedFlows( context ); 407 408 if ( mc != null ) 409 { 410 ControllerConfig cc = mc.getControllerConfig(); 411 412 if ( cc instanceof PageFlowControllerConfig ) 413 { 414 Map sharedFlowTypes = ( ( PageFlowControllerConfig ) cc ).getSharedFlowTypes(); 415 416 if ( sharedFlowTypes != null && sharedFlowTypes.size() > 0 ) 417 { 418 if ( sharedFlows == null ) sharedFlows = new LinkedHashMap (); 419 420 for ( Iterator i = sharedFlowTypes.entrySet().iterator(); i.hasNext(); ) 421 { 422 Map.Entry entry = ( Map.Entry ) i.next(); 423 String name = ( String ) entry.getKey(); 424 String type = ( String ) entry.getValue(); 425 addSharedFlow( context, name, type, sharedFlows ); 426 } 427 428 return sharedFlows; 429 } 430 } 431 } 432 433 SharedFlowController ga = PageFlowUtils.getGlobalApp( request ); 437 438 if ( ga != null ) 439 { 440 ga.reinitialize( request, response, getServletContext() ); 441 } 442 else 443 { 444 getGlobalApp( request, response, getServletContext() ); 445 } 446 447 return sharedFlows; 448 } 449 450 LinkedHashMap getDefaultSharedFlows( RequestContext context ) 451 throws ClassNotFoundException , InstantiationException , IllegalAccessException 452 { 453 DefaultSharedFlowRefs defaultRefs = ConfigUtil.getConfig().getDefaultSharedFlowRefs(); 454 455 if ( defaultRefs != null ) 456 { 457 SharedFlowRef[] refs = defaultRefs.getSharedFlowRefArray(); 458 459 if ( refs.length > 0 ) 460 { 461 LinkedHashMap sharedFlows = new LinkedHashMap (); 462 463 for ( int i = 0; i < refs.length; i++ ) 464 { 465 SharedFlowRef ref = refs[i]; 466 if ( _log.isInfoEnabled() ) 467 { 468 _log.info( "Shared flow of type " + ref.getType() + " is a default shared flow reference " 469 + "with name " + ref.getName() ); 470 } 471 addSharedFlow( context, ref.getName(), ref.getType(), sharedFlows ); 472 } 473 474 return sharedFlows; 475 } 476 } 477 478 return null; 479 } 480 481 private void addSharedFlow( RequestContext context, String name, String type, LinkedHashMap sharedFlows ) 482 throws ClassNotFoundException , InstantiationException , IllegalAccessException 483 { 484 HttpServletRequest request = context.getHttpRequest(); 485 SharedFlowController sf = PageFlowUtils.getSharedFlow( type, request ); 486 487 if ( sf != null ) 491 { 492 sf.reinitialize( request, context.getHttpResponse(), getServletContext() ); 493 } 494 else 495 { 496 sf = createSharedFlow( context, type ); 497 } 498 499 if ( ! ( sf instanceof GlobalApp ) ) sharedFlows.put( name, sf ); 500 } 501 502 508 public Class getFlowControllerClass( String className ) 509 throws ClassNotFoundException 510 { 511 return _rch.loadClass( className ); 512 } 513 514 525 public static PageFlowController getPageFlowForRequest( HttpServletRequest request, HttpServletResponse response, 526 ServletContext servletContext ) 527 { 528 return getPageFlowForRelativeURI( request, response, InternalUtils.getDecodedServletPath( request ), servletContext ); 529 } 530 531 544 public static PageFlowController getPageFlowForURI( HttpServletRequest request, HttpServletResponse response, 545 String uri, ServletContext servletContext ) 546 { 547 return getPageFlowForRelativeURI( request, response, PageFlowUtils.getRelativeURI( request, uri, null ), 548 servletContext ); 549 } 550 551 563 public static PageFlowController getPageFlowForRelativeURI( HttpServletRequest request, 564 HttpServletResponse response, String path, 565 ServletContext servletContext ) 566 { 567 try 568 { 569 return get( servletContext ).getPageFlowForPath( new RequestContext( request, response ), path ); 570 } 571 catch ( InstantiationException e ) 572 { 573 _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e ); 574 return null; 575 } 576 catch ( IllegalAccessException e ) 577 { 578 _log.error( "Could not instantiate PageFlowController for request " + request.getRequestURI(), e ); 579 return null; 580 } 581 } 582 583 594 public static PageFlowController getPageFlow( String pageFlowClassName, HttpServletRequest request, 595 HttpServletResponse response, ServletContext servletContext ) 596 { 597 try 598 { 599 return get( servletContext ).createPageFlow( new RequestContext( request, response ), pageFlowClassName ); 600 } 601 catch ( ClassNotFoundException e) 602 { 603 if ( _log.isErrorEnabled() ) _log.error( "Requested page flow class " + pageFlowClassName + " not found." ); 604 return null; 605 } 606 catch ( InstantiationException e ) 607 { 608 _log.error( "Could not instantiate PageFlowController of type " + pageFlowClassName, e ); 609 return null; 610 } 611 catch ( IllegalAccessException e ) 612 { 613 _log.error( "Could not instantiate PageFlowController of type " + pageFlowClassName, e ); 614 return null; 615 } 616 } 617 618 627 public static GlobalApp getGlobalApp( HttpServletRequest request, HttpServletResponse response, 628 ServletContext servletContext ) 629 { 630 GlobalApp current = PageFlowUtils.getGlobalApp( request ); 631 if ( current != null ) return current; 632 633 try 634 { 635 try 636 { 637 FlowControllerFactory factory = get( servletContext ); 638 SharedFlowController sf = 639 factory.createSharedFlow( new RequestContext( request, response ), PageFlowConstants.GLOBALAPP_CLASSNAME ); 640 641 if ( ! ( sf instanceof GlobalApp ) ) 642 { 643 _log.error( "Class " + PageFlowConstants.GLOBALAPP_CLASSNAME + " is not an instance of " 644 + GlobalApp.class.getName() ); 645 return null; 646 } 647 648 return ( GlobalApp ) sf; 649 } 650 catch ( InstantiationException e ) 651 { 652 _log.error( "Could not instantiate Global.app.", e ); 653 return null; 654 } 655 catch ( IllegalAccessException e ) 656 { 657 _log.error( "Could not instantiate Global.app", e ); 658 return null; 659 } 660 } 661 catch ( ClassNotFoundException e ) 662 { 663 return null; 665 } 666 } 667 668 private static ModuleConfig ensureModule( String modulePath, ServletRequest request, 669 ServletContext servletContext ) 670 { 671 ModuleConfig mc = InternalUtils.getModuleConfig( modulePath, servletContext ); 672 673 if ( mc == null ) 674 { 675 ActionServlet as = InternalUtils.getActionServlet( servletContext ); 676 677 if ( as instanceof AutoRegisterActionServlet ) 678 { 679 AutoRegisterActionServlet das = ( AutoRegisterActionServlet ) as; 680 681 try 682 { 683 mc = das.ensureModuleRegistered( modulePath, request ); 684 } 685 catch ( IOException e ) 686 { 687 _log.error( "Could not register Struts module for path " + modulePath, e ); 688 } 689 catch ( ServletException e ) 690 { 691 _log.error( "Could not register Struts module for path " + modulePath, e.getRootCause() ); 692 } 693 } 694 } 695 696 return mc; 697 } 698 699 710 public static PageFlowController getPageFlow( Class pageFlowClass, HttpServletRequest request, 711 HttpServletResponse response, ServletContext servletContext ) 712 { 713 try 714 { 715 FlowControllerFactory factory = get( servletContext ); 716 return factory.createPageFlow( new RequestContext( request, response ), pageFlowClass ); 717 } 718 catch ( InstantiationException e ) 719 { 720 _log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e ); 721 return null; 722 } 723 catch ( IllegalAccessException e ) 724 { 725 _log.error( "Could not instantiate PageFlowController of type " + pageFlowClass.getName(), e ); 726 return null; 727 } 728 } 729 } 730 | Popular Tags |