CVS: plexus-container/src/java/org/apache/plexus/service/repository ComponentDescriptor.java,1.2,1.3 ComponentHousing.java,1.1,1.2 ComponentManager.java,1.2,1.3 ComponentRepository.java,1.2,1.3 ComponentRepositoryFactory.java,1.2,1.3 DefaultComponentRepository.java,1.8,1.9

Jason van Zyl <[email protected]> Tue, 5 Aug 2003 14:26:26 -0500
Newsgroups gmane.comp.java.plexus.devel
Message-ID <[email protected]>
Update of /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository
In directory hogshead.codehaus.org:/tmp/cvs-serv25662/src/java/org/apache/plexus/service/repository

Modified Files:
	ComponentDescriptor.java ComponentHousing.java 
	ComponentManager.java ComponentRepository.java 
	ComponentRepositoryFactory.java 
	DefaultComponentRepository.java 
Log Message:
o first pass at integrating bert's patch. checking it in so that bert can
  look at some stuff for me.


Index: ComponentDescriptor.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/ComponentDescriptor.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ComponentDescriptor.java	10 May 2003 16:39:30 -0000	1.2
+++ ComponentDescriptor.java	5 Aug 2003 19:26:24 -0000	1.3
@@ -93,6 +93,9 @@
 
     /** Instantiation strategy. */
     private String instantiationStrategy;
+    
+    /** Which lifecyclehandler to use. If null, use the containers default one. */
+    private String lifecycleHandlerId;
 
     // ----------------------------------------------------------------------
     //  Constructors
@@ -252,4 +255,22 @@
     {
         return parameters;
     }
+    /**
+     * @return
+     */
+    public String getLifecycleHandlerId()
+    {
+        return lifecycleHandlerId;
+    }
+
+    /**
+     * Set the id of the lifecycle handler the component uses
+     * 
+     * @param string
+     */
+    public void setLifecycleHandlerId(String id)
+    {
+        lifecycleHandlerId = id;
+    }
+
 }

Index: ComponentHousing.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/ComponentHousing.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- ComponentHousing.java	1 May 2003 19:35:36 -0000	1.1
+++ ComponentHousing.java	5 Aug 2003 19:26:24 -0000	1.2
@@ -1,7 +1,8 @@
 package org.apache.plexus.service.repository;
 
 /**
- *
+ * Holds the actual instantiated component
+ *  
  * 
  * @author <a href="mailto:[email protected]">Jason van Zyl</a>
  *
@@ -9,15 +10,15 @@
  */
 public class ComponentHousing
 {
-    /** Component Manager that oversees this intance. */
+    /** Component Manager that oversees this instance. */
     private ComponentManager componentManager;
 
     /** The component being housed. */
     private Object component;
 
     /** How many clients are connected to this component. */
-    private int connections;
-
+    //private int connections;
+	
     // ----------------------------------------------------------------------
     // Accessors
     // ----------------------------------------------------------------------
@@ -32,7 +33,7 @@
         this.component = component;
     }
 
-    public int getConnections()
+   /* public int getConnections()
     {
         return connections;
     }
@@ -40,9 +41,9 @@
     public void setConnections( int connections )
     {
         this.connections = connections;
-    }
+    }*/
 
-    public ComponentManager getComponentManager()
+   public ComponentManager getComponentManager()
     {
         return componentManager;
     }

Index: ComponentManager.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/ComponentManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ComponentManager.java	12 May 2003 18:57:22 -0000	1.2
+++ ComponentManager.java	5 Aug 2003 19:26:24 -0000	1.3
@@ -1,9 +1,18 @@
 package org.apache.plexus.service.repository;
 
-import org.apache.avalon.framework.service.ServiceException;
+import org.apache.plexus.lifecycle.LifecycleHandler;
+import org.apache.plexus.lifecycle.UndefinedLifecycleHandlerException;
 import org.apache.plexus.service.repository.instance.InstanceManager;
 
-/** House the information for a single instantiated service.
+import com.werken.classworlds.ConfigurationException;
+
+/** 
+ * House the information for a component
+ * and the instance manager which performs the 
+ * management of this component on behalf of this 
+ * ComponentManager.
+ * 
+ * <p>This is used so that the instance managers can be pluggable</p>
  *
  */
 public class ComponentManager
@@ -20,10 +29,11 @@
     private ComponentRepository componentRespository;
 
     /** Constuctor. */
-    public ComponentManager( ComponentDescriptor componentDescriptor,
-                             ComponentRepository componentRepository,
-                             ComponentDescriptor instanceManagerDescriptor,
-                             ClassLoader classLoader )
+    public ComponentManager(
+        ComponentDescriptor componentDescriptor,
+        ComponentRepository componentRepository,
+        ComponentDescriptor instanceManagerDescriptor,
+        ClassLoader classLoader)
     {
         this.componentDescriptor = componentDescriptor;
         this.componentRespository = componentRepository;
@@ -35,14 +45,39 @@
     // Lifecylce Management
     // ----------------------------------------------------------------------
 
-    public void initialize()
-        throws Exception
+    public void initialize() throws Exception
     {
-        Class c = classLoader.loadClass( instanceManagerDescriptor.getImplementation() );
+        Class c = classLoader.loadClass(instanceManagerDescriptor.getImplementation());
         instanceManager = (InstanceManager) c.newInstance();
-        instanceManager.setClassLoader( classLoader );
-        instanceManager.setImplementation( componentDescriptor.getImplementation() );
-        instanceManager.setComponentManager( this );
+        instanceManager.setClassLoader(classLoader);
+        instanceManager.setComponentImplementation(componentDescriptor.getImplementation());
+		instanceManager.setComponentManager( this );
+        //the lifecyclehandler used is based on the component descriptor        
+        //look it up from the component repository
+        String id = componentDescriptor.getLifecycleHandlerId();
+        if (id == null)
+        {
+            //use the default handler
+            instanceManager.setLifecycleHandler(
+                getComponentRespository().getDefaultLifecycleHandler());
+        }
+        else
+        {
+            LifecycleHandler lh;
+            try
+            {
+                lh = getComponentRespository().getLifecycleHandler(id);
+            }
+            catch (UndefinedLifecycleHandlerException e)
+            {
+                throw new ConfigurationException(
+                    "No LifecycleHandler confgured with id:"
+                        + id
+                        + " required by component with role:"
+                        + componentDescriptor.getRole());
+            }
+            instanceManager.setLifecycleHandler(lh);
+        }
         instanceManager.initialize();
     }
 
@@ -77,39 +112,69 @@
         return componentRespository;
     }
 
+	/**
+	 *
+	 * @param componentRespository
+	 */
+	public void setComponentRespository( ComponentRepository componentRespository )
+	{
+		this.componentRespository = componentRespository;
+	}
+
     /**
-     *
-     * @param componentRespository
+     * Release the component back to this manager. 
+     * 
+     * @param component
      */
-    public void setComponentRespository( ComponentRepository componentRespository )
+    public void release(Object component)
     {
-        this.componentRespository = componentRespository;
+        if (component != null)
+        {
+            getInstanceManager().release(component);
+        }
     }
 
     /**
-     *
+     * Obtain the component this manager manages.
+     * 
      * @return
      */
-    public ComponentHousing getComponentHousing()
-        throws ServiceException
+    public Object getComponent() throws Exception
+    {
+        return getInstanceManager().getComponent();
+    }
+    /**
+     *
+     * @return
+     *//*
+    public ComponentHousing getComponentHousing() throws ServiceException
     {
         try
         {
             return getInstanceManager().getInstance();
         }
-        catch ( Exception e )
+        catch (Exception e)
         {
-            throw new ServiceException( "instance-manager", e.getMessage(), e );
+            throw new ServiceException("instance-manager", e.getMessage(), e);
         }
-    }
+    }*/
 
-    public InstanceManager getInstanceManager()
+    private InstanceManager getInstanceManager()
     {
         return instanceManager;
     }
 
-    public void setInstanceManager( InstanceManager instanceManager )
+    /*   public void setInstanceManager( InstanceManager instanceManager )
+       {
+           this.instanceManager = instanceManager;
+       }*/
+
+    /**
+     * Dispose this manager. This will also cause all components this manager 
+     * manages to be disposed.
+     */
+    public void dispose()
     {
-        this.instanceManager = instanceManager;
+        getInstanceManager().dispose();
     }
 }

Index: ComponentRepository.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/ComponentRepository.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ComponentRepository.java	12 May 2003 18:57:22 -0000	1.2
+++ ComponentRepository.java	5 Aug 2003 19:26:24 -0000	1.3
@@ -1,42 +1,115 @@
 package org.apache.plexus.service.repository;
 
 import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
 import org.apache.avalon.framework.logger.Logger;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.plexus.PlexusContainer;
+import org.apache.plexus.lifecycle.LifecycleHandler;
+import org.apache.plexus.lifecycle.UndefinedLifecycleHandlerException;
+import org.apache.plexus.logging.LoggerManager;
 
-public interface ComponentRepository
-{
-    void configure( Configuration defaultConfiguration, Configuration configuration );
-
-    void initialize()
-        throws Exception;
-
-    Object lookup( String role )
-        throws ServiceException;
+/**
+ * Like the avalon service manager. Central point to get the components from.
+ *
+ *
+ */
+public interface ComponentRepository {
+	void configure(
+		Configuration defaultConfiguration,
+		Configuration configuration);
 
-    Object lookup( String role, String id )
-        throws ServiceException;
+	void contextualize(Context context);
+	/**
+	 * Initialize this repository
+	 * @throws Exception
+	 */
+	void initialize() throws Exception;
+	
+	/**
+	 * Lookup the component with the given role
+	 * 
+	 * @param role
+	 * @return
+	 * @throws ServiceException if no component with the given role exists, or there was an
+	 * error taking the component through a lifecycle
+	 */
+	Object lookup(String role) throws ServiceException;
 
-    boolean hasService( String role );
+	Object lookup(String role, String id) throws ServiceException;
 
-    boolean hasService( String role, String id );
+	/**
+	 * Test if this repository manages the component with the given role
+	 * 
+	 * @param role
+	 * @return
+	 */
+	boolean hasService(String role);
 
-    void release( Object service );
+	/**
+		 * Test if this repository manages the component with the given role
+		 * and id
+		 * 
+		 * @param role
+		 * @return
+		 */
+	boolean hasService(String role, String id);
 
-    void dispose();
+	void release(Object service);
 
-    void setPlexusContainer( PlexusContainer container );
+	/**
+	 * Dispose of this Repository
+	 *
+	 */
+	void dispose();
 
-    // Information
+	void setPlexusContainer(PlexusContainer container);
 
-    int configuredComponents();
+	// Information
 
-    int instantiatedComponents();
+	/**
+	 * Return the number of configured components
+	 */
+	int configuredComponents();
 
-    ClassLoader getClassLoader();
+	/**
+	 * Return the number of instantiated components
+	 * @return
+	 */
+	int instantiatedComponents();
 
-    void enableLogging( Logger logger );
+	ClassLoader getClassLoader();
 
-    void startComponentLifecycle( ComponentHousing housing );
+	/** Set this repositories logger */
+	void enableLogging(Logger logger);
+	
+	/** Set the logManager to be used for components */
+	void setComponentLogManager(LoggerManager logManager);
+	/**
+	 * Start the lifecycle for the component in this housing
+	 * 
+	 * @param housing
+	 */
+	//void startComponentLifecycle(ComponentHousing housing);
+	
+	/**
+	 * Return the lifecycle handler with the given id. Throws exception if no lifecycle
+	 * handler with the given id exists. 
+	 * 
+	 * <p>Note: it is recommended the returned handler is immutable</p>
+	 * 
+	 * @param id
+	 * @return
+	 */
+	LifecycleHandler getLifecycleHandler(String id)  throws UndefinedLifecycleHandlerException;
+	
+	/**
+	 * Return the default lifecycle handler. This is the handler used for components 
+	 * which don't specify a handler.
+	 * 
+	 * <p>Note: it is recommended the returned handler is immutable</p>
+	 * 
+	 * @return
+	 */
+	LifecycleHandler getDefaultLifecycleHandler();
 }

Index: ComponentRepositoryFactory.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/ComponentRepositoryFactory.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- ComponentRepositoryFactory.java	31 May 2003 18:13:13 -0000	1.2
+++ ComponentRepositoryFactory.java	5 Aug 2003 19:26:24 -0000	1.3
@@ -1,6 +1,7 @@
 package org.apache.plexus.service.repository;
 
 import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.context.Context;
 import org.apache.plexus.PlexusContainer;
 import org.apache.plexus.factory.AbstractPlexusFactory;
 import org.apache.plexus.logging.LoggerManager;
@@ -12,7 +13,8 @@
                                               Configuration configuration,
                                               LoggerManager loggerManager,
                                               PlexusContainer container,
-                                              ClassLoader classLoader )
+                                              ClassLoader classLoader,
+											  Context context )
         throws Exception
     {
         String implementation;
@@ -31,8 +33,9 @@
 
         ComponentRepository sr =
             (ComponentRepository) getInstance( implementation, classLoader );
-
+		sr.setComponentLogManager(loggerManager);
         sr.enableLogging( loggerManager.getLogger( "service-repository" ) );
+        sr.contextualize(context);
         sr.setPlexusContainer( container );
         sr.configure( defaultConfiguration, configuration );
         sr.initialize();

Index: DefaultComponentRepository.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/DefaultComponentRepository.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- DefaultComponentRepository.java	21 Jul 2003 22:40:51 -0000	1.8
+++ DefaultComponentRepository.java	5 Aug 2003 19:26:24 -0000	1.9
@@ -1,14 +1,21 @@
 package org.apache.plexus.service.repository;
 
 import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.context.Context;
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.plexus.PlexusContainer;
 import org.apache.plexus.lifecycle.LifecycleHandler;
+import org.apache.plexus.lifecycle.LifecycleHandlerHousing;
 import org.apache.plexus.lifecycle.UndefinedLifecycleHandlerException;
+import org.apache.plexus.lifecycle.LifecycleHandlerFactory;
 import org.apache.plexus.logging.AbstractLogEnabled;
-import org.apache.plexus.service.repository.instance.InstanceManager;
+import org.apache.plexus.logging.LoggerManager;
+import org.apache.plexus.util.ThreadSafeMap;
+import org.apache.plexus.util.Tracer;
 
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 /**
@@ -46,6 +53,12 @@
     protected static String POOLABLE_STRATEGY = "poolable";
     protected static String SINGLETON_STRATEGY = "singleton";
 
+    private static String INSTANCE_MANAGER = "instance-manager";
+    private static String INSTANCE_MANAGERS = "instance-managers";
+    private static String LIFECYCLE_HANDLER = "lifecycle-handler";
+    private static String LIFECYCLE_HANDLERS = "lifecycle-handlers";
+
+
     // ----------------------------------------------------------------------
     //  Instance Members
     // ----------------------------------------------------------------------
@@ -59,25 +72,57 @@
     /** Map of service descriptors keyed by role. */
     private Map componentDescriptors;
 
-    /** Map of component managers by component key. */
+    /** Map of component managers by component key. Needs to be
+     * threadSafe with lots of reads, small number of writes.*/
     private Map componentManagers;
 
-    /** Map of service capsules key by the service object. */
-    private Map componentHousings;
+    /** Map of ComponentManagers keyed by component class. Use a Map
+     * which can handle concurrent reads and writes. Will be about
+     * the same number of reads as writes
+     */
+    private Map compManagersByCompClass;
+
+    /** Map of component housings keyed by the component object. */
+    //private Map componentHousings;
 
     private PlexusContainer plexusContainer;
 
+    /** Parent containers context */
+    private Context context;
+
+    private LoggerManager loggerManager;
+
+    /** The instance manager descriptors. Seperate from the other
+     * components as they shouldn't have access to them. Keyed
+     * by instantiation strategy*/
+    private Map instanceManagerDescriptors;
+
+    private Map lifecycleHandlers;
+
+    private String defaultInstantiationStrategy;
+
+    private LifecycleHandler defaultLifecycleHandler;
+
+    /**
+     * Object to lock when creating a new component manager during
+     * component lookup. Separate from enclosing class as we have no control
+     * on what locks calling code places.
+     */
+    private Object lookupLock = new Object();
+
     /** Constructor. */
     public DefaultComponentRepository()
     {
         componentDescriptors = new HashMap();
-        componentManagers = new HashMap();
-        componentHousings = new HashMap();
+        instanceManagerDescriptors = new HashMap();
+        componentManagers = new ThreadSafeMap();
+        //componentHousings = new HashMap();
+        compManagersByCompClass = new ThreadSafeMap();
+        lifecycleHandlers = new HashMap();
     }
 
     // take the lifecycle handler stuff out of here
 
-
     // ----------------------------------------------------------------------
     // Lifecylce Management
     // ----------------------------------------------------------------------
@@ -99,6 +144,20 @@
     public void initialize()
         throws Exception
     {
+        initializeLifecycleHandlers();
+        initializeInstanceManagers();
+        initializeComponentDescriptors();
+    }
+
+    /**
+     * Grab all the component descriptors from the configuration and
+     * make them available during lookup
+     *
+     * @throws Exception
+     */
+    public void initializeComponentDescriptors()
+        throws Exception
+    {
         Configuration[] defaultComponentConfigurations =
             defaultConfiguration.getChild( COMPONENTS ).getChildren( COMPONENT );
 
@@ -117,6 +176,51 @@
 
     }
 
+    /**
+     * Grab all the InstanceManager configurations and make them available
+     * during lookup
+     *
+     * @throws Exception
+     */
+    private void initializeInstanceManagers()
+        throws Exception
+    {
+
+
+        Configuration[] defaultComponentConfigurations =
+            defaultConfiguration.getChild( INSTANCE_MANAGERS ).getChildren( INSTANCE_MANAGER );
+
+        for ( int i = 0; i < defaultComponentConfigurations.length; i++ )
+        {
+            addInstanceManagerDescriptor(
+                createComponentDescriptor( defaultComponentConfigurations[i] ) );
+        }
+
+        Configuration[] componentConfigurations =
+            configuration.getChild( INSTANCE_MANAGERS ).getChildren( INSTANCE_MANAGER );
+
+        for ( int i = 0; i < componentConfigurations.length; i++ )
+        {
+            addInstanceManagerDescriptor( createComponentDescriptor( componentConfigurations[i] ) );
+        }
+
+        defaultInstantiationStrategy = getConfiguration().getChild( INSTANCE_MANAGERS ).getAttribute(
+                "default", getDefaultConfiguration().getChild( INSTANCE_MANAGERS ).getAttribute( "default", null ) );
+
+        if ( defaultInstantiationStrategy == null || defaultInstantiationStrategy.length() == 0 )
+        {
+            throw new ConfigurationException( "No default instantiation strategy defined" );
+        }
+        if ( false == getInstanceManagerDescriptors().containsKey( defaultInstantiationStrategy ) )
+        {
+            throw new ConfigurationException(
+                "The default instantiation strategy is specified as: '"
+                + defaultInstantiationStrategy
+                + "' but no InstanceManager"
+                + " with this id is defined" );
+        }
+        getLogger().info( "Default instantiation strategy set to: '" + defaultInstantiationStrategy + "'" );
+    }
     // ----------------------------------------------------------------------
     // Accessors
     // ----------------------------------------------------------------------
@@ -153,11 +257,107 @@
         return getComponentDescriptors().size();
     }
 
+    /**
+     * @todo correct this
+     * @see org.apache.plexus.service.repository.ComponentRepository#instantiatedComponents()
+     */
     public int instantiatedComponents()
     {
+        //this is no longer correct. Each manager could
+        //be managing multiple instances. Should sum
+        //the number of component managers active
+        //connections
         return getComponentManagers().size();
     }
 
+    /**
+     *Adds all the lifecycle handlers and initializes them. Sets up the default lifecycle handler
+     */
+    private void initializeLifecycleHandlers()
+        throws Exception
+    {
+        String defaultHandlerId =
+            getConfiguration().getChild( LIFECYCLE_HANDLERS ).getAttribute(
+                "default",
+                getDefaultConfiguration().getChild( LIFECYCLE_HANDLERS ).getAttribute(
+                    "default",
+                    null ) );
+
+        if ( defaultHandlerId == null )
+        {
+            throw new ConfigurationException( "No default lifecycle handler defined" );
+        }
+
+        Configuration[] configs =
+            getConfiguration().getChild( LIFECYCLE_HANDLERS ).getChildren( LIFECYCLE_HANDLER );
+        Configuration[] defaults =
+            getDefaultConfiguration().getChild( LIFECYCLE_HANDLERS ).getChildren( LIFECYCLE_HANDLER );
+        for ( int i = 0; i < configs.length; i++ )
+        {
+            addLifecycleHandlerHousing( configs[i], false );
+        }
+        for ( int i = 0; i < defaults.length; i++ )
+        {
+            //ignore duplicates as we allow the custom configuration
+            //to override default handlers
+            addLifecycleHandlerHousing( defaults[i], true );
+        }
+
+        //grab the default LifecycleHandler. This is the one used when components don't specify
+        //one
+        LifecycleHandlerHousing housing =
+            (LifecycleHandlerHousing) lifecycleHandlers.get( defaultHandlerId );
+        if ( housing == null )
+        {
+            throw new ConfigurationException(
+                "The default LifecycleHandler is specified as: "
+                + defaultHandlerId
+                + " but no LifecycleHandler"
+                + " of this id is defined" );
+
+        }
+        defaultLifecycleHandler = housing.getHandler();
+        getLogger().info( "Default LifecycleHandler id is set to: '" + defaultHandlerId + "'" );
+    }
+
+    /**
+     * Add a LifecycleHandler to this container.
+     *
+     * @param config
+     * @param ignoreDuplicates if duplicate handlers should be quitely ignored
+     * @throws Exception
+     */
+    void addLifecycleHandlerHousing( Configuration config, boolean ignoreDuplicates )
+        throws Exception
+    {
+        LifecycleHandlerHousing housing =
+            LifecycleHandlerFactory.createLifecycleHandlerHousing(
+                config,
+                getComponnetLogManager(),
+                getClassLoader(),
+                getContext(),
+                this );
+        if ( lifecycleHandlers.containsKey( housing.getId() ) == false )
+        {
+            getLogger().info(
+                "Adding Lifecyclehandler. id="
+                + housing.getId()
+                + ", impl="
+                + housing.getImplementation() );
+            lifecycleHandlers.put( housing.getId(), housing );
+        }
+        else
+        {
+            if ( ignoreDuplicates == false )
+            {
+
+                throw new ConfigurationException(
+                    "Duplicate Lifecycle handler. Duplicate id: " + housing.getId() );
+            }
+        }
+
+    }
+
     // ----------------------------------------------------------------------
     // Package Scoped Accessors
     // ----------------------------------------------------------------------
@@ -188,17 +388,20 @@
     /**
      *
      * @return
-     */
+     *//*
     Map getComponentHousings()
     {
         return componentHousings;
-    }
+    }*/
 
     // ----------------------------------------------------------------------
     //  Component Descriptor processing and Holder creation.
     // ----------------------------------------------------------------------
 
     /**
+     * Create a new ComponentManager with the correct InstanceManager for the
+     * component specified by the given descriptor. The ComponentManager
+     * will select the correct LifecycleHandler based on the descriptor
      *
      * @return The new component instance.
      *
@@ -208,15 +411,33 @@
     ComponentManager instantiateComponentManager( ComponentDescriptor descriptor )
         throws Exception
     {
-        ComponentDescriptor instantiationManagerDescriptor = (ComponentDescriptor)
-            getComponentDescriptors().get( InstanceManager.ROLE + descriptor.getInstantiationStrategy() );
+        ComponentDescriptor instantiationManagerDescriptor;
+        String strategy = descriptor.getInstantiationStrategy();
+        //donˈt want a 'ROLE#null' lookup
+        if ( strategy == null )
+        {
+            strategy = defaultInstantiationStrategy;
+        }
+        instantiationManagerDescriptor =
+            (ComponentDescriptor) getInstanceManagerDescriptors().get( strategy );
 
-        ComponentManager componentManager = new ComponentManager( descriptor,
-                                                                  this,
-                                                                  instantiationManagerDescriptor,
-                                                                  getClassLoader() );
-        componentManager.initialize();
+        if ( instantiationManagerDescriptor == null )
+        {
+            throw new ConfigurationException(
+                "No instance manager configured with strategy: "
+                + strategy
+                + " for component with role: "
+                + descriptor.getRole() );
+        }
+        ComponentManager componentManager =
+            new ComponentManager(
+                descriptor,
+                this,
+                instantiationManagerDescriptor,
+                getClassLoader() );
 
+        componentManager.initialize();
+        //make the ComponentManager available for future requests
         getComponentManagers().put( descriptor.getComponentKey(), componentManager );
 
         return componentManager;
@@ -240,13 +461,19 @@
         componentDescriptor.setId( configuration.getChild( ID ).getValue( null ) );
 
         componentDescriptor.setInstantiationStrategy(
-            configuration.getChild( INSTANTIATION_STRATEGY ).getValue( SINGLETON_STRATEGY ) );
-
+            configuration.getChild( INSTANTIATION_STRATEGY ).getValue( null ) );
+        componentDescriptor.setLifecycleHandlerId(
+            configuration.getChild( LIFECYCLE_HANDLER ).getValue( null ) );
         componentDescriptor.setConfiguration( configuration.getChild( CONFIGURATION ) );
 
         return componentDescriptor;
     }
 
+    Map getInstanceManagerDescriptors()
+    {
+        return instanceManagerDescriptors;
+    }
+
     /**
      * Adds a component to the ServiceBroker.  If the component has a
      * ServiceSelector, the appropriate action is taken.
@@ -255,9 +482,40 @@
      */
     protected void addComponentDescriptor( ComponentDescriptor descriptor )
     {
+        if ( getLogger().isDebugEnabled() )
+        {
+            StringBuffer buff = new StringBuffer();
+            buff.append( "Adding ComponentDescriptor. role=" );
+            buff.append( descriptor.getRole() );
+            buff.append( ", id=" );
+            buff.append( descriptor.getId() );
+            buff.append( ",role-hint=" );
+            buff.append( descriptor.getRoleHint() );
+            buff.append( ",strategy=" );
+            buff.append( descriptor.getInstantiationStrategy() );
+            buff.append( ", impl=" );
+            buff.append( descriptor.getImplementation() );
+
+            getLogger().debug( buff.toString() );
+        }
         getComponentDescriptors().put( descriptor.getComponentKey(), descriptor );
     }
 
+    /**
+     * Adds a InstanceManager to this repository.
+     *
+     * @param descriptor
+     */
+    protected void addInstanceManagerDescriptor( ComponentDescriptor descriptor )
+    {
+        getLogger().info(
+            "Adding instance manager descriptor. strategy="
+            + descriptor.getInstantiationStrategy()
+            + ", impl="
+            + descriptor.getImplementation() );
+        getInstanceManagerDescriptors().put( descriptor.getInstantiationStrategy(), descriptor );
+    }
+
     // ----------------------------------------------------------------------
     // Service lookup methods
     // ----------------------------------------------------------------------
@@ -270,51 +528,92 @@
 
         Object component = null;
 
+        //have todo some synchronization stuff here as two different threads may
+        //try to create seperate instances of the same component managers. Need
+        //to block one until the other has created it.Seeing this happens once
+        //per component it shouldn't be a drag on performance
         if ( componentManager == null )
         {
-            // We need to create an instance of this componentManager.
+            //lock, and check for component manager again within
+            //synch block, as another thread may have just created one
+            synchronized ( lookupLock )
+            {
+                componentManager = getComponentManager( key );
+                if ( componentManager != null )
+                {
+                    try
+                    {
+                        return componentManager.getComponent();
+                    }
+                    catch ( Exception e )
+                    {
+                        throw new ServiceException(
+                            key,
+                            "Error retrieving component from ComponentManager" );
+                    }
+                }
+                // We need to create an instance of this componentManager.
+                getLogger().debug( "Creating new ComponentDescriptor for role: " + key );
+                ComponentDescriptor descriptor =
+                    (ComponentDescriptor) getComponentDescriptors().get( key );
 
-            ComponentDescriptor descriptor =
-                (ComponentDescriptor) getComponentDescriptors().get( key );
+                if ( descriptor == null )
+                {
+                    getLogger().error( "Non existant component: " + key );
+                    throw new ServiceException( key, "Non existant component for key " + key + "." );
+                }
 
-            if ( descriptor == null )
-            {
-                getLogger().error( "Non existant component: " + key );
-                throw new ServiceException( key, "Non existant component for key " + key + "." );
+                try
+                {
+                    componentManager = instantiateComponentManager( descriptor );
+                }
+                catch ( Exception e )
+                {
+                    getLogger().error( "Could not create component: " + key, e );
+                    throw new ServiceException(
+                        key,
+                        "Could not create component for key " + key + "!",
+                        e );
+                }
+                try
+                {
+                    component = componentManager.getComponent();
+                }
+                catch ( Exception e )
+                {
+                    throw new ServiceException(
+                        key,
+                        "Error retrieving component from ComponentManager. cause="
+                        + Tracer.traceToString( e ) );
+                }
+                if ( getLogger().isDebugEnabled() )
+                {
+                    StringBuffer buff = new StringBuffer();
+                    buff.append( "Obtained new component :role=" ).append( descriptor.getRole() );
+                    buff.append( ",impl=" ).append( descriptor.getImplementation() );
+                    buff.append( ",lifecycle-id=" ).append( descriptor.getLifecycleHandlerId() );
+                    buff.append( ",strategy=" ).append( descriptor.getInstantiationStrategy() );
+                    getLogger().debug( buff.toString() );
+                }
+                // We do this so we know what to do when releasing. Only have to do it once
+                //per component class
+                compManagersByCompClass.put( component.getClass().getName(), componentManager );
+
+                lookupLock.notifyAll();
             }
 
+        }
+        else
+        {
             try
             {
-                componentManager = instantiateComponentManager( descriptor );
+                component = componentManager.getComponent();
             }
             catch ( Exception e )
             {
-                getLogger().error( "Could not create component: " + key, e );
-                throw new ServiceException( key, "Could not create component for key " + key + "!", e );
-            }
-
-            // We do this so we know what to do when releasing.
-            ComponentHousing housing = componentManager.getComponentHousing();
-
-            if ( housing == null )
-            {
-                throw new ServiceException( key, "ComponentHousing is null.");
-            }
-
-            component = housing.getComponent();
-
-            if ( component == null )
-            {
-                throw new ServiceException( key, "Component is null.");
+                throw new ServiceException( key, "Error retrieving component from ComponentManager" );
             }
-
-            getComponentHousings().put( component, housing );
-        }
-        else
-        {
-            component = componentManager.getComponentHousing().getComponent();
         }
-
         return component;
     }
 
@@ -344,37 +643,16 @@
      */
     public synchronized void release( Object component )
     {
-        ComponentHousing housing = (ComponentHousing) getComponentHousings().get( component );
-
-        if ( housing != null )
-        {
-            // Only call the end of lifecyle events when there are
-            // no more users of this component, doing so otherwise
-            // might lead in plexus giving out a component that has
-            // been effectively extinguished or even worse, a client
-            // with an existing reference to the valid component may
-            // have the rug pulled out from under them by another
-            // client releasing the component.
-
-            try
-            {
-                endComponentLifecycle( housing );
-            }
-            catch ( Exception e )
-            {
-                getLogger().error( "Error ending component lifecycle", e );
-            }
-
-            // This is where we need to track the count for pools and reuse.
+        if ( component == null )
+            return;
 
-            // Now get rid of the Service capsule references.
-            String serviceKey = housing.getComponentManager().getComponentDescriptor().getComponentKey();
-            getComponentManagers().remove( serviceKey );
-            getComponentHousings().remove( component );
+        ComponentManager cm =
+            (ComponentManager) compManagersByCompClass.get( component.getClass().getName() );
 
-            housing = null;
-            component = null;
-        }
+        //this repository does not deal with this component
+        if ( cm == null )
+            return;
+        cm.release( component );
     }
 
     /**
@@ -382,6 +660,7 @@
      */
     public synchronized void dispose()
     {
+        getLogger().info( "Disposing ComponentRepository..." );
         disposeAllComponents();
     }
 
@@ -390,66 +669,106 @@
      */
     protected void disposeAllComponents()
     {
-        // Use an array to get the list of components; otherwise we'll
+        // Use an array to get the list of componentManagers else we'll
         // end up with a ConcurrentModificationException if we use an
         // Iterator to cycle through the set because release() makes
         // changes to the set as well.
+        //<== now not important as each component manager does this.
 
-        Object components[] = getComponentHousings().keySet().toArray();
+        Iterator iter = getComponentManagers().values().iterator();
 
-        for ( int i = 0; i < components.length; i++ )
+        while ( iter.hasNext() )
         {
-            release( components[ i ] );
+            try
+            {
+                ( (ComponentManager) iter.next() ).dispose();
+            }
+            catch ( Exception e )
+            {
+                getLogger().error(
+                    "Error while disposing component manager. Continuing with the rest",
+                    e );
+            }
         }
+
+        componentManagers.clear();
+        getLogger().info( "...ComponentRepository disposed" );
     }
 
     // ----------------------------------------------------------------------
     // Lifecycle Handling
     // ----------------------------------------------------------------------
 
-    protected LifecycleHandler getLifecycleHandler( String role )
+    public LifecycleHandler getLifecycleHandler( String id )
         throws UndefinedLifecycleHandlerException
     {
-        return getPlexusContainer().getLifecycleHandler();
+        LifecycleHandlerHousing h = null;
+        if ( id != null )
+        {
+            h = (LifecycleHandlerHousing) lifecycleHandlers.get( id );
+        }
+        if ( h == null )
+        {
+            throw new UndefinedLifecycleHandlerException(
+                "No LifecycleHandler defined for id: " + id );
+        }
+        return h.getHandler();
     }
 
+    /**
+     * @return
+     */
+    protected Configuration getConfiguration()
+    {
+        return configuration;
+    }
 
-    // I have made the lifecycle handlers public because the instance manager is now responsible for running
-    // a component it deals with through its lifecyle. I was running the component through its lifecycle
-    // in this class but that is not appropriate as we want the instanace manager to control the
-    // component. These are public for now but we need a little restructuring.
+    /**
+     * @return
+     */
+    protected Configuration getDefaultConfiguration()
+    {
+        return defaultConfiguration;
+    }
 
-    /** Start a component's lifecycle.
-     *
+    /**
+     * @see org.apache.plexus.service.repository.ComponentRepository#contextualize(org.apache.avalon.framework.context.Context)
      */
-    public void startComponentLifecycle( ComponentHousing housing )
+    public void contextualize( Context context )
     {
-        try
-        {
-            LifecycleHandler lh = getLifecycleHandler( housing.getComponentManager().getComponentDescriptor().getRole() );
-            lh.startLifecycle( housing );
-        }
-        catch ( Exception e )
-        {
-            getLogger().error( "Cannot start component lifecycle with role : "
-                               + housing.getComponentManager().getComponentDescriptor().getRole(), e );
-        }
+        this.context = context;
     }
 
-    /** End a component's lifecycle.
-     *
+    /**
+     * @see org.apache.plexus.service.repository.ComponentRepository#getDefaultLifecycleHandler()
      */
-    public void endComponentLifecycle( ComponentHousing housing )
+    public LifecycleHandler getDefaultLifecycleHandler()
     {
-        try
-        {
-            LifecycleHandler lh = getLifecycleHandler( housing.getComponentManager().getComponentDescriptor().getRole() );
-            lh.endLifecycle( housing );
-        }
-        catch ( Exception e )
-        {
-            getLogger().error( "Cannot start component lifecycle with role : "
-                               + housing.getComponentManager().getComponentDescriptor().getRole(), e );
-        }
+        return defaultLifecycleHandler;
+    }
+
+    /**
+     * @return
+     */
+    Context getContext()
+    {
+        return context;
     }
+
+    /**
+     * @return
+     */
+    public LoggerManager getComponnetLogManager()
+    {
+        return loggerManager;
+    }
+
+    /**
+     * @param manager
+     */
+    public void setComponentLogManager( LoggerManager manager )
+    {
+        loggerManager = manager;
+    }
+
 }