KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > excalibur > component > ExcaliburComponentManager


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.component;
9
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collections JavaDoc;
12 import java.util.HashMap JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Map JavaDoc;
16 import org.apache.avalon.framework.activity.Disposable;
17 import org.apache.avalon.framework.activity.Initializable;
18 import org.apache.avalon.framework.component.Component;
19 import org.apache.avalon.framework.component.ComponentException;
20 import org.apache.avalon.framework.component.ComponentManager;
21 import org.apache.avalon.framework.configuration.Configurable;
22 import org.apache.avalon.framework.configuration.Configuration;
23 import org.apache.avalon.framework.configuration.ConfigurationException;
24 import org.apache.avalon.framework.configuration.DefaultConfiguration;
25 import org.apache.avalon.framework.context.Context;
26 import org.apache.avalon.framework.context.Contextualizable;
27 import org.apache.avalon.framework.logger.AbstractLoggable;
28 import org.apache.avalon.excalibur.logger.LogKitManager;
29 import org.apache.avalon.excalibur.logger.LogKitManageable;
30
31 /**
32  * Default component manager for Avalon's components.
33  *
34  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
35  * @author <a HREF="mailto:paul@luminas.co.uk">Paul Russell</a>
36  * @version CVS $Revision: 1.16 $ $Date: 2002/01/30 16:49:04 $
37  * @since 4.0
38  */

39 public class ExcaliburComponentManager
40     extends AbstractLoggable
41     implements ComponentManager,
42                Configurable,
43                Contextualizable,
44                Initializable,
45                Disposable,
46                RoleManageable,
47                LogKitManageable
48 {
49     /** The parent ComponentManager */
50     private final ComponentManager m_parentManager;
51
52     /** The classloader used for this system. */
53     private final ClassLoader JavaDoc m_loader;
54
55     /** The application context for components
56      */

57     private Context m_context;
58
59     /** Static component mapping handlers.
60      */

61     private Map JavaDoc m_componentMapping;
62
63     /** Static component handlers.
64      */

65     private Map JavaDoc m_componentHandlers;
66
67     /** RoleInfos.
68      */

69     private RoleManager m_roles;
70
71     /** LogKitManager.
72      */

73     private LogKitManager m_logkit;
74
75     /** Is the Manager disposed or not? */
76     private boolean m_disposed;
77
78     /** Is the Manager initialized? */
79     private boolean m_initialized;
80
81     /** Create the ComponentManager */
82     public ExcaliburComponentManager()
83     {
84         this( null, Thread.currentThread().getContextClassLoader() );
85     }
86
87     /** Create the ComponentManager with a Classloader */
88     public ExcaliburComponentManager( final ClassLoader JavaDoc loader )
89     {
90         this( null, loader );
91     }
92
93     /** Create the ComponentManager with a Classloader and parent ComponentManager */
94     public ExcaliburComponentManager( final ComponentManager manager, final ClassLoader JavaDoc loader )
95     {
96         if( null == loader )
97         {
98             m_loader = Thread.currentThread().getContextClassLoader();
99         }
100         else
101         {
102             m_loader = loader;
103         }
104
105         m_parentManager = manager;
106
107         // Setup the maps.
108
m_componentHandlers = Collections.synchronizedMap( new HashMap JavaDoc() );
109         m_componentMapping = Collections.synchronizedMap( new HashMap JavaDoc() );
110     }
111
112     /** Create the ComponentManager with a parent ComponentManager */
113     public ExcaliburComponentManager(final ComponentManager manager)
114     {
115         this( manager, Thread.currentThread().getContextClassLoader() );
116     }
117
118     /** Set up the Component's Context.
119      */

120     public void contextualize( final Context context )
121     {
122         if( null == m_context )
123         {
124             m_context = context;
125         }
126     }
127
128     /**
129      * Tests for existence of a component. Please note that this test is for
130      * <strong>existing</strong> components, and a component will not be created
131      * to satisfy the request.
132      */

133     public boolean hasComponent( final String JavaDoc role )
134     {
135         if ( ! m_initialized ) return false;
136         if ( m_disposed ) return false;
137
138         boolean exists = m_componentHandlers.containsKey( role );
139
140         if ( ! exists && null != m_parentManager )
141         {
142             exists = m_parentManager.hasComponent( role );
143         }
144
145         return exists;
146     }
147
148     /** Properly initialize of the Child handlers.
149      */

150     public void initialize( )
151         throws Exception JavaDoc
152     {
153         synchronized( this )
154         {
155             m_initialized = true;
156
157             List JavaDoc keys = new ArrayList JavaDoc(m_componentHandlers.keySet());
158
159             for(int i = 0; i < keys.size(); i++ )
160             {
161                 final Object JavaDoc key = keys.get(i);
162                 final ComponentHandler handler =
163                     (ComponentHandler)m_componentHandlers.get( key );
164
165                 try
166                 {
167                     handler.initialize();
168                 }
169                 catch (Exception JavaDoc e)
170                 {
171                     if (getLogger().isErrorEnabled())
172                     {
173                         getLogger().error( "Caught an exception trying to initialize " +
174                                            "the component handler.", e );
175                     }
176                 }
177
178             }
179         }
180     }
181
182     /** Properly dispose of the Child handlers.
183      */

184     public void dispose( )
185     {
186         synchronized( this )
187         {
188             Iterator JavaDoc keys = m_componentHandlers.keySet().iterator();
189             final List JavaDoc keyList = new ArrayList JavaDoc();
190
191             while( keys.hasNext() )
192             {
193                 final Object JavaDoc key = keys.next();
194                 final ComponentHandler handler =
195                     (ComponentHandler)m_componentHandlers.get( key );
196
197                 handler.dispose();
198
199                 keyList.add( key );
200             }
201
202             keys = keyList.iterator();
203
204             while( keys.hasNext() )
205             {
206                 m_componentHandlers.remove( keys.next() );
207             }
208
209             keyList.clear();
210
211             m_disposed = true;
212         }
213     }
214
215     /**
216      * Return an instance of a component based on a Role. The Role is usually the Interface's
217      * Fully Qualified Name(FQN)--unless there are multiple Components for the same Role. In that
218      * case, the Role's FQN is appended with "Selector", and we return a ComponentSelector.
219      */

220     public Component lookup( final String JavaDoc role )
221         throws ComponentException
222     {
223         if( !m_initialized )
224         {
225             if (getLogger().isWarnEnabled()) {
226                 getLogger().warn("Looking up component on an uninitialized ComponentManager: " + role);
227             }
228         }
229
230         if( m_disposed )
231         {
232             throw new IllegalStateException JavaDoc( "You cannot lookup components on a disposed ComponentManager" );
233         }
234
235         if( null == role )
236         {
237             final String JavaDoc message =
238                 "ComponentManager Attempted to retrieve component with null role.";
239
240             if (getLogger().isErrorEnabled())
241             {
242                 getLogger().error( message );
243             }
244             throw new ComponentException( message );
245         }
246
247         ComponentHandler handler = (ComponentHandler)m_componentHandlers.get( role );
248
249         // Retrieve the instance of the requested component
250
if( null == handler )
251         {
252             if ( m_parentManager != null ) {
253                 try
254                 {
255                     return m_parentManager.lookup( role );
256                 }
257                 catch (Exception JavaDoc e)
258                 {
259                     // ignore. If the exception is thrown, we try to
260
// create the component next
261
}
262             }
263
264             if ( null != m_roles )
265             {
266                 final String JavaDoc className = m_roles.getDefaultClassNameForRole( role );
267
268                 if ( null != className )
269                 {
270                     if (getLogger().isDebugEnabled())
271                     {
272                         getLogger().debug( "Could not find ComponentHandler, attempting to create one for role: " + role );
273                     }
274
275                     try
276                     {
277                         final Class JavaDoc componentClass = m_loader.loadClass( className );
278
279                         final Configuration configuration = new DefaultConfiguration( "", "-" );
280
281                         handler =
282                                 ComponentHandler.getComponentHandler( componentClass,
283                                                                       configuration,
284                                                                       this,
285                                                                       m_context,
286                                                                       m_roles,
287                                                                       m_logkit);
288
289                         handler.setLogger( getLogger() );
290                         handler.initialize();
291                     }
292                     catch( final Exception JavaDoc e )
293                     {
294                         final String JavaDoc message = "Could not find component";
295                         if( getLogger().isDebugEnabled() )
296                         {
297                             getLogger().debug( message + " for role: " + role, e );
298                         }
299                         throw new ComponentException( message, e );
300                     }
301
302                     m_componentHandlers.put( role, handler );
303                 }
304             }
305             else
306             {
307                 getLogger().debug("Component requested without a RoleManager set.\nThat means this ComponentManager was not configured.");
308             }
309         }
310
311         if ( null == handler )
312         {
313             final String JavaDoc message = "Could not find component";
314             if( getLogger().isErrorEnabled() )
315             {
316                 getLogger().debug( message + " for role: " + role );
317             }
318             throw new ComponentException( message );
319         }
320
321         Component component = null;
322
323         try
324         {
325             component = handler.get();
326         }
327         catch( final IllegalStateException JavaDoc ise )
328         {
329             try
330             {
331                 handler.initialize();
332                 component = handler.get();
333             }
334             catch( final Exception JavaDoc e )
335             {
336                 final String JavaDoc message = "Could not access the Component";
337                 if (getLogger().isDebugEnabled())
338                 {
339                     getLogger().debug(message + " for role: " + role, e);
340                 }
341
342                 throw new ComponentException( message, e );
343             }
344         }
345         catch( final Exception JavaDoc e )
346         {
347             final String JavaDoc message = "Could not access the Component";
348             if (getLogger().isDebugEnabled())
349             {
350                 getLogger().debug(message + " for role: " + role, e);
351             }
352
353             throw new ComponentException( message, e );
354         }
355
356         m_componentMapping.put(component, handler);
357         return component;
358     }
359
360     /**
361      * Configure the ComponentManager.
362      */

363     public void configure( final Configuration configuration )
364         throws ConfigurationException
365     {
366         if( null == m_roles )
367         {
368             DefaultRoleManager role_info = new DefaultRoleManager();
369             role_info.setLogger( getLogger() );
370             role_info.configure( configuration );
371             m_roles = role_info;
372             getLogger().debug("No RoleManager given, deriving one from configuration");
373         }
374
375         // Set components
376

377         final Configuration[] configurations = configuration.getChildren();
378
379         for( int i = 0; i < configurations.length; i++ )
380         {
381             String JavaDoc type = configurations[i].getName();
382
383             if( !type.equals( "role" ) )
384             {
385                 String JavaDoc role = configurations[ i ].getAttribute( "role", "" );
386                 String JavaDoc className = configurations[ i ].getAttribute( "class", "" );
387
388                 if( role.equals( "" ) )
389                 {
390                     role = m_roles.getRoleForName( type );
391                 }
392
393                 if( null != role && !role.equals( "" ) )
394                 {
395                     if( className.equals( "" ) )
396                     {
397                         className = m_roles.getDefaultClassNameForRole( role );
398                     }
399
400                     try
401                     {
402                         if (getLogger().isDebugEnabled())
403                         {
404                             getLogger().debug( "Adding component (" + role + " = " +
405                                                className + ")" );
406                         }
407
408                         final Class JavaDoc clazz = m_loader.loadClass( className );
409                         addComponent( role, clazz, configurations[ i ] );
410                     }
411                     catch( final ClassNotFoundException JavaDoc cnfe )
412                     {
413                         final String JavaDoc message = "Could not get class ";
414
415                         if (getLogger().isErrorEnabled())
416                         {
417                             getLogger().error( message + className + " for role " + role +
418                             " on configuration element " + configurations[ i ].getName(), cnfe );
419                         }
420
421                         throw new ConfigurationException( message, cnfe );
422                     }
423                     catch( final ComponentException ce )
424                     {
425                         final String JavaDoc message = "Bad component ";
426
427                         if (getLogger().isErrorEnabled())
428                         {
429                             getLogger().error( message + className + " for role " + role +
430                             " on configuration element " + configurations[ i ].getName(), ce );
431                         }
432
433                         throw new ConfigurationException( message, ce );
434                     }
435                     catch( final Exception JavaDoc e )
436                     {
437                         if (getLogger().isErrorEnabled())
438                         {
439                             getLogger().error("Unexpected exception for hint: " + role, e);
440                         }
441                         throw new ConfigurationException( "Unexpected exception", e );
442                     }
443                 }
444             }
445         }
446     }
447
448     /**
449      * Configure the RoleManager
450      */

451     public void setRoleManager( final RoleManager roles )
452     {
453         if( null == m_roles )
454         {
455             m_roles = roles;
456         }
457     }
458
459     /**
460      * Configure the LogKitManager
461      */

462     public void setLogKitManager( final LogKitManager logkit )
463     {
464         if( null == m_logkit )
465         {
466             m_logkit = logkit;
467         }
468     }
469
470     /**
471      * Release a Component. This implementation makes sure it has a handle on the propper
472      * ComponentHandler, and let's the ComponentHandler take care of the actual work.
473      */

474     public void release( final Component component )
475     {
476         if( null == component )
477         {
478             return;
479         }
480
481         final ComponentHandler handler =
482             (ComponentHandler)m_componentMapping.get( component );
483
484         if( null != handler )
485         {
486             try
487             {
488                 handler.put( component );
489             }
490             catch (Exception JavaDoc e)
491             {
492                 if (getLogger().isDebugEnabled())
493                 {
494                     getLogger().debug("Error trying to release component.", e);
495                 }
496             }
497
498             m_componentMapping.remove( component );
499         }
500         else if ( null != m_parentManager)
501         {
502             m_parentManager.release(component);
503         }
504     }
505
506     /** Add a new component to the manager.
507      * @param role the role name for the new component.
508      * @param component the class of this component.
509      * @param Configuration the configuration for this component.
510      */

511     public void addComponent( final String JavaDoc role,
512                               final Class JavaDoc component,
513                               final Configuration configuration )
514         throws ComponentException
515     {
516         if ( m_initialized )
517         {
518             throw new ComponentException("Cannot add components to an initialized ComponentManager", null);
519         }
520
521         try
522         {
523             if (getLogger().isDebugEnabled())
524             {
525                 getLogger().debug("Attempting to get Handler for: " + role);
526             }
527
528             final ComponentHandler handler =
529                 ComponentHandler.getComponentHandler( component,
530                                                       configuration,
531                                                       this,
532                                                       m_context,
533                                                       m_roles,
534                                                       m_logkit );
535
536             if (getLogger().isDebugEnabled())
537             {
538                 getLogger().debug("Handler type = " + handler.getClass().getName());
539             }
540
541             handler.setLogger( getLogger() );
542             m_componentHandlers.put( role, handler );
543         }
544         catch( final Exception JavaDoc e )
545         {
546             throw new ComponentException( "Could not set up Component for role: " +
547                                           role, e );
548         }
549     }
550
551     /** Add a static instance of a component to the manager.
552      * @param role the role name for the component.
553      * @param instance the instance of the component.
554      */

555     public void addComponentInstance( final String JavaDoc role, final Component instance )
556     {
557         if ( m_initialized )
558         {
559             throw new IllegalStateException JavaDoc("Cannot add components to an initialized ComponentManager");
560         }
561
562         try
563         {
564             ComponentHandler handler =
565                 ComponentHandler.getComponentHandler( instance );
566             handler.setLogger( getLogger() );
567             m_componentHandlers.put( role, handler );
568         }
569         catch( final Exception JavaDoc e )
570         {
571             if (getLogger().isWarnEnabled())
572             {
573                 getLogger().warn( "Could not set up Component for role: " + role, e );
574             }
575         }
576     }
577 }
578
Popular Tags