KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > util > ContextManager


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

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 JavaDoc;
62 import java.util.Collections JavaDoc;
63 import java.util.Comparator JavaDoc;
64 import java.util.Iterator JavaDoc;
65
66 /**
67  * <p>You can get two different contexts from the ContextManager:
68  * the container context (m_childContext)
69  * and the container manager context (m_containerManagerContext)</p>
70  *
71  * <p>You can get two different contexts from the ContextManager: the child
72  * context and the impl manager context. The former contains all
73  * managers, such as the pool manager etc. necessary for a child impl to
74  * create additional child containers. The impl manager context contains
75  * all of the child context, but also initialization parameters for the
76  * impl, such as a Configuration object, a ComponentLocator, etc., that
77  * the impl wants, but does not want to pass on to its children.</p>
78  *
79  * <p>The container manager context is used to provide the container manager
80  * with all the data needed to initialize the container.</p>
81  * <p>The container context is passed directly to the container.</p>
82  *
83  * <p>The ContextManager will sometimes create new components, such as
84  * a service manager, a pool manager, etc. It will manage these components
85  * and dispose of them properly when it itself is disposed .</p>
86  *
87  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
88  * @version CVS $Revision: 1.51 $ $Date: 2004/02/28 15:16:26 $
89  * @since 4.1
90  */

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     /**
105      * The root context.
106      */

107     protected final Context m_rootContext;
108
109     /**
110      * The context of the new impl. This context has the rootContext
111      * as its parent. Put everything here that you want the new impl
112      * to have in its own context.
113      */

114     protected final DefaultContext m_childContext;
115
116     /**
117      * Container manager's context. This context has the child context
118      * as parent. Put things here that you want the impl manager
119      * to see, but do not wish to expose to the impl.
120      */

121     protected final DefaultContext m_containerManagerContext;
122
123     protected Logger m_logger;
124     protected final Logger m_primordialLogger;
125
126     /**
127      * Source resolver used to read-in the configurations.
128      * and provided as a default source resolver if the
129      * user has not supplied a ServiceManager.
130      */

131     protected SourceResolver m_defaultSourceResolver;
132
133     /**
134      * The logger manager in use.
135      * Either supplied via rootContext, or created locally.
136      */

137     protected LoggerManager m_loggerManager;
138
139     /**
140      * The Sink in use.
141      * Either supplied via rootContext or created locally.
142      */

143     protected Sink m_sink;
144
145     /**
146      * The MetaInfoManager to be used by the container.
147      * Either supplied via rootContext or created locally.
148      */

149     protected MetaInfoManager m_metaInfoManager;
150
151     /**
152      * The PoolManager to be used by the container.
153      * Either supplied via rootContext or created locally.
154      */

155     protected PoolManager m_poolManager;
156
157     /**
158      * The ThreadManager to be used by the container.
159      * Either supplied via rootContext or created locally.
160      */

161     protected ThreadManager m_threadManager;
162
163     /**
164      * The InstrumentManager to be used by the container.
165      * Either supplied via rootContext or created locally.
166      */

167     protected InstrumentManager m_instrumentManager;
168     /**
169      * The components that are "owned" by this context and should
170      * be disposed by it. Any manager that is created as a result
171      * of it not being in the rootContext, or having been created
172      * by the ContextManager should go in here.
173      */

174     private final ArrayList JavaDoc ownedComponents = new ArrayList JavaDoc();
175
176     /**
177      * The ConfigurationBuilder is instantiated lazilly in getConfiguration
178      * to avoid LinkageErrors in some environments.
179      */

180     private DefaultConfigurationBuilder configBuilder;
181
182     /**
183      * Create a new ContextManager.
184      *
185      * @param rootContext the default values.
186      * @param logger logger to use when creating new components.
187      */

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         // The primordial logger is used for all output up until the point where
196
// the logger manager has been initialized. However it is set into
197
// two objects used to load the configuration resource files within
198
// the ContextManager. Any problems loading these files will result in
199
// warning or error messages. However in most cases, the debug
200
// information should not be displayed, so turn it off by default.
201
// Unfortunately, there is not a very good place to make this settable.
202
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     /**
213      * Method to assume ownership of one of the managers the
214      * <code>ContextManager</code> created. Ownership means that the
215      * <code>ContextManager</code> is responsible for destroying the
216      * manager when the <code>ContextManager</code> is destroyed.
217      *
218      * @param object The object being claimed
219      *
220      * @throws IllegalArgumentException if the object is null.
221      */

222     protected void assumeOwnership( final Object JavaDoc object )
223     {
224         if ( object == null )
225         {
226             throw new NullPointerException JavaDoc( "object: Can not assume ownership of a null!" );
227         }
228         ownedComponents.add( object );
229     }
230
231     /**
232      * Initialize the <code>ContextManager</code>. This will cause the
233      * <code>ContextManager</code> to create any managers it needs.
234      *
235      * @throws Exception if there is a problem at any point in the
236      * initialization.
237      */

238     public void initialize() throws Exception JavaDoc
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     /**
258      * Load the configuration file that the Container will need to operate.
259      */

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                 // Guess there is none.
276
return;
277             }
278             else
279             {
280                 m_containerManagerContext.put( CONFIGURATION, containerConfig );
281             }
282         }
283     }
284
285     /**
286      * Initialize the context that will be passed into the impl.
287      *
288      * @throws Exception if any of the parameters cannot be copied properly.
289      */

290     protected void initializeContext() throws Exception JavaDoc
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         // hide from the container implementation what it does not need
305
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     /**
323      * Copies the specified entry from the <code>rootContext</code> to the
324      * <code>containerManagerContext</code>.
325      *
326      * @throws ContextException if the parameter does not exist
327      */

328     protected void copyEntry( final String JavaDoc key ) throws ContextException
329     {
330         m_containerManagerContext.put( key, m_rootContext.get( key ) );
331         m_childContext.put( key, null );
332     }
333
334     /**
335      * Checks if a specified entry in <code>context</code>
336      * has been supplied by the invoker.
337      *
338      * @param context The context to check
339      * @param key The key name to check
340      */

341     protected boolean entryPresent( Context context, final String JavaDoc key )
342     {
343         boolean isPresent = false;
344
345         try
346         {
347             context.get( key );
348             isPresent = true;
349         }
350         catch ( ContextException ce )
351         {
352             // It is not present, so the value remains false
353
}
354
355         return isPresent;
356     }
357
358     /**
359      * Disposes all items that this ContextManager has created.
360      */

361     public void dispose()
362     {
363         // Dispose all items owned by ContextManager
364
disposeOwned();
365
366         // Now dispose the Logger (cannot log to logger after its shutdown)
367
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 JavaDoc ex)
377         {
378             if ( m_primordialLogger.isDebugEnabled() )
379             {
380                 m_primordialLogger.debug( "Failed to shutdown loggerManager", ex );
381             }
382         }
383     }
384
385     /**
386      * Disposes all items ContextManager has assumed ownership over
387      */

388     public void disposeOwned()
389     {
390         Collections.sort( ownedComponents, new DestroyOrderComparator() );
391
392         // Dispose owned components
393
final Iterator JavaDoc ownedComponentsIter = ownedComponents.iterator();
394         while ( ownedComponentsIter.hasNext() )
395         {
396             final Object JavaDoc 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 JavaDoc 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     /**
415      * Convenience method to obtain a value, or defer to a default if it does
416      * not exist.
417      *
418      * @param context The context object we intend to get a value from.
419      * @param key The key we want to use to get the value.
420      * @param defaultValue The default value we return if the key does not
421      * exist.
422      */

423     protected Object JavaDoc get( final Context context, final String JavaDoc key, final Object JavaDoc defaultValue )
424     {
425         try
426         {
427             return context.get( key );
428         }
429         catch ( ContextException ce )
430         {
431             return defaultValue;
432         }
433     }
434
435     /**
436      * Set up the CommandSink to enable asynchronous management.
437      *
438      * @throws Exception if the <code>CommandSink</code> could not be
439      * created.
440      */

441     protected void initializeCommandSink() throws Exception JavaDoc
442     {
443         try
444         {
445             m_sink = (Sink) m_rootContext.get( Sink.ROLE );
446         }
447         catch ( ContextException ce )
448         {
449             // No CommandSink specified, create a default one
450
m_sink = createCommandSink();
451         }
452     }
453
454     /**
455      * Helper method for creating a default CommandSink
456      *
457      * @return a default <code>CommandSink</code>
458      * @throws Exception if an error occurs
459      */

460     private Sink createCommandSink() throws Exception JavaDoc
461     {
462         final CommandManager cm = new CommandManager();
463
464         assumeOwnership( cm );
465
466         // Set the CommandFailureHandler
467
Class JavaDoc failureHandlerClass;
468         try
469         {
470             failureHandlerClass = (Class JavaDoc)m_rootContext.get( COMMAND_FAILURE_HANDLER_CLASS );
471         }
472         catch ( ContextException ce )
473         {
474             // Not set. Use the default.
475
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     /**
489      * Helper method for creating ThreadManager configuration.
490      *
491      * @return ThreadManager configuration as a <code>Parameters</code>
492      * instance
493      */

494     private Parameters buildThreadManagerParameters()
495     {
496         final Parameters p = new Parameters();
497         Integer JavaDoc threadsPerProcessor;
498         Long JavaDoc threadBlockTimeout;
499
500         try
501         {
502             final Integer JavaDoc processors = (Integer JavaDoc) m_rootContext.get( "processors" );
503             p.setParameter( "processors", processors.toString() );
504         }
505         catch ( ContextException e )
506         {
507         }
508
509         try
510         {
511             threadsPerProcessor = (Integer JavaDoc) m_rootContext.get( THREADS_CPU );
512         }
513         catch ( ContextException e )
514         {
515             threadsPerProcessor = new Integer JavaDoc( 2 );
516         }
517
518         p.setParameter( "threads-per-processor", threadsPerProcessor.toString() );
519
520         try
521         {
522             threadBlockTimeout = (Long JavaDoc) m_rootContext.get( THREAD_TIMEOUT );
523         }
524         catch ( ContextException e )
525         {
526             threadBlockTimeout = new Long JavaDoc( 1000 );
527         }
528
529         p.setParameter( "block-timeout", threadBlockTimeout.toString() );
530
531         return p;
532     }
533
534     /**
535      * Set up the Pool Manager for the managed pool.
536      *
537      * @throws Exception if there is an error.
538      */

539     protected void initializePoolManager() throws Exception JavaDoc
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     /**
554      * Set up a RoleManager for the Container if configuration for
555      * it has been supplied.
556      *
557      * @throws Exception if there is an error.
558      */

559     protected RoleManager obtainRoleManager() throws Exception JavaDoc
560     {
561         /* we don't want an error message from getConfiguration, so
562          * check if there is job to do first
563          */

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             // Something went wrong, but the error has already been reported
581
return null;
582         }
583
584         // Lookup the context class loader
585
final ClassLoader JavaDoc classLoader =
586                 (ClassLoader JavaDoc) m_rootContext.get( ClassLoader JavaDoc.class.getName() );
587
588         // Create a logger for the role manager
589
final Logger rmLogger = m_loggerManager.getLoggerForCategory(
590                 roleConfig.getAttribute( "logger", "system.roles" ) );
591
592         // Create a parent role manager with all the default roles
593
final FortressRoleManager frm = new FortressRoleManager( null, classLoader );
594         frm.enableLogging( rmLogger.getChildLogger( "defaults" ) );
595         frm.initialize();
596
597         // Create a role manager with the configured roles
598
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 JavaDoc
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             // okay, we will create one
618
}
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             // Otherwise everything is ok, and we continue on (i.e. return)
631
}
632         else
633         {
634             final ClassLoader JavaDoc classLoader =
635                     (ClassLoader JavaDoc) m_rootContext.get( ClassLoader JavaDoc.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     /**
659      * Initialize the default source resolver
660      *
661      * @throws Exception when there is an error.
662      */

663     protected void initializeDefaultSourceResolver() throws Exception JavaDoc
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     /**
686      * Get a reference to the initial ComponentLocator used by the
687      * ContainerManager to hold the Components used for parsing the config
688      * files and setting up the environment.
689      *
690      * @throws Exception when there is an error.
691      */

692     protected void initializeServiceManager() throws Exception JavaDoc
693     {
694         final ServiceManager parent = (ServiceManager) get( m_rootContext, SERVICE_MANAGER, null );
695         final DefaultServiceManager manager = new EAServiceManager( parent, getLogger().getChildLogger("compat") );
696
697         /**
698          * If there is a parent ServiceManager, we need to see if it has a SourceResolver,
699          * and if not, make sure that one is available to fortress
700          */

701
702         if ( parent == null || !parent.hasService( SourceResolver.ROLE ) )
703         {
704             manager.put( SourceResolver.ROLE, m_defaultSourceResolver );
705         }
706
707         Object JavaDoc lem = get( m_rootContext, LifecycleExtensionManager.ROLE, null);
708
709         /**
710          * Role manager won't be passed here as it is now only
711          * an utility for reading ECM role files.
712          */

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     /**
733      * Get a configuration based on a config and URI key.
734      *
735      * @param configKey Get the <code>Configuration</code> object directly
736      * from the context.
737      * @param uriKey Get the uri from the context.
738      */

739     protected Configuration getConfiguration( final String JavaDoc configKey, final String JavaDoc 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 JavaDoc configUri;
752         try
753         {
754             configUri = (String JavaDoc) 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 JavaDoc 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     /**
786      * Finalizes and returns the context.
787      *
788      * @return a <code>Context</code>
789      */

790     public Context getContainerManagerContext()
791     {
792         return m_containerManagerContext;
793     }
794
795     /**
796      * Finalizes and returns the context.
797      *
798      * @return a <code>Context</code>
799      */

800     public Context getChildContext()
801     {
802         return m_childContext;
803     }
804
805     /**
806      * Get a reference the Logger.
807      *
808      * @return a <code>Logger</code>
809      */

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     /**
823      * Will set up a LogKitLoggerManager if none is supplied. This can be
824      * overridden if you don't want a LogKitLoggerManager.
825      *
826      * <p>The postcondition is that
827      * <code>childContext.get( LoggerManager.ROLE )</code> should
828      * return a valid logger manager.</p>
829      *
830      * @throws Exception if it cannot instantiate the LoggerManager
831      */

832     protected void initializeLoggerManager() throws Exception JavaDoc
833     {
834         try
835         {
836             // Try copying an already existing logger manager from the override context.
837
m_loggerManager = (LoggerManager) m_rootContext.get( LoggerManager.ROLE );
838         }
839         catch ( ContextException ce )
840         {
841             // Should we set one up?
842
// Try to get a configuration for it...
843
Configuration loggerManagerConfig =
844                     getConfiguration( LOGGER_MANAGER_CONFIGURATION,
845                             LOGGER_MANAGER_CONFIGURATION_URI );
846
847             boolean log4j = false;
848
849             if ( loggerManagerConfig == null )
850             {
851                 // Create an empty configuration so that
852
// a default logger can be created.
853
loggerManagerConfig = EMPTY_CONFIG;
854             }
855             else
856             {
857                 /*
858                  * We rely on namespace handing being turned off in DefaultConfiguration
859                  * builder here. TODO: add code that tests
860                  * root element for name "configuration" and for the correct Log4J
861                  * configuration namespace (not currently known to me - Anton Tagunov)
862                  * to survive if a namespace-enabled configuration has been passed to us.
863                  */

864                 final String JavaDoc 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 JavaDoc lmDefaultLoggerName =
876                     (String JavaDoc) get( m_rootContext, ContextManagerConstants.LOG_CATEGORY, "fortress" );
877             final String JavaDoc lmLoggerName = loggerManagerConfig.getAttribute( "logger",
878                     log4j ? "system.log4j" : "system.logkit" );
879
880             if ( log4j )
881             {
882                 /**
883                  * Working around a weird compilation problem: with JDK 1.4.1-b21
884                  * on Win2K couldn't get the following statement to compile:
885                  *
886                  * m_loggerManager =
887                  * new Log4JConfLoggerManager( lmDefaultLoggerName, lmLoggerName );
888                  *
889                  * javac kept complaining:
890                  *
891                  * file org\apache\log4j\spi\LoggerRepository.class not found
892                  * new Log4JConfLoggerManager( lmDefaultLoggerName, lmLoggerName );
893                  *
894                  * ... ContextManager.java:xxx: cannot access org.apache.log4j.spi.LoggerRepository
895                  * file org\apache\log4j\spi\LoggerRepository.class not found
896                  * m_loggerManager = new Log4JConfLoggerManager( lmDefaultLoggerName, lmLoggerName );
897                  * ^
898                  *
899                  * - Anton Tagunov
900                  */

901                 m_loggerManager = Log4JConfLoggerManager.newInstance(
902                         lmDefaultLoggerName, lmLoggerName );
903             }
904             else // LogKitLoggerManager
905
{
906                 // Setup the Logger Manager
907
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         // Since we now have a LoggerManager, we can update the this.logger field
918
// if it is null and start logging to the "right" logger.
919

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         // pass our own logger to the ContainerManager
928
m_containerManagerContext.put( LOGGER, m_logger );
929     }
930
931     protected void initializeThreadManager() throws Exception JavaDoc
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             // Get the context Logger Manager
944
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     /**
955      * Will set up an InstrumentManager if none is supplied. This can be
956      * overridden if you don't want an InstrumentManager
957      *
958      * <p>The postcondition is that
959      * <code>childContext.get( InstrumentManager.ROLE )</code> should
960      * return a valid instrument manager.</p>
961      *
962      * @throws Exception if it cannot instantiate the InstrumentManager
963      */

964     protected void initializeInstrumentManager() throws Exception JavaDoc
965     {
966         try
967         {
968             // Try copying an already existing instrument manager from the override context.
969
m_instrumentManager = (InstrumentManager) m_rootContext.get( InstrumentManager.ROLE );
970         }
971         catch ( ContextException ce )
972         {
973             // Should we set one up?
974
// Try to get a configuration for it...
975
Configuration instrumentConfig = getConfiguration( INSTRUMENT_MANAGER_CONFIGURATION,
976                     INSTRUMENT_MANAGER_CONFIGURATION_URI );
977             if ( instrumentConfig == null )
978             {
979                 // No config.
980
instrumentConfig = EMPTY_CONFIG;
981             }
982
983             // Get the logger for the instrument manager
984
final Logger imLogger = m_loggerManager.getLoggerForCategory(
985                     instrumentConfig.getAttribute( "logger", "system.instrument" ) );
986
987             // Set up the Instrument Manager
988
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 JavaDoc
1000    {
1001        public boolean equals( final Object JavaDoc 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 JavaDoc a, final Object JavaDoc 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 JavaDoc obj )
1022        {
1023            int retVal = 1; // Doesn't matter the type
1024

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    /**
1034     * This is a compatibility thing for early adopters of Fortress so that they will use the
1035     * correct ROLE for the CommandSink.
1036     */

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 JavaDoc lookup(String JavaDoc 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 JavaDoc 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