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>

Reply via email to