KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > system > ContainerManager


1 /*
2  * Copyright (C) The Apache Software Foundation. All rights reserved.
3  *
4  * This software is published under the terms of the Apache Software License
5  * version 1.1, a copy of which has been included with this distribution in
6  * the LICENSE.txt file.
7  */

8 package org.apache.avalon.excalibur.system;
9
10 import org.apache.avalon.framework.activity.*;
11 import org.apache.avalon.framework.context.*;
12 import org.apache.avalon.framework.component.*;
13 import org.apache.avalon.framework.configuration.*;
14 import org.apache.avalon.framework.parameters.*;
15 import org.apache.avalon.framework.logger.*;
16 import org.apache.avalon.excalibur.logger.LoggerManager;
17 import org.apache.avalon.excalibur.logger.LogKitLoggerManager;
18 import org.apache.avalon.excalibur.util.ComponentStateValidator;
19 import org.apache.avalon.excalibur.source.*;
20 import org.apache.avalon.excalibur.command.*;
21 import org.apache.avalon.excalibur.pool.*;
22
23 import java.io.File JavaDoc;
24
25 /**
26  * The ContainerManager is a single point of contact to manage your Container
27  * resources. It takes care of creating the other managers that a Container
28  * needs to use, as well as initializing the Container. It is designed to be
29  * directly instantiated by whatever class needs to initialize your system.
30  *
31  * <p>
32  * The ContainerManager provides some constants used in the initial
33  * <code>Parameters</code> passed into the ContainerManager. The ContainerManager
34  * uses these values to create all the pieces necessary for the Container.
35  * Below is a table that describes what those options are.
36  * </p>
37  *
38  * <table>
39  * <tr>
40  * <th>Constant</th>
41  * <td>Description</th>
42  * </tr>
43  * <tr>
44  * <td><code>CONTAINER_CLASS</code></td>
45  * <td>
46  * <code>String</code> fully qualified class name for the container class.
47  * this is absolutely necessary for the ContainerManager to create the
48  * Container class instance.
49  * </td>
50  * </tr>
51  * <tr>
52  * <td><code>CONTEXT_DIRECTORY</code></td>
53  * <td>
54  * <code>String</code> path to the Context's root directory. This is
55  * used to resolve all relative paths, and the "context:" psuedo-protocol.
56  * Defaults to "./".
57  * </td>
58  * </tr>
59  * <tr>
60  * <td><code>WORK_DIRECTORY</code></td>
61  * <td>
62  * <code>String</code> path to a work area on the file system. Defaults
63  * to "/tmp".
64  * </td>
65  * </tr>
66  * <tr>
67  * <td><code>XML_PARSER</code></td>
68  * <td>
69  * <code>String</code> fully qualified class name of the Parser component
70  * implementation. It defaults to
71  * "<code>org.apache.avalon.excalibur.xml.JaxpParser</code>".
72  * </td>
73  * </tr>
74  * <tr>
75  * <td><code>LOG_CATEGORY</code></td>
76  * <td>
77  * <code>String</code> root category name for the container and its manager.
78  * If no value is given, the default (null) is used.
79  * </td>
80  * </tr>
81  * <tr>
82  * <td><code>LOGKIT_CONFIG</code></td>
83  * <td>
84  * <code>String</code> path to the LogKitLoggerManager configuration file.
85  * If this is not set, ContainerManager tries the uri
86  * <code>"context://logkit.xconf"</code>. If nothing is there, the
87  * LogKitLoggerManager is not configured. <strong>Note:</strong> If you
88  * passed in a reference to a LoggerManager yourself, ContainerManager
89  * ignores this parameter altogether.
90  * </td>
91  * </tr>
92  * <tr>
93  * <td><code>ROLE_CONFIG</code></td>
94  * <td>
95  * <code>String</code> path to the RoleManager configuration file. If
96  * this is not set, ContainerManager does not create a RoleManager at all.
97  * </td>
98  * </tr>
99  * <tr>
100  * <td><code>CONTAINER_CONFIG</code></td>
101  * <td>
102  * <code>String</code> path the points to the container's Configuration
103  * file. This value defaults to the uri "context://container.xconf".
104  * If the Container is Configurable and no entry can be found, then the
105  * Container is given an empty Configuration object.
106  * </td>
107  * </tr>
108  * <tr>
109  * <td><code>THREADS_CPU</code></td>
110  * <td>
111  * <code>Integer</code> that holds the value of the number of threads used
112  * by the ThreadManager per CPU. This defaults to 2.
113  * </td>
114  * </tr>
115  * <tr>
116  * <td><code>CPU_COUNT</code></td>
117  * <td>
118  * <code>Integer</code> representing the number of CPUs on a machine. The
119  * value is used in efficiency calculations, and determining the number of
120  * threads to have running for the CommandManager. Defaults to <code>1</code>.
121  * </td>
122  * </tr>
123  * </table>
124  *
125  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
126  * @version CVS $Revision: 1.10 $ $Date: 2002/01/28 19:29:47 $
127  */

128 public class ContainerManager
129 {
130     public static final String JavaDoc CONTEXT_DIRECTORY = Container.CONTEXT_DIRECTORY;
131     public static final String JavaDoc WORK_DIRECTORY = Container.WORK_DIRECTORY;
132     public static final String JavaDoc CONTAINER_CLASS = "container.class";
133     public static final String JavaDoc XML_PARSER = "container.xmlParser";
134     public static final String JavaDoc LOGKIT_CONFIG = "container.loggerConfig";
135     public static final String JavaDoc ROLE_CONFIG = "container.roles";
136     public static final String JavaDoc THREADS_CPU = "container.threadsPerCPU";
137     public static final String JavaDoc CONTAINER_CONFIG = "container.configFile";
138     public static final String JavaDoc LOG_CATEGORY = "container.logCategory";
139     public static final String JavaDoc CPU_COUNT = "os.arch.cpus";
140
141     private static final Configuration EMPTY_CONFIG;
142
143     static
144     {
145         DefaultConfiguration config = new DefaultConfiguration("", "", "", "");
146         config.makeReadOnly();
147         EMPTY_CONFIG = config;
148     }
149
150     private final DefaultConfigurationBuilder m_configBuilder =
151                                                      new DefaultConfigurationBuilder();
152     private final DefaultConfigurationSerializer m_configSerialzer =
153                                                      new DefaultConfigurationSerializer();
154
155     private final Parameters m_initialParameters;
156     private final ClassLoader JavaDoc m_contextClassLoader;
157     private final File JavaDoc m_contextDirectory;
158     private final File JavaDoc m_workDirectory;
159     private LoggerManager m_logManager;
160     private final PoolManager m_poolManager;
161     private final ThreadManager m_threadManager;
162     private final CommandManager m_commandManager;
163     private ComponentManager m_componentManager;
164     private Configuration m_containerConfig;
165     private Configuration m_logKitConfig;
166     private Configuration m_roleConfig;
167     private Context m_containerContext;
168     private Container m_containerInstance;
169     private ComponentStateValidator m_validator;
170     private RoleManager m_roleManager;
171
172     /**
173      * This constructor creates a new ContainerManager with a LogKitLoggerManager
174      * for managing your logging categories. If you want another LoggerManager
175      * implementation, then use the constructor with two arguments.
176      */

177     public ContainerManager( final Parameters initialParameters )
178         throws InitializationException
179     {
180         this( initialParameters, null );
181     }
182
183     /**
184      * Create a ContainerManager with all the information in the Context, and the
185      * supplied LoggerManager.
186      */

187     public ContainerManager( final Parameters initialParameters, final LoggerManager defaultLogManager )
188         throws InitializationException
189     {
190         this( initialParameters, defaultLogManager, Thread.currentThread().getContextClassLoader() );
191     }
192
193     /**
194      * Create a ContainerManager with all the information in the Context, and the
195      * supplied LoggerManager.
196      */

197     public ContainerManager( final Parameters initialParameters,
198                              final LoggerManager defaultLogManager,
199                              final ClassLoader JavaDoc rootClassLoader )
200         throws InitializationException
201     {
202         m_initialParameters = initialParameters;
203         m_contextClassLoader = rootClassLoader;
204         m_contextDirectory = new File JavaDoc(initialParameters.getParameter( CONTEXT_DIRECTORY, "./" ) );
205         m_workDirectory = new File JavaDoc( initialParameters.getParameter( CONTEXT_DIRECTORY, "/tmp" ) );
206         m_commandManager = new CommandManager();
207         m_threadManager = new TPCThreadManager( initialParameters );
208         m_threadManager.register( m_commandManager );
209         m_poolManager = new DefaultPoolManager( m_commandManager.getCommandQueue() );
210
211         if ( null != defaultLogManager )
212         {
213             m_logManager = defaultLogManager;
214         }
215
216         recycleContainer();
217     }
218
219     /**
220      * Get a reference to your Container. Typically, you would cast this to
221      * whatever interface you will use to interact with it. The actual
222      * initialization process
223      */

224     Container getContainer()
225     {
226         return m_containerInstance;
227     }
228
229     /**
230      * Get a reference to the initial ComponentManager used by the ContainerManager
231      * to hold the Components used for parsing the config files and setting up the
232      * environment.
233      */

234     public ComponentManager getComponentManager()
235     {
236         if ( null == m_componentManager )
237         {
238             DefaultComponentManager manager = new DefaultComponentManager();
239
240             try
241             {
242                 SourceResolverImpl resolver = new SourceResolverImpl();
243                 resolver.enableLogging( getLogger() );
244                 resolver.contextualize( getContext() );
245                 resolver.compose( manager );
246                 manager.put( resolver.ROLE, resolver );
247
248                 DefaultComponentSelector selector = new DefaultComponentSelector();
249                 ResourceSourceFactory resource = new ResourceSourceFactory();
250                 resource.enableLogging( getLogger() );
251                 selector.put("resource", resource);
252
253                 manager.put( resource.ROLE + "Selector", selector );
254             }
255             catch ( Exception JavaDoc e )
256             {
257                 getLogger().warn("Could not set up the initial components", e);
258             }
259
260             manager.makeReadOnly();
261             m_componentManager = manager;
262         }
263
264         return m_componentManager;
265     }
266
267     /**
268      * Override this if you have any special needs for the container (such as
269      * wanting to use your own class).
270      */

271     protected void recycleContainer()
272         throws InitializationException
273     {
274         if ( null != m_containerInstance )
275         {
276             if ( m_containerInstance instanceof Startable )
277             {
278                 try
279                 {
280                     ( (Startable) m_containerInstance ).stop();
281                 }
282                 catch (Exception JavaDoc e)
283                 {
284                     if ( getLogger().isWarnEnabled() )
285                     {
286                         getLogger().warn("Caught an exception when stopping the Container, continuing with shutdown", e);
287                     }
288                 }
289             }
290
291             if ( m_containerInstance instanceof Disposable )
292             {
293                 ( (Disposable) m_containerInstance ).dispose();
294             }
295
296             m_containerInstance = null;
297         }
298
299         Container instance = null;
300         try
301         {
302             instance = (Container) m_contextClassLoader
303                     .loadClass( m_initialParameters.getParameter( CONTAINER_CLASS ) )
304                     .newInstance();
305         }
306         catch ( Exception JavaDoc e )
307         {
308             instance = null;
309             if ( getLogger().isFatalErrorEnabled() )
310             {
311                 getLogger().fatalError( "Cannot set up the Container, this is an error I cannot recover from.", e );
312             }
313             return;
314         }
315
316         try
317         {
318             if ( instance instanceof Contextualizable )
319             {
320                 ( (Contextualizable) instance ).contextualize( getContext() );
321             }
322
323             if ( instance instanceof LogEnabled )
324             {
325                 ( (LogEnabled) instance ).enableLogging( getLogger() );
326             }
327
328             if ( instance instanceof Composable )
329             {
330                 ( (Composable) instance ).compose( getComponentManager() );
331             }
332
333             if ( instance instanceof Configurable )
334             {
335                 ( (Configurable) instance ).configure( getContainerConfig() );
336             }
337
338             if ( instance instanceof Parameterizable )
339             {
340                 ( (Parameterizable) instance ).parameterize( Parameters.fromConfiguration( getContainerConfig() ) );
341             }
342
343             if ( instance instanceof Initializable )
344             {
345                 ( (Initializable) instance ).initialize();
346             }
347
348             if ( instance instanceof Startable )
349             {
350                 ( (Startable) instance ).start();
351             }
352         }
353         catch ( Exception JavaDoc e )
354         {
355             instance = null;
356             if ( getLogger().isFatalErrorEnabled() )
357             {
358                 getLogger().fatalError( "Cannot set up the Container, this is an error I cannot recover from.", e );
359             }
360         }
361
362         m_containerInstance = instance;
363     }
364
365     /**
366      * Override this if you have any special needs for the Container's Context.
367      * Typically, this will f
368      */

369     protected Context getContext()
370     {
371         if ( null == m_containerContext )
372         {
373             DefaultContext context = new DefaultContext();
374             context.put( CONTEXT_DIRECTORY, m_contextDirectory );
375             context.put( WORK_DIRECTORY, m_workDirectory );
376             context.put( CPU_COUNT,
377                     new Integer JavaDoc(m_initialParameters.getParameterAsInteger( CPU_COUNT, 1 ) )
378             );
379             context.put( LOG_CATEGORY,
380                     m_initialParameters.getParameter(LOG_CATEGORY, null)
381             );
382             context.put( Container.CONTEXT_CLASSLOADER, m_contextClassLoader );
383             context.put( Container.ROLE_MANAGER, getRoleManager() );
384
385             context.put( Container.COMMAND_QUEUE, m_commandManager.getCommandQueue() );
386             context.put( Container.POOL_MANAGER, m_poolManager );
387
388             context.makeReadOnly();
389             m_containerContext = context;
390         }
391
392         return m_containerContext;
393     }
394
395     /**
396      * Get the LoggerManager. Will set up a LogKitLoggerManager if none is
397      * supplied. This can be overridden if you don't want a LogKitLoggerManager.
398      */

399     public LoggerManager getLoggerManager()
400     {
401         if ( null == m_logManager )
402         {
403             LogKitLoggerManager logManager = new LogKitLoggerManager(
404                     m_initialParameters.getParameter(LOG_CATEGORY, null)
405             );
406
407             try
408             {
409                 logManager.contextualize( getContext() );
410                 logManager.configure( getLogKitConfig() );
411             }
412             catch (Exception JavaDoc e)
413             {
414                 getLogger().warn("Could not completely set up LogKitLoggerManager", e);
415             }
416
417             m_logManager = logManager;
418         }
419
420         return m_logManager;
421     }
422
423     /**
424      * Get a reference the default Logger.
425      */

426     public Logger getLogger()
427     {
428         return getLoggerManager().getDefaultLogger();
429     }
430
431     /**
432      * Sets up the RoleManager. You may override this method to implement your
433      * own logic. This is the RoleManager given to the Container so that the
434      * Container can interpret it's Configuration.
435      */

436     protected RoleManager getRoleManager()
437     {
438         if ( null == m_roleManager )
439         {
440             if ( null == m_roleConfig )
441             {
442                 m_roleManager = new ExcaliburRoleManager();
443             }
444             else
445             {
446                 ExcaliburRoleManager erm = new ExcaliburRoleManager();
447                 ConfigurableRoleManager crm = new ConfigurableRoleManager( erm );
448
449                 try
450                 {
451                     crm.configure( getRoleConfig() );
452                     m_roleManager = crm;
453                 }
454                 catch ( Exception JavaDoc e )
455                 {
456                     getLogger().warn("There was a problem with the role configuration, defaulting to ExcaliburComponentManager.", e);
457                     m_roleManager = erm;
458                 }
459             }
460         }
461
462         return m_roleManager;
463     }
464
465     /**
466      * Get the Container Configuration hierarchy.
467      */

468     protected Configuration getContainerConfig()
469     {
470         if ( null == m_containerConfig )
471         {
472             String JavaDoc configFile = m_initialParameters.getParameter( CONTAINER_CONFIG, "" );
473
474             try
475             {
476                 m_containerConfig = m_configBuilder.buildFromFile( configFile );
477             }
478             catch (Exception JavaDoc e)
479             {
480                 if ( getLogger().isWarnEnabled() )
481                 {
482                     getLogger().warn("Could not read configuration file: " + configFile, e);
483                     m_containerConfig = EMPTY_CONFIG;
484                 }
485             }
486         }
487
488         return m_containerConfig;
489     }
490
491     /**
492      * Get the Container Configuration hierarchy.
493      */

494     protected Configuration getRoleConfig()
495     {
496         if ( null == m_containerConfig )
497         {
498             String JavaDoc configFile = m_initialParameters.getParameter( ROLE_CONFIG, "" );
499
500             try
501             {
502                 m_roleConfig = m_configBuilder.buildFromFile( configFile );
503             }
504             catch (Exception JavaDoc e)
505             {
506                 if ( getLogger().isWarnEnabled() )
507                 {
508                     getLogger().warn("Could not read configuration file: " + configFile, e);
509                     m_roleConfig = EMPTY_CONFIG;
510                 }
511             }
512         }
513
514         return m_roleConfig;
515     }
516
517     /**
518      * Get the Container Configuration hierarchy.
519      */

520     protected Configuration getLogKitConfig()
521     {
522         if ( null == m_containerConfig )
523         {
524             String JavaDoc configFile = m_initialParameters.getParameter( LOGKIT_CONFIG, "" );
525
526             try
527             {
528                 m_logKitConfig = m_configBuilder.buildFromFile( configFile );
529             }
530             catch (Exception JavaDoc e)
531             {
532                 if ( getLogger().isWarnEnabled() )
533                 {
534                     getLogger().warn("Could not read configuration file: " + configFile, e);
535                     m_logKitConfig = EMPTY_CONFIG;
536                 }
537             }
538         }
539
540         return m_logKitConfig;
541     }
542 }
543
Popular Tags