KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > fortress > impl > handler > ComponentFactory


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.impl.handler;
19
20 import org.apache.avalon.excalibur.logger.LoggerManager;
21 import org.apache.avalon.fortress.util.LifecycleExtensionManager;
22 import org.apache.avalon.framework.CascadingException;
23 import org.apache.avalon.framework.component.Composable;
24 import org.apache.avalon.framework.component.WrapperComponentManager;
25 import org.apache.avalon.framework.configuration.Configuration;
26 import org.apache.avalon.framework.container.ContainerUtil;
27 import org.apache.avalon.framework.context.Context;
28 import org.apache.avalon.framework.context.ContextException;
29 import org.apache.avalon.framework.context.DefaultContext;
30 import org.apache.avalon.framework.logger.LogKit2AvalonLoggerAdapter;
31 import org.apache.avalon.framework.logger.Loggable;
32 import org.apache.avalon.framework.logger.Logger;
33 import org.apache.avalon.framework.parameters.Parameterizable;
34 import org.apache.avalon.framework.parameters.Parameters;
35 import org.apache.avalon.framework.service.ServiceManager;
36 import org.apache.excalibur.instrument.AbstractLogEnabledInstrumentable;
37 import org.apache.excalibur.instrument.CounterInstrument;
38 import org.apache.excalibur.mpool.ObjectFactory;
39
40 /**
41  * Factory for Avalon components.
42  *
43  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
44  * @version CVS $Revision: 1.28 $ $Date: 2004/02/28 15:16:25 $
45  * @since 4.0
46  */

47 public final class ComponentFactory
48     extends AbstractLogEnabledInstrumentable
49     implements ObjectFactory
50 {
51     private final CounterInstrument m_newInstance;
52     private final CounterInstrument m_dispose;
53
54     /** The class which this <code>ComponentFactory</code>
55      * should create.
56      */

57     private final Class JavaDoc m_componentClass;
58
59     /** The Context for the component
60      */

61     private final Context m_context;
62
63     /** The component manager for this component.
64      */

65     private final ServiceManager m_serviceManager;
66
67     /** The configuration for this component.
68      */

69     private final Configuration m_configuration;
70
71     /** The LogKitManager for child ComponentSelectors
72      */

73     private final LoggerManager m_loggerManager;
74
75     /** Lifecycle extensions manager
76      */

77     private final LifecycleExtensionManager m_extManager;
78
79     /** The component's logger
80      */

81     private final Logger m_componentLogger;
82
83     /**
84      * Construct a new component factory for the specified component.
85      *
86      * @param componentClass the class to instantiate (must have a default constructor).
87      * @param configuration the <code>Configuration</code> object to pass to new instances.
88      * @param serviceManager the service manager to pass to <code>Serviceable</code>s.
89      * @param context the <code>Context</code> to pass to <code>Contexutalizable</code>s.
90      * @param loggerManager the loggerManager manager instance.
91      */

92     public ComponentFactory( final Class JavaDoc componentClass,
93                              final Configuration configuration,
94                              final ServiceManager serviceManager,
95                              final Context context,
96                              final LoggerManager loggerManager,
97                              final LifecycleExtensionManager extManager )
98     {
99         m_componentClass = componentClass;
100         m_configuration = configuration;
101         m_serviceManager = serviceManager;
102         m_context = new DefaultContext( context );
103         final String JavaDoc name = configuration.getAttribute( "id", componentClass.getName() );
104         ( (DefaultContext) m_context ).put( "component.name", name );
105         ( (DefaultContext) m_context ).put( "component.logger", configuration.getAttribute( "logger", name ) );
106         // Take each configuration attribute, and make a context entry of form "component.<attribName>"
107
String JavaDoc[] attribNames = configuration.getAttributeNames();
108
109         for ( int index = 0; index < attribNames.length; index++ )
110         {
111             String JavaDoc oneName = attribNames[index];
112             ( (DefaultContext) m_context ).put( "component." + oneName, configuration.getAttribute( oneName, "" ) );
113         }
114
115         ( (DefaultContext) m_context ).put( "component.configuration", configuration );
116         ( (DefaultContext) m_context ).makeReadOnly();
117         m_loggerManager = loggerManager;
118         m_extManager = extManager;
119         enableLogging( m_loggerManager.getLoggerForCategory( "system.factory" ) );
120         m_componentLogger = aquireLogger();
121
122         m_newInstance = new CounterInstrument( "creates" );
123         m_dispose = new CounterInstrument( "destroys" );
124
125         setInstrumentableName( "factory" );
126
127         addInstrument( m_newInstance );
128         addInstrument( m_dispose );
129     }
130
131     /**
132      * Returns a new instance of a component and optionally applies a logging channel,
133      * instrumentation, context, a component or service manager, configuration, parameters,
134      * lifecycle extensions, initialization, and execution phases based on the interfaces
135      * implemented by the component class.
136      *
137      * @return the new instance
138      */

139     public Object JavaDoc newInstance()
140         throws Exception JavaDoc
141     {
142         final Object JavaDoc component;
143
144         try
145         {
146             component = m_componentClass.newInstance();
147
148             if ( getLogger().isDebugEnabled() )
149             {
150                 final String JavaDoc message =
151                     "ComponentFactory creating new instance of " +
152                     m_componentClass.getName() + ".";
153                 getLogger().debug( message );
154             }
155
156             ContainerUtil.enableLogging( component, m_componentLogger );
157
158             if ( component instanceof Loggable )
159             {
160                 final org.apache.log.Logger logkitLogger =
161                     LogKit2AvalonLoggerAdapter.createLogger( m_componentLogger );
162                 ( (Loggable) component ).setLogger( logkitLogger );
163             }
164
165             ContainerUtil.contextualize( component, m_context );
166             if ( component instanceof Composable )
167             {
168                 ContainerUtil.compose( component, new WrapperComponentManager( m_serviceManager ) );
169             }
170             ContainerUtil.service( component, m_serviceManager );
171             ContainerUtil.configure( component, m_configuration );
172
173             if ( component instanceof Parameterizable )
174             {
175                 ContainerUtil.parameterize( component, Parameters.fromConfiguration( m_configuration ) );
176             }
177
178             m_extManager.executeCreationExtensions( component, m_context );
179
180             ContainerUtil.initialize( component );
181
182             ContainerUtil.start( component );
183
184             if ( m_newInstance.isActive() )
185             {
186                 m_newInstance.increment();
187             }
188         }
189         catch (LinkageError JavaDoc le)
190         {
191             throw new CascadingException("Could not load component", le);
192         }
193
194         return component;
195     }
196
197     private Logger aquireLogger()
198     {
199         Logger logger;
200
201         try
202         {
203             final String JavaDoc name = (String JavaDoc) m_context.get( "component.logger" );
204             if ( getLogger().isDebugEnabled() )
205             {
206                 final String JavaDoc message = "logger name is " + name;
207                 getLogger().debug( message );
208             }
209             logger = m_loggerManager.getLoggerForCategory( name );
210         }
211         catch ( ContextException ce )
212         {
213             if ( getLogger().isDebugEnabled() )
214             {
215                 final String JavaDoc message = "no logger name available, using standard name";
216                 getLogger().debug( message );
217             }
218             logger = m_loggerManager.getDefaultLogger();
219         }
220         return logger;
221     }
222
223     /**
224      * Returns the component class.
225      * @return the class
226      */

227     public final Class JavaDoc getCreatedClass()
228     {
229         return m_componentClass;
230     }
231
232     /**
233      * Disposal of the supplied component instance.
234      * @param component the component to dispose of
235      * @exception Exception if a disposal error occurs
236      */

237     public final void dispose( final Object JavaDoc component )
238         throws Exception JavaDoc
239     {
240         if ( getLogger().isDebugEnabled() )
241         {
242             final String JavaDoc message = "ComponentFactory decommissioning instance of " +
243                 getCreatedClass().getName() + ".";
244             getLogger().debug( message );
245         }
246
247         if ( getCreatedClass().equals( component.getClass() ) )
248         {
249             ContainerUtil.shutdown( component );
250
251             m_extManager.executeDestructionExtensions( component, m_context );
252
253             if ( m_dispose.isActive() )
254             {
255                 m_dispose.increment();
256             }
257         }
258         else
259         {
260             final String JavaDoc message = "The object given to be disposed does " +
261                 "not come from this ObjectFactory";
262             throw new IllegalArgumentException JavaDoc( message );
263         }
264     }
265 }
266
Popular Tags