1 17 18 package org.apache.avalon.fortress.util; 19 20 import org.apache.avalon.excalibur.logger.LogKitLoggerManager; 21 import org.apache.avalon.excalibur.logger.LoggerManager; 22 import org.apache.avalon.excalibur.logger.Log4JConfLoggerManager; 23 import org.apache.avalon.fortress.MetaInfoManager; 24 import org.apache.avalon.fortress.RoleManager; 25 import org.apache.avalon.fortress.impl.role.ConfigurableRoleManager; 26 import org.apache.avalon.fortress.impl.role.FortressRoleManager; 27 import org.apache.avalon.fortress.impl.role.Role2MetaInfoManager; 28 import org.apache.avalon.fortress.impl.role.ServiceMetaManager; 29 import org.apache.avalon.framework.activity.Disposable; 30 import org.apache.avalon.framework.activity.Initializable; 31 import org.apache.avalon.framework.configuration.Configuration; 32 import org.apache.avalon.framework.configuration.DefaultConfiguration; 33 import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; 34 import org.apache.avalon.framework.container.ContainerUtil; 35 import org.apache.avalon.framework.context.Context; 36 import org.apache.avalon.framework.context.ContextException; 37 import org.apache.avalon.framework.context.DefaultContext; 38 import org.apache.avalon.framework.logger.ConsoleLogger; 39 import org.apache.avalon.framework.logger.Logger; 40 import org.apache.avalon.framework.parameters.Parameters; 41 import org.apache.avalon.framework.service.DefaultServiceManager; 42 import org.apache.avalon.framework.service.DefaultServiceSelector; 43 import org.apache.avalon.framework.service.ServiceManager; 44 import org.apache.avalon.framework.service.ServiceException; 45 import org.apache.excalibur.event.Sink; 46 import org.apache.excalibur.event.Queue; 47 import org.apache.excalibur.event.command.CommandFailureHandler; 48 import org.apache.excalibur.event.command.CommandManager; 49 import org.apache.excalibur.event.command.TPCThreadManager; 50 import org.apache.excalibur.event.command.ThreadManager; 51 import org.apache.excalibur.instrument.InstrumentManager; 52 import org.apache.excalibur.instrument.manager.DefaultInstrumentManager; 53 import org.apache.excalibur.mpool.DefaultPoolManager; 54 import org.apache.excalibur.mpool.PoolManager; 55 import org.apache.excalibur.source.Source; 56 import org.apache.excalibur.source.SourceResolver; 57 import org.apache.excalibur.source.impl.ResourceSourceFactory; 58 import org.apache.excalibur.source.impl.SourceResolverImpl; 59 import org.apache.excalibur.source.impl.URLSourceFactory; 60 61 import java.util.ArrayList ; 62 import java.util.Collections ; 63 import java.util.Comparator ; 64 import java.util.Iterator ; 65 66 91 public class ContextManager 92 implements ContextManagerConstants, Initializable, Disposable 93 { 94 protected static final Configuration EMPTY_CONFIG; 95 96 static 97 { 98 DefaultConfiguration config = 99 new DefaultConfiguration( "", "", "", "" ); 100 config.makeReadOnly(); 101 EMPTY_CONFIG = config; 102 } 103 104 107 protected final Context m_rootContext; 108 109 114 protected final DefaultContext m_childContext; 115 116 121 protected final DefaultContext m_containerManagerContext; 122 123 protected Logger m_logger; 124 protected final Logger m_primordialLogger; 125 126 131 protected SourceResolver m_defaultSourceResolver; 132 133 137 protected LoggerManager m_loggerManager; 138 139 143 protected Sink m_sink; 144 145 149 protected MetaInfoManager m_metaInfoManager; 150 151 155 protected PoolManager m_poolManager; 156 157 161 protected ThreadManager m_threadManager; 162 163 167 protected InstrumentManager m_instrumentManager; 168 174 private final ArrayList ownedComponents = new ArrayList (); 175 176 180 private DefaultConfigurationBuilder configBuilder; 181 182 188 public ContextManager( final Context rootContext, final Logger logger ) 189 { 190 m_rootContext = rootContext; 191 m_childContext = new OverridableContext( m_rootContext ); 192 m_containerManagerContext = new OverridableContext( m_childContext ); 193 m_logger = logger; 194 195 if ( m_logger == null ) 203 { 204 m_primordialLogger = new ConsoleLogger( ConsoleLogger.LEVEL_INFO ); 205 } 206 else 207 { 208 m_primordialLogger = null; 209 } 210 } 211 212 222 protected void assumeOwnership( final Object object ) 223 { 224 if ( object == null ) 225 { 226 throw new NullPointerException ( "object: Can not assume ownership of a null!" ); 227 } 228 ownedComponents.add( object ); 229 } 230 231 238 public void initialize() throws Exception 239 { 240 initializeDefaultSourceResolver(); 241 initializeLoggerManager(); 242 initializeMetaInfoManager(); 243 initializeThreadManager(); 244 initializeCommandSink(); 245 initializePoolManager(); 246 initializeContext(); 247 initializeInstrumentManager(); 248 initializeConfiguration(); 249 initializeServiceManager(); 250 251 m_childContext.makeReadOnly(); 252 m_containerManagerContext.makeReadOnly(); 253 254 m_defaultSourceResolver = null; 255 } 256 257 260 protected void initializeConfiguration() 261 { 262 try 263 { 264 copyEntry( CONFIGURATION ); 265 return; 266 } 267 catch ( ContextException ce ) 268 { 269 final Configuration containerConfig = 270 getConfiguration( CONFIGURATION, CONFIGURATION_URI ); 271 272 if ( containerConfig == null ) 273 { 274 getLogger().debug( "Could not initialize the Configuration", ce ); 275 return; 277 } 278 else 279 { 280 m_containerManagerContext.put( CONFIGURATION, containerConfig ); 281 } 282 } 283 } 284 285 290 protected void initializeContext() throws Exception 291 { 292 copyEntry( CONTAINER_CLASS ); 293 294 try 295 { 296 copyEntry( PARAMETERS ); 297 } 298 catch ( ContextException ce ) 299 { 300 getLogger().debug( "Could not copy Context parameters. This may be Ok depending on " 301 + "other configured context values." ); 302 } 303 304 m_childContext.put( CONFIGURATION, null ); 306 m_childContext.put( CONFIGURATION_URI, null ); 307 m_childContext.put( RoleManager.ROLE, null ); 308 m_childContext.put( ROLE_MANAGER_CONFIGURATION, null ); 309 m_childContext.put( ROLE_MANAGER_CONFIGURATION_URI, null ); 310 m_childContext.put( LoggerManager.ROLE, null ); 311 m_childContext.put( LOGGER_MANAGER_CONFIGURATION, null ); 312 m_childContext.put( LOGGER_MANAGER_CONFIGURATION_URI, null ); 313 m_childContext.put( InstrumentManager.ROLE, null ); 314 m_childContext.put( INSTRUMENT_MANAGER_CONFIGURATION, null ); 315 m_childContext.put( INSTRUMENT_MANAGER_CONFIGURATION_URI, null ); 316 m_childContext.put( Sink.ROLE, null ); 317 m_childContext.put( MetaInfoManager.ROLE, null ); 318 m_childContext.put( PoolManager.ROLE, null ); 319 m_childContext.put( LifecycleExtensionManager.ROLE, null ); 320 } 321 322 328 protected void copyEntry( final String key ) throws ContextException 329 { 330 m_containerManagerContext.put( key, m_rootContext.get( key ) ); 331 m_childContext.put( key, null ); 332 } 333 334 341 protected boolean entryPresent( Context context, final String key ) 342 { 343 boolean isPresent = false; 344 345 try 346 { 347 context.get( key ); 348 isPresent = true; 349 } 350 catch ( ContextException ce ) 351 { 352 } 354 355 return isPresent; 356 } 357 358 361 public void dispose() 362 { 363 disposeOwned(); 365 366 if ( getLogger().isDebugEnabled() ) 368 { 369 getLogger().debug( "Shutting down: " + m_loggerManager ); 370 } 371 372 try 373 { 374 ContainerUtil.shutdown( m_loggerManager ); 375 } 376 catch (final Exception ex) 377 { 378 if ( m_primordialLogger.isDebugEnabled() ) 379 { 380 m_primordialLogger.debug( "Failed to shutdown loggerManager", ex ); 381 } 382 } 383 } 384 385 388 public void disposeOwned() 389 { 390 Collections.sort( ownedComponents, new DestroyOrderComparator() ); 391 392 final Iterator ownedComponentsIter = ownedComponents.iterator(); 394 while ( ownedComponentsIter.hasNext() ) 395 { 396 final Object o = ownedComponentsIter.next(); 397 398 try 399 { 400 if ( getLogger().isDebugEnabled() ) getLogger().debug( "Shutting down: " + o ); 401 ContainerUtil.shutdown( o ); 402 if ( getLogger().isDebugEnabled() ) getLogger().debug( "Done." ); 403 } 404 catch ( Exception e ) 405 { 406 getLogger().warn( "Unable to dispose of owned component " 407 + o.getClass().getName(), e ); 408 } 409 410 ownedComponentsIter.remove(); 411 } 412 } 413 414 423 protected Object get( final Context context, final String key, final Object defaultValue ) 424 { 425 try 426 { 427 return context.get( key ); 428 } 429 catch ( ContextException ce ) 430 { 431 return defaultValue; 432 } 433 } 434 435 441 protected void initializeCommandSink() throws Exception 442 { 443 try 444 { 445 m_sink = (Sink) m_rootContext.get( Sink.ROLE ); 446 } 447 catch ( ContextException ce ) 448 { 449 m_sink = createCommandSink(); 451 } 452 } 453 454 460 private Sink createCommandSink() throws Exception 461 { 462 final CommandManager cm = new CommandManager(); 463 464 assumeOwnership( cm ); 465 466 Class failureHandlerClass; 468 try 469 { 470 failureHandlerClass = (Class )m_rootContext.get( COMMAND_FAILURE_HANDLER_CLASS ); 471 } 472 catch ( ContextException ce ) 473 { 474 failureHandlerClass = FortressCommandFailureHandler.class; 476 } 477 CommandFailureHandler fh = (CommandFailureHandler)failureHandlerClass.newInstance(); 478 final Logger fhLogger = m_loggerManager.getLoggerForCategory( "system.command" ); 479 ContainerUtil.enableLogging( fh, fhLogger ); 480 ContainerUtil.initialize( fh ); 481 cm.setCommandFailureHandler( fh ); 482 483 m_threadManager.register( cm ); 484 485 return cm.getCommandSink(); 486 } 487 488 494 private Parameters buildThreadManagerParameters() 495 { 496 final Parameters p = new Parameters(); 497 Integer threadsPerProcessor; 498 Long threadBlockTimeout; 499 500 try 501 { 502 final Integer processors = (Integer ) m_rootContext.get( "processors" ); 503 p.setParameter( "processors", processors.toString() ); 504 } 505 catch ( ContextException e ) 506 { 507 } 508 509 try 510 { 511 threadsPerProcessor = (Integer ) m_rootContext.get( THREADS_CPU ); 512 } 513 catch ( ContextException e ) 514 { 515 threadsPerProcessor = new Integer ( 2 ); 516 } 517 518 p.setParameter( "threads-per-processor", threadsPerProcessor.toString() ); 519 520 try 521 { 522 threadBlockTimeout = (Long ) m_rootContext.get( THREAD_TIMEOUT ); 523 } 524 catch ( ContextException e ) 525 { 526 threadBlockTimeout = new Long ( 1000 ); 527 } 528 529 p.setParameter( "block-timeout", threadBlockTimeout.toString() ); 530 531 return p; 532 } 533 534 539 protected void initializePoolManager() throws Exception 540 { 541 try 542 { 543 m_poolManager = (PoolManager) m_rootContext.get( PoolManager.ROLE ); 544 } 545 catch ( ContextException ce ) 546 { 547 final PoolManager pm = new DefaultPoolManager( m_sink ); 548 assumeOwnership( pm ); 549 m_poolManager = pm; 550 } 551 } 552 553 559 protected RoleManager obtainRoleManager() throws Exception 560 { 561 564 if ( entryPresent( m_rootContext, RoleManager.ROLE ) ) 565 { 566 return (RoleManager) m_rootContext.get( RoleManager.ROLE ); 567 } 568 569 if ( !entryPresent( m_rootContext, ROLE_MANAGER_CONFIGURATION ) && 570 !entryPresent( m_rootContext, ROLE_MANAGER_CONFIGURATION_URI ) ) 571 { 572 return null; 573 } 574 575 Configuration roleConfig = 576 getConfiguration( ROLE_MANAGER_CONFIGURATION, ROLE_MANAGER_CONFIGURATION_URI ); 577 578 if ( roleConfig == null ) 579 { 580 return null; 582 } 583 584 final ClassLoader classLoader = 586 (ClassLoader ) m_rootContext.get( ClassLoader .class.getName() ); 587 588 final Logger rmLogger = m_loggerManager.getLoggerForCategory( 590 roleConfig.getAttribute( "logger", "system.roles" ) ); 591 592 final FortressRoleManager frm = new FortressRoleManager( null, classLoader ); 594 frm.enableLogging( rmLogger.getChildLogger( "defaults" ) ); 595 frm.initialize(); 596 597 final ConfigurableRoleManager rm = new ConfigurableRoleManager( frm ); 599 rm.enableLogging( rmLogger ); 600 rm.configure( roleConfig ); 601 602 assumeOwnership( rm ); 603 return rm; 604 } 605 606 protected void initializeMetaInfoManager() throws Exception 607 { 608 boolean mmSupplied = false; 609 610 try 611 { 612 m_metaInfoManager = (MetaInfoManager) m_rootContext.get( MetaInfoManager.ROLE ); 613 mmSupplied = true; 614 } 615 catch ( ContextException ce ) 616 { 617 } 619 620 RoleManager roleManager = obtainRoleManager(); 621 final boolean rmSupplied = roleManager != null; 622 623 if ( mmSupplied ) 624 { 625 if ( rmSupplied ) 626 { 627 getLogger().warn( "MetaInfoManager found, ignoring RoleManager" ); 628 } 629 630 } 632 else 633 { 634 final ClassLoader classLoader = 635 (ClassLoader ) m_rootContext.get( ClassLoader .class.getName() ); 636 637 if ( !rmSupplied ) 638 { 639 final FortressRoleManager newRoleManager = 640 new FortressRoleManager( null, classLoader ); 641 newRoleManager.enableLogging( 642 m_loggerManager.getLoggerForCategory( "system.roles.defaults" ) ); 643 newRoleManager.initialize(); 644 645 roleManager = newRoleManager; 646 } 647 648 final ServiceMetaManager metaManager = 649 new ServiceMetaManager( new Role2MetaInfoManager( roleManager ), classLoader ); 650 651 metaManager.enableLogging( m_loggerManager.getLoggerForCategory( "system.meta" ) ); 652 metaManager.initialize(); 653 assumeOwnership( metaManager ); 654 m_metaInfoManager = metaManager; 655 } 656 } 657 658 663 protected void initializeDefaultSourceResolver() throws Exception 664 { 665 final DefaultServiceManager manager = new DefaultServiceManager(); 666 final DefaultServiceSelector selector = new DefaultServiceSelector(); 667 final URLSourceFactory file = new URLSourceFactory(); 668 file.enableLogging( getLogger() ); 669 selector.put( "*", file ); 670 final ResourceSourceFactory resource = new ResourceSourceFactory(); 671 resource.enableLogging( getLogger() ); 672 selector.put( "resource", resource ); 673 674 manager.put( ResourceSourceFactory.ROLE + "Selector", selector ); 675 676 final SourceResolverImpl resolver = new SourceResolverImpl(); 677 ContainerUtil.enableLogging( resolver, getLogger() ); 678 ContainerUtil.contextualize( resolver, m_childContext ); 679 ContainerUtil.service( resolver, manager ); 680 ContainerUtil.parameterize( resolver, new Parameters() ); 681 682 m_defaultSourceResolver = resolver; 683 } 684 685 692 protected void initializeServiceManager() throws Exception 693 { 694 final ServiceManager parent = (ServiceManager) get( m_rootContext, SERVICE_MANAGER, null ); 695 final DefaultServiceManager manager = new EAServiceManager( parent, getLogger().getChildLogger("compat") ); 696 697 701 702 if ( parent == null || !parent.hasService( SourceResolver.ROLE ) ) 703 { 704 manager.put( SourceResolver.ROLE, m_defaultSourceResolver ); 705 } 706 707 Object lem = get( m_rootContext, LifecycleExtensionManager.ROLE, null); 708 709 713 714 manager.put( LoggerManager.ROLE, m_loggerManager ); 715 manager.put( Sink.ROLE, m_sink ); 716 manager.put( MetaInfoManager.ROLE, m_metaInfoManager ); 717 manager.put( PoolManager.ROLE, m_poolManager ); 718 manager.put( InstrumentManager.ROLE, m_instrumentManager ); 719 manager.put( ThreadManager.ROLE, m_threadManager ); 720 721 if ( lem != null ) 722 { 723 manager.put( LifecycleExtensionManager.ROLE, lem ); 724 } 725 726 manager.makeReadOnly(); 727 728 m_containerManagerContext.put( SERVICE_MANAGER, manager ); 729 m_childContext.put( SERVICE_MANAGER, manager ); 730 } 731 732 739 protected Configuration getConfiguration( final String configKey, final String uriKey ) 740 { 741 try 742 { 743 return (Configuration) m_rootContext.get( configKey ); 744 } 745 catch ( ContextException ce ) 746 { 747 getLogger().debug( "A preloaded Configuration was not found for key: " + configKey 748 + " This may be Ok depending on other configured context values." ); 749 } 750 751 final String configUri; 752 try 753 { 754 configUri = (String ) m_rootContext.get( uriKey ); 755 } 756 catch ( ContextException ce ) 757 { 758 getLogger().debug( "A configuration URI was not specified: " + uriKey ); 759 return null; 760 } 761 762 Source src = null; 763 try 764 { 765 src = m_defaultSourceResolver.resolveURI( configUri ); 766 if ( configBuilder == null ) 767 { 768 configBuilder = new DefaultConfigurationBuilder(); 769 } 770 771 return configBuilder.build( src.getInputStream(), src.getURI() ); 772 } 773 catch ( Exception e ) 774 { 775 getLogger().warn( "Could not read configuration file: " + configUri, e ); 776 777 return null; 778 } 779 finally 780 { 781 m_defaultSourceResolver.release( src ); 782 } 783 } 784 785 790 public Context getContainerManagerContext() 791 { 792 return m_containerManagerContext; 793 } 794 795 800 public Context getChildContext() 801 { 802 return m_childContext; 803 } 804 805 810 protected Logger getLogger() 811 { 812 if ( m_logger == null ) 813 { 814 return m_primordialLogger; 815 } 816 else 817 { 818 return m_logger; 819 } 820 } 821 822 832 protected void initializeLoggerManager() throws Exception 833 { 834 try 835 { 836 m_loggerManager = (LoggerManager) m_rootContext.get( LoggerManager.ROLE ); 838 } 839 catch ( ContextException ce ) 840 { 841 Configuration loggerManagerConfig = 844 getConfiguration( LOGGER_MANAGER_CONFIGURATION, 845 LOGGER_MANAGER_CONFIGURATION_URI ); 846 847 boolean log4j = false; 848 849 if ( loggerManagerConfig == null ) 850 { 851 loggerManagerConfig = EMPTY_CONFIG; 854 } 855 else 856 { 857 864 final String version = loggerManagerConfig.getAttribute( "version", null ); 865 if ( "log4j".equals( version ) ) 866 { 867 log4j = true; 868 } 869 else if ( "log4j:configuration".equals( loggerManagerConfig.getName() ) ) 870 { 871 log4j = true; 872 } 873 } 874 875 final String lmDefaultLoggerName = 876 (String ) get( m_rootContext, ContextManagerConstants.LOG_CATEGORY, "fortress" ); 877 final String lmLoggerName = loggerManagerConfig.getAttribute( "logger", 878 log4j ? "system.log4j" : "system.logkit" ); 879 880 if ( log4j ) 881 { 882 901 m_loggerManager = Log4JConfLoggerManager.newInstance( 902 lmDefaultLoggerName, lmLoggerName ); 903 } 904 else { 906 m_loggerManager = new LogKitLoggerManager( 908 lmDefaultLoggerName, lmLoggerName ); 909 } 910 911 ContainerUtil.enableLogging( m_loggerManager, getLogger() ); 912 ContainerUtil.contextualize( m_loggerManager, m_rootContext ); 913 ContainerUtil.configure( m_loggerManager, loggerManagerConfig ); 914 ContainerUtil.start( m_loggerManager ); 915 } 916 917 920 if ( m_logger == null ) 921 { 922 getLogger().debug( "Switching to default Logger provided by LoggerManager." ); 923 924 m_logger = m_loggerManager.getDefaultLogger(); 925 } 926 927 m_containerManagerContext.put( LOGGER, m_logger ); 929 } 930 931 protected void initializeThreadManager() throws Exception 932 { 933 try 934 { 935 m_threadManager = (ThreadManager)m_rootContext.get( ThreadManager.ROLE ); 936 } 937 catch( ContextException e ) 938 { 939 final ThreadManager tm = new TPCThreadManager(); 940 941 assumeOwnership( tm ); 942 943 final Logger tmLogger = m_loggerManager.getLoggerForCategory( "system.threadmgr" ); 945 946 ContainerUtil.enableLogging( tm, tmLogger ); 947 ContainerUtil.parameterize( tm, buildThreadManagerParameters() ); 948 ContainerUtil.initialize( tm ); 949 950 m_threadManager = tm; 951 } 952 } 953 954 964 protected void initializeInstrumentManager() throws Exception 965 { 966 try 967 { 968 m_instrumentManager = (InstrumentManager) m_rootContext.get( InstrumentManager.ROLE ); 970 } 971 catch ( ContextException ce ) 972 { 973 Configuration instrumentConfig = getConfiguration( INSTRUMENT_MANAGER_CONFIGURATION, 976 INSTRUMENT_MANAGER_CONFIGURATION_URI ); 977 if ( instrumentConfig == null ) 978 { 979 instrumentConfig = EMPTY_CONFIG; 981 } 982 983 final Logger imLogger = m_loggerManager.getLoggerForCategory( 985 instrumentConfig.getAttribute( "logger", "system.instrument" ) ); 986 987 final DefaultInstrumentManager instrumentManager = new DefaultInstrumentManager(); 989 instrumentManager.enableLogging( imLogger ); 990 instrumentManager.configure( instrumentConfig ); 991 instrumentManager.initialize(); 992 993 assumeOwnership( instrumentManager ); 994 995 m_instrumentManager = instrumentManager; 996 } 997 } 998 999 private final class DestroyOrderComparator implements Comparator 1000 { 1001 public boolean equals( final Object other ) 1002 { 1003 return other instanceof DestroyOrderComparator; 1004 } 1005 1006 public int hashCode() 1007 { 1008 return DestroyOrderComparator.class.hashCode(); 1009 } 1010 1011 public int compare( final Object a, final Object b ) 1012 { 1013 final int typeA = typeOf( a ); 1014 final int typeB = typeOf( b ); 1015 1016 if ( typeA < typeB ) return -1; 1017 if ( typeA > typeB ) return 1; 1018 return 0; 1019 } 1020 1021 private int typeOf( final Object obj ) 1022 { 1023 int retVal = 1; 1025 if ( obj instanceof CommandManager ) retVal = 0; 1026 if ( obj instanceof ThreadManager ) retVal = 2; 1027 if ( obj instanceof LoggerManager ) retVal = 3; 1028 1029 return retVal; 1030 } 1031 } 1032 1033 1037 private static final class EAServiceManager extends DefaultServiceManager 1038 { 1039 private final Logger m_ealogger; 1040 1041 public EAServiceManager( ServiceManager parent, Logger logger ) 1042 { 1043 super( parent ); 1044 m_ealogger = logger; 1045 } 1046 1047 public Object lookup(String role) throws ServiceException 1048 { 1049 if ( Queue.ROLE.equals( role ) ) 1050 { 1051 m_ealogger.info("Using deprecated role (Queue.ROLE) for the Command Sink. Use \"Sink.ROLE\" instead."); 1052 return lookup(Sink.ROLE); 1053 } 1054 1055 return super.lookup( role ); 1056 } 1057 1058 public boolean hasService(String role) 1059 { 1060 if (Queue.ROLE.equals( role ) ) return hasService(Sink.ROLE); 1061 1062 return super.hasService( role ); 1063 } 1064 } 1065} 1066 1067 | Popular Tags |