leif 2002/11/07 10:27:53
Modified: component/src/java/org/apache/avalon/excalibur/component
DefaultComponentFactory.java
Log:
Completely rework the way components are decommissioned so that that the ECM
will work correctly with components which do not implement the Component
interface.
Revision Changes Path
1.14 +53 -62
jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/DefaultComponentFactory.java
Index: DefaultComponentFactory.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/component/src/java/org/apache/avalon/excalibur/component/DefaultComponentFactory.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- DefaultComponentFactory.java 7 Nov 2002 12:45:23 -0000 1.13
+++ DefaultComponentFactory.java 7 Nov 2002 18:27:52 -0000 1.14
@@ -78,9 +78,12 @@
private LogkitLoggerManager m_loggerManager;
/** Components created by this factory, and their associated ComponentLocator
- * proxies, if they are Composables.
+ * proxies, if they are Composables. These must be seperate maps in case
+ * a component falls into more than one category, which they often do.
*/
- private final BucketMap m_components = new BucketMap();
+ private final BucketMap m_composableProxies = new BucketMap();
+ private final BucketMap m_serviceableProxies = new BucketMap();
+ private final BucketMap m_componentProxies = new BucketMap();
/** Instrument Manager to register objects created by this factory with (May be
null). */
private InstrumentManager m_instrumentManager;
@@ -237,15 +240,16 @@
ContainerUtil.contextualize( component, m_context );
}
- Object proxy = null;
-
if( component instanceof Composable )
{
// wrap the real CM with a proxy, see below for more info
final ComponentManagerProxy manager =
new ComponentManagerProxy( m_componentManager );
ContainerUtil.compose( component, manager );
- proxy = manager;
+
+ // Store the mapping of the component manager to its proxy so it can
+ // be found to be decommissioned later.
+ m_composableProxies.put( component, manager );
}
if( component instanceof Serviceable )
@@ -254,7 +258,10 @@
final ServiceManagerProxy manager =
new ServiceManagerProxy( m_componentManager );
ContainerUtil.service( component, manager );
- proxy = manager;
+
+ // Store the mapping of the component manager to its proxy so it can
+ // be found to be decommissioned later.
+ m_serviceableProxies.put( component, manager );
}
if( component instanceof RoleManageable )
@@ -289,16 +296,15 @@
}
ContainerUtil.start( component );
- m_components.put( component, proxy );
-
// If the component is not an instance of Component then wrap it in a proxy.
// This makes it possible to use components which are not real Components
- // with the ECM.
+ // with the ECM. We need to remember to unwrap this when the component is
+ // decommissioned.
Component returnableComponent;
if( !( component instanceof Component ) )
{
returnableComponent = m_proxyGenerator.getProxy( m_role, component );
- m_components.put( returnableComponent, component );
+ m_componentProxies.put( returnableComponent, component );
}
else
{
@@ -316,40 +322,39 @@
public final void decommission( final Object component )
throws Exception
{
- Object check = m_components.get( component );
- Object decommission;
- if( check instanceof ServiceManager || check instanceof ComponentManager ||
null == check )
- {
- decommission = component;
- }
- else
- {
- decommission = check;
- m_components.remove( component );
- }
-
if( getLogger().isDebugEnabled() )
{
getLogger().debug( "ComponentFactory decommissioning instance of " +
m_componentClass.getName() + "." );
}
-
- ContainerUtil.stop( component );
- ContainerUtil.dispose( component );
-
- if( decommission instanceof Composable )
- {
- // ensure any components looked up by this Composable are properly
- // released, if they haven't been released already
- ( (ComponentManagerProxy)m_components.get( decommission )
).releaseAll();
- }
-
- if( decommission instanceof Serviceable )
- {
- ( (ServiceManagerProxy)m_components.get( decommission ) ).releaseAll();
+
+ // See if we need to unwrap this component. It may have been wrapped in a
proxy
+ // by the ProxyGenerator.
+ Object decommissionComponent = m_componentProxies.remove( component );
+ if ( null == decommissionComponent )
+ {
+ // It was not wrapped.
+ decommissionComponent = component;
+ }
+
+ ContainerUtil.stop( decommissionComponent );
+ ContainerUtil.dispose( decommissionComponent );
+
+ if ( decommissionComponent instanceof Composable )
+ {
+ // A proxy will have been created. Ensure that components created by it
+ // are also released.
+ ((ComponentManagerProxy)m_composableProxies.remove(
decommissionComponent )).
+ releaseAll();
+ }
+
+ if ( decommissionComponent instanceof Serviceable )
+ {
+ // A proxy will have been created. Ensure that components created by it
+ // are also released.
+ ((ServiceManagerProxy)m_serviceableProxies.remove(
decommissionComponent )).
+ releaseAll();
}
-
- m_components.remove( decommission );
}
/*---------------------------------------------------------------
@@ -357,25 +362,6 @@
*-------------------------------------------------------------*/
public final void dispose()
{
- Component[] components = new Component[ m_components.keySet().size() ];
-
- m_components.keySet().toArray( components );
-
- for( int i = 0; i < components.length; i++ )
- {
- try
- {
- decommission( components[ i ] );
- }
- catch( final Exception e )
- {
- if( getLogger().isWarnEnabled() )
- {
- getLogger().warn( "Error decommissioning component: " +
- getCreatedClass().getName(), e );
- }
- }
- }
}
/*---------------------------------------------------------------
@@ -474,7 +460,11 @@
extends WrapperServiceManager
{
private final ComponentManager m_realManager;
- private final Collection m_unreleased = new ArrayList();
+
+ /** Use a BucketMap rather than an ArrayList as above because this will
+ * contain Proxy instances. And proxy instances always return false for
+ * equals() making a test for inclusion in the list always fail. */
+ private final BucketMap m_unreleased = new BucketMap();
ServiceManagerProxy( final ComponentManager manager )
{
@@ -498,7 +488,7 @@
private synchronized void addUnreleased( final Object component )
{
- m_unreleased.add( component );
+ m_unreleased.put( component, component );
}
private synchronized void removeUnreleased( final Object component )
@@ -517,8 +507,9 @@
synchronized( this )
{
- unreleased = new Object[ m_unreleased.size() ];
- m_unreleased.toArray( unreleased );
+ Collection unreleasedC = m_unreleased.keySet();
+ unreleased = new Object[ unreleasedC.size() ];
+ unreleasedC.toArray( unreleased );
}
for( int i = 0; i < unreleased.length; i++ )
--
To unsubscribe, e-mail: <mailto:avalon-cvs-unsubscribe@;jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@;jakarta.apache.org>