KickJava   Java API By Example, From Geeks To Geeks.

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


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.component.ComponentSelector;
22 import org.apache.avalon.framework.component.Composable;
23 import org.apache.avalon.framework.configuration.Configurable;
24 import org.apache.avalon.framework.configuration.Configuration;
25 import org.apache.avalon.framework.configuration.ConfigurationException;
26 import org.apache.avalon.framework.context.Context;
27 import org.apache.avalon.framework.context.Contextualizable;
28 import org.apache.avalon.framework.logger.AbstractLoggable;
29 import org.apache.avalon.framework.thread.ThreadSafe;
30 import org.apache.avalon.excalibur.logger.LogKitManager;
31 import org.apache.avalon.excalibur.logger.LogKitManageable;
32
33 /**
34  * Default component selector for Avalon's components.
35  *
36  * @author <a HREF="mailto:bloritsch@apache.org">Berin Loritsch</a>
37  * @author <a HREF="mailto:paul@luminas.co.uk">Paul Russell</a>
38  * @version CVS $Revision: 1.10 $ $Date: 2002/01/30 16:49:05 $
39  * @since 4.0
40  */

41 public class ExcaliburComponentSelector
42     extends AbstractLoggable
43     implements Contextualizable,
44                ComponentSelector,
45                Composable,
46                Configurable,
47                Initializable,
48                ThreadSafe,
49                Disposable,
50                RoleManageable,
51                LogKitManageable
52 {
53     /** The classloader used for this system. */
54     private final ClassLoader JavaDoc m_loader;
55
56     /** The ComponentSelector's name for logging purposes.
57      */

58     private static final String JavaDoc DEFAULT_NAME = "UnnamedSelector";
59
60     /** The role name for this instance
61      */

62     private String JavaDoc m_rolename;
63
64     /** The application context for components
65      */

66     protected Context m_context;
67
68     /** The application context for components
69      */

70     private ComponentManager m_componentManager;
71
72     /** Dynamic component handlers mapping.
73      */

74     private Map JavaDoc m_componentMapping;
75
76     /** Static configuraiton object.
77      */

78     private Configuration m_configuration;
79
80     /** Static component handlers.
81      */

82     private Map JavaDoc m_componentHandlers;
83
84     /** Flag for if this is disposed or not.
85      */

86     private boolean m_disposed;
87
88     /** Flag for if this is initialized or not.
89      */

90     private boolean m_initialized;
91
92     /** The RoleManager to get hint shortcuts
93      */

94     private RoleManager m_roles;
95
96     /** The RoleManager to get hint shortcuts
97      */

98     private LogKitManager m_logkit;
99
100     /** Create the ComponentSelector */
101     public ExcaliburComponentSelector()
102     {
103         this(Thread.currentThread().getContextClassLoader());
104     }
105
106     /** Create the ComponentSelector with a Classloader */
107     public ExcaliburComponentSelector(final ClassLoader JavaDoc loader)
108     {
109         if (loader == null)
110         {
111             m_loader = Thread.currentThread().getContextClassLoader();
112         }
113         else
114         {
115             m_loader = loader;
116         }
117
118         // Setup the maps.
119
m_componentHandlers = Collections.synchronizedMap( new HashMap JavaDoc() );
120         m_componentMapping = Collections.synchronizedMap( new HashMap JavaDoc() );
121     }
122
123     /** Provide the application Context.
124      */

125     public void contextualize( final Context context )
126     {
127         if( null == m_context )
128         {
129             m_context = context;
130         }
131     }
132
133     /** Compose the ComponentSelector so that we know what the parent ComponentManager is.
134      */

135     public void compose( final ComponentManager componentManager )
136         throws ComponentException
137     {
138         //HACK: Is this necessary???
139
if( null == m_componentManager )
140         {
141             m_componentManager = componentManager;
142         }
143     }
144
145     /** Properly initialize of the Child handlers.
146      */

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

181     public boolean hasComponent( final Object JavaDoc hint )
182     {
183         if ( ! m_initialized ) return false;
184         if ( m_disposed ) return false;
185
186         boolean exists = false;
187
188         try
189         {
190             this.release( this.select( hint ) );
191             exists = true;
192         }
193         catch ( Throwable JavaDoc t )
194         {
195             // We can safely ignore all exceptions
196
}
197
198         return exists;
199     }
200
201     /**
202      * Properly dispose of all the ComponentHandlers.
203      */

204     public void dispose()
205     {
206         synchronized(this)
207         {
208             Iterator JavaDoc keys = m_componentHandlers.keySet().iterator();
209             List JavaDoc keyList = new ArrayList JavaDoc();
210
211             while( keys.hasNext() )
212             {
213                 Object JavaDoc key = keys.next();
214                 ComponentHandler handler =
215                     (ComponentHandler)m_componentHandlers.get( key );
216
217                 handler.dispose();
218
219                 keyList.add( key );
220             }
221
222             keys = keyList.iterator();
223
224             while( keys.hasNext() )
225             {
226                 m_componentHandlers.remove( keys.next() );
227             }
228
229             keyList.clear();
230
231             m_disposed = true;
232         }
233     }
234
235     /**
236      * Return an instance of a component based on a hint. The Composable has already selected the
237      * role, so the only part left it to make sure the Component is handled.
238      */

239     public Component select( final Object JavaDoc hint )
240         throws ComponentException
241     {
242         if( !m_initialized )
243         {
244             if (getLogger().isWarnEnabled()) {
245                 getLogger().warn("Looking up component on an uninitialized ComponentManager: " + hint);
246             }
247         }
248
249
250         if( m_disposed )
251         {
252             throw new IllegalStateException JavaDoc( "You cannot select a Component from a disposed ComponentSelector" );
253         }
254
255         if( null == hint )
256         {
257             final String JavaDoc message = getName() + ": ComponentSelector Attempted to retrieve component with null hint.";
258             if (getLogger().isErrorEnabled())
259             {
260                 getLogger().error( message );
261             }
262
263             throw new ComponentException( message );
264         }
265
266         ComponentHandler handler = (ComponentHandler)m_componentHandlers.get( hint );
267
268         // Retrieve the instance of the requested component
269
if( null == handler )
270         {
271             final String JavaDoc message = getName() + ": ComponentSelector could not find the component for hint: " + hint;
272             if (getLogger().isDebugEnabled())
273             {
274                 getLogger().debug( message );
275             }
276             throw new ComponentException( message );
277         }
278
279         Component component = null;
280
281         try
282         {
283             component = handler.get();
284         }
285         catch( final Exception JavaDoc e )
286         {
287             final String JavaDoc message = getName() + ": ComponentSelector could not access the Component for hint: " + hint;
288
289             if (getLogger().isDebugEnabled())
290             {
291                 getLogger().debug( message, e );
292             }
293             throw new ComponentException( message, e );
294         }
295
296         if( null == component )
297         {
298             final String JavaDoc message = getName() + ": ComponentSelector could not find the component for hint: " + hint;
299             if (getLogger().isDebugEnabled())
300             {
301                 getLogger().debug( message );
302             }
303             throw new ComponentException( message );
304         }
305
306         m_componentMapping.put( component, handler );
307         return component;
308     }
309
310     /**
311      * Default Configuration handler for ComponentSelector.
312      */

313     public void configure( final Configuration configuration )
314         throws ConfigurationException
315     {
316         m_configuration = configuration;
317
318         if (getLogger().isDebugEnabled())
319         {
320             getLogger().debug( "ComponentSelector setting up with root element: " +
321                                m_configuration.getName() );
322         }
323
324         final String JavaDoc name = configuration.getName();
325         if( name.equals( "component" ) )
326         {
327             m_rolename = m_configuration.getAttribute( "role" );
328         }
329         else
330         {
331             m_rolename = m_roles.getRoleForName( name );
332         }
333
334         Configuration[] instances = m_configuration.getChildren();
335
336         for( int i = 0; i < instances.length; i++ )
337         {
338             final Object JavaDoc hint = instances[ i ].getAttribute( "name" ).trim();
339             final String JavaDoc className;
340
341             if( "component-instance".equals( instances[i].getName() ) )
342             {
343                 className = (String JavaDoc)instances[i].getAttribute( "class" ).trim();
344             }
345             else
346             {
347                 className = m_roles.getDefaultClassNameForHint( m_rolename,
348                                                                 instances[i].getName() );
349             }
350
351             try
352             {
353                 final Class JavaDoc clazz = m_loader.loadClass( className );
354                 addComponent( hint, clazz, instances[i]);
355             }
356             catch( final ClassNotFoundException JavaDoc cnfe )
357             {
358                 final String JavaDoc message =
359                     "The component instance for '" + hint +
360                     "' has an invalid class name (" + className + ").";
361                 if (getLogger().isErrorEnabled())
362                 {
363                     getLogger().error( message, cnfe );
364                 }
365
366                 throw new ConfigurationException( message, cnfe );
367             }
368             catch( final ComponentException ce )
369             {
370                 if (getLogger().isErrorEnabled())
371                 {
372                     getLogger().error( "The component instance for '" + hint +
373                     "' is not valid.", ce );
374                 }
375
376                 throw new ConfigurationException( "Could not set up component", ce );
377             }
378             catch( final Exception JavaDoc e )
379             {
380                 if (getLogger().isErrorEnabled())
381                 {
382                     getLogger().error("Unexpected exception for hint: " + hint, e);
383                 }
384                 throw new ConfigurationException( "Unexpected exception", e );
385             }
386         }
387     }
388
389     /**
390      * Configure the RoleManager
391      */

392     public void setRoleManager( final RoleManager roles )
393     {
394         if( null == m_roles )
395         {
396             m_roles = roles;
397         }
398     }
399
400     /**
401      * Configure the LogKitManager
402      */

403     public void setLogKitManager( final LogKitManager logkit )
404     {
405         if( null == m_logkit )
406         {
407             m_logkit = logkit;
408         }
409     }
410
411     /**
412      * Release the Component to the propper ComponentHandler.
413      */

414     public void release( final Component component )
415     {
416         if( null == component )
417         {
418             return;
419         }
420
421         final ComponentHandler handler =
422             (ComponentHandler)m_componentMapping.get( component );
423
424         if( null == handler )
425         {
426             return;
427         }
428
429         try {
430             handler.put( component );
431         } catch (Exception JavaDoc e) {
432             if (getLogger().isDebugEnabled())
433             {
434                 getLogger().debug("Error trying to release component", e);
435             }
436         }
437
438         m_componentMapping.remove( component );
439     }
440
441     /** Add a new component to the manager.
442      * @param hint the hint name for the new component.
443      * @param component the class of this component.
444      * @param Configuration the configuration for this component.
445      */

446     public void addComponent( final Object JavaDoc hint,
447                               final Class JavaDoc component,
448                               final Configuration configuration )
449         throws ComponentException
450     {
451         if ( m_initialized )
452         {
453             throw new ComponentException("Cannot add components to an initialized ComponentSelector", null);
454         }
455
456         try
457         {
458             final ComponentHandler handler =
459                 ComponentHandler.getComponentHandler( component,
460                                                       configuration,
461                                                       m_componentManager,
462                                                       m_context,
463                                                       m_roles,
464                                                       m_logkit );
465
466             handler.setLogger( getLogger() );
467             handler.initialize();
468             m_componentHandlers.put( hint, handler );
469
470             if (getLogger().isDebugEnabled())
471             {
472                 getLogger().debug( "Adding " + component.getName() + " for " + hint.toString() );
473             }
474         }
475         catch( final Exception JavaDoc e )
476         {
477             final String JavaDoc message =
478                 "Could not set up Component for hint: " + hint;
479             if (getLogger().isErrorEnabled())
480             {
481                 getLogger().error( message, e);
482             }
483
484             throw new ComponentException( message, e );
485         }
486     }
487
488     /** Add a static instance of a component to the manager.
489      * @param hint the hint for the component.
490      * @param instance the instance of the component.
491      */

492     public void addComponentInstance( final Object JavaDoc hint, final Component instance )
493     {
494         if ( m_initialized )
495         {
496             throw new IllegalStateException JavaDoc("Cannot add components to an initialized ComponentSelector");
497         }
498
499         try
500         {
501             final ComponentHandler handler =
502                 ComponentHandler.getComponentHandler( instance );
503             handler.setLogger( getLogger() );
504             handler.initialize();
505             m_componentHandlers.put( hint, handler );
506
507             if (getLogger().isDebugEnabled())
508             {
509                 getLogger().debug( "Adding " + instance.getClass().getName() +
510                                    " for " + hint.toString() );
511             }
512         }
513         catch( final Exception JavaDoc e )
514         {
515             if (getLogger().isErrorEnabled())
516             {
517                 getLogger().error( "Could not set up Component for hint: " + hint, e );
518             }
519         }
520     }
521
522     /**
523      * Return this selector's configuration name or a default name if no such
524      * configuration was provided. This accounts for the case when a static
525      * component instance has been added through
526      * <code>addComponentInstance</code> with no associated configuration
527      */

528     private String JavaDoc getName()
529     {
530         if( null != m_configuration &&
531             !m_configuration.getName().equals( "" ) )
532         {
533             return m_configuration.getName();
534         }
535
536         return DEFAULT_NAME;
537     }
538 }
539
Popular Tags