CVS: plexus-container/src/java/org/apache/plexus/service/repository/instance AbstractInstanceManager.java,1.2,1.3 InstanceManager.java,1.1,1.2 PerLookupInstanceManager.java,1.1,1.2 PoolableInstanceManager.java,1.1,1.2

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/instance
In directory hogshead.codehaus.org:/tmp/cvs-serv25662/src/java/org/apache/plexus/service/repository/instance

Modified Files:
	AbstractInstanceManager.java InstanceManager.java 
	PerLookupInstanceManager.java PoolableInstanceManager.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: AbstractInstanceManager.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/instance/AbstractInstanceManager.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- AbstractInstanceManager.java	12 May 2003 18:57:28 -0000	1.2
+++ AbstractInstanceManager.java	5 Aug 2003 19:26:24 -0000	1.3
@@ -2,38 +2,68 @@
 
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.plexus.lifecycle.LifecycleHandler;
 import org.apache.plexus.service.repository.ComponentHousing;
 import org.apache.plexus.service.repository.ComponentManager;
 
 /**
- *
+ * Base InstanceManager
  *
  * @author <a href="mailto:[email protected]">Jason van Zyl</a>
  *
  * @version $Id$
  */
-public abstract class
-    AbstractInstanceManager
-    implements InstanceManager
+public abstract class AbstractInstanceManager implements InstanceManager
 {
+    /** ClassLoader used to load the component */
     private ClassLoader classLoader;
 
+    /** Component configuration */
     private Configuration configuration;
 
+    /** Component implementation */
     private String implementation;
 
+    /** ComponantManager which handles the component */
     private ComponentManager componentManager;
 
+    /** Lifecycle handler for this component type */
+    private LifecycleHandler lifecycleHandler;
+
+    private Logger logger;
+    /**
+     * 
+     */
+    public AbstractInstanceManager()
+    {
+        super();
+       
+    }
+
+    /**
+     * This currently does nothing. Subclasses should still call this if they override this method
+     * as it may doing something useful in future.
+     * 
+    	* @see org.apache.plexus.service.repository.instance.InstanceManager#initialize()
+    	*/
+    public void initialize() 
+    	throws Exception
+    {
+
+    }
     // ----------------------------------------------------------------------
     // Lifecylce Management
     // ----------------------------------------------------------------------
 
-    public void configure( Configuration configuration )
-        throws ConfigurationException
+    /**
+     * make sure to call this if overriding
+     */
+    public void configure(Configuration configuration) 
+    	throws ConfigurationException
     {
         this.configuration = configuration;
-
-        implementation = configuration.getChild( "implementation" ).getValue();
+        implementation = configuration.getChild("implementation").getValue();
     }
 
     // ----------------------------------------------------------------------
@@ -45,7 +75,7 @@
         return configuration;
     }
 
-    public void setConfiguration( Configuration configuration )
+    public void setConfiguration(Configuration configuration)
     {
         this.configuration = configuration;
     }
@@ -55,7 +85,15 @@
         return implementation;
     }
 
-    public void setImplementation( String implementation )
+    /**
+    	* @see org.apache.plexus.service.repository.instance.InstanceManager#setLifecycleHandler(org.apache.plexus.lifecycle.LifecycleHandler)
+    	*/
+    public void setLifecycleHandler(LifecycleHandler handler)
+    {
+        this.lifecycleHandler = handler;
+    }
+
+    public void setComponentImplementation(String implementation)
     {
         this.implementation = implementation;
     }
@@ -65,7 +103,7 @@
         return classLoader;
     }
 
-    public void setClassLoader( ClassLoader classLoader )
+    public void setClassLoader(ClassLoader classLoader)
     {
         this.classLoader = classLoader;
     }
@@ -75,27 +113,84 @@
         return componentManager;
     }
 
-    public void setComponentManager( ComponentManager componentManager )
+    public void setComponentManager(ComponentManager componentManager)
     {
         this.componentManager = componentManager;
     }
 
+    protected LifecycleHandler getLifecycleHandler()
+    {
+        return lifecycleHandler;
+    }
+
+	/**
+	 * @return
+	 */
+	protected Logger getLogger()
+	{
+		return logger;
+	}
+
+	/**
+	 * @see org.apache.plexus.service.repository.instance.InstanceManager#enableLogging(org.apache.avalon.framework.logger.Logger)
+	 */
+	public void enableLogging(Logger logger)
+	{
+		this.logger = logger;
+	}
+
     // ----------------------------------------------------------------------
     // Implementation
     // ----------------------------------------------------------------------
 
-    protected ComponentHousing createInstance()
-        throws Exception
-    {
-        ComponentHousing housing = new  ComponentHousing();
-
-        housing.setComponent( getClassLoader().loadClass( getImplementation() ).newInstance() );
-        housing.setComponentManager( getComponentManager() );
-
-        getComponentManager().getComponentRespository().startComponentLifecycle( housing );
+	protected void startComponentLifecycle(ComponentHousing housing)
+	{
+			try
+			{
+				getLifecycleHandler().endLifecycle(housing);
+			}
+			catch (Exception e)
+			{
+				getLogger().error(
+					"Cannot start component lifecycle with role : "
+						+ getComponentManager().getComponentDescriptor().getRole(),
+					e);
+			}
+		}
 
+		/** End a component's lifecycle.
+		 *
+		 */
+		protected void endComponentLifecycle(ComponentHousing housing)
+		{
+			try
+			{
+				getLifecycleHandler().endLifecycle(housing);
+			}
+			catch (Exception e)
+			{
+				getLogger().error(
+					"Cannot start component lifecycle with role : "
+						+ getComponentManager().getComponentDescriptor().getRole(),
+					e);
+			}
+		}
+		
+    /**
+     * Create a new Component  instance,and start it's lifecycle
+     */
+    protected ComponentHousing newHousingInstance() 
+    	throws Exception
+    {
+        ComponentHousing housing = new ComponentHousing();
+		housing.setComponentManager(getComponentManager());
+        housing.setComponent(getClassLoader().loadClass(getImplementation()).newInstance());
+        getLifecycleHandler().startLifecycle(housing);
         return housing;
     }
+
+    public abstract void release(Object component);
+
 
 
 }

Index: InstanceManager.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/instance/InstanceManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- InstanceManager.java	1 May 2003 19:35:36 -0000	1.1
+++ InstanceManager.java	5 Aug 2003 19:26:24 -0000	1.2
@@ -1,12 +1,17 @@
 package org.apache.plexus.service.repository.instance;
 
+
 import org.apache.avalon.framework.configuration.Configuration;
 import org.apache.avalon.framework.configuration.ConfigurationException;
-import org.apache.plexus.service.repository.ComponentHousing;
+import org.apache.avalon.framework.logger.Logger;
+import org.apache.plexus.lifecycle.LifecycleHandler;
 import org.apache.plexus.service.repository.ComponentManager;
 
 /**
- *
+ * Manages a component instance. 
+ * Determines when a component is shutdown, and when it's started up. Each
+ * instance deals with only one component class, though may handle multiple 
+ * instances of this class.
  *
  * @author <a href="mailto:[email protected]">Jason van Zyl</a>
  *
@@ -16,9 +21,9 @@
 {
     static String ROLE = InstanceManager.class.getName();
 
-    ComponentHousing getInstance()
+  /* ComponentHousing newHousingInstance()
         throws Exception;
-
+*/
     void configure( Configuration configuration )
         throws ConfigurationException;
 
@@ -27,7 +32,40 @@
 
     void setClassLoader( ClassLoader classLoader );
 
-    void setImplementation( String implementation );
+    void setComponentImplementation( String implementation );
 
     void setComponentManager( ComponentManager manager );
-}
+    
+    int getConnections();
+    /**
+     * Set the lifecycle handler to use. This is determined by the component.
+     */
+    void setLifecycleHandler(LifecycleHandler handler);
+    /**
+     * Dispose this manager. Instance manager should take any components it holds
+     * through their shutdown lifecycle.
+     *
+     */
+    void dispose();
+    /**
+     * Release the component back to this manager. The manager may decide to
+     * end the components lifecycle, put it back in a pool, or just keep it alive. It can
+     * be safely assumed the component is never null.
+     * 
+     * @param component
+     */
+    void release(Object component);
+    
+    /**
+     * Set this managers logger
+     * 
+     * @param logger
+     */
+    void enableLogging(Logger logger);
+    /**
+     * Retrieve a component instance
+     * 
+     * @return
+     */
+    Object getComponent() throws Exception;
+}
\ No newline at end of file

Index: PerLookupInstanceManager.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/instance/PerLookupInstanceManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- PerLookupInstanceManager.java	1 May 2003 19:35:36 -0000	1.1
+++ PerLookupInstanceManager.java	5 Aug 2003 19:26:24 -0000	1.2
@@ -3,23 +3,64 @@
 import org.apache.plexus.service.repository.ComponentHousing;
 
 /**
- *
+ * Creates a new component instance for every lookup
  * 
  * @author <a href="mailto:[email protected]">Jason van Zyl</a>
  *
  * @version $Id$
  */
-public class PerLookupInstanceManager
-    extends AbstractInstanceManager
+public class PerLookupInstanceManager extends AbstractMultipleInstanceManager
 {
-    public void initialize()
-        throws Exception
+    private int connections = 0;
+    /**
+     * 
+     */
+    public PerLookupInstanceManager()
     {
+        super();
     }
 
-    public ComponentHousing getInstance()
-        throws Exception
+    public void dispose()
     {
-        return createInstance();
+        //nothing todo as component has lifecycle
+        //ended on release
     }
+    
+    /**
+     * Return the current number of components this manager has given out
+     * which have not yet been returned.
+     * 
+     * @return
+     */
+    public int getConnections()
+    {
+    	return connections;
+    }    
+
+    /* (non-Javadoc)
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#getComponent()
+     */
+    public Object getComponent() throws Exception
+    {
+        ComponentHousing h = newHousingInstance();
+        putHousing(h.getComponent(), h);
+        connections++;
+        return h.getComponent();
+    }
+
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#release(java.lang.Object)
+     */
+    public void release(Object component)
+    {
+        ComponentHousing h =removeHousing(component);
+        if (h != null)
+        {
+        	connections--;
+            endComponentLifecycle( h );	
+        }
+    }
+
+   
+
 }

Index: PoolableInstanceManager.java
===================================================================
RCS file: /cvsroot/plexus/plexus-container/src/java/org/apache/plexus/service/repository/instance/PoolableInstanceManager.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- PoolableInstanceManager.java	1 May 2003 19:35:36 -0000	1.1
+++ PoolableInstanceManager.java	5 Aug 2003 19:26:24 -0000	1.2
@@ -1,35 +1,165 @@
 package org.apache.plexus.service.repository.instance;
 
+import org.apache.avalon.framework.configuration.Configuration;
+import org.apache.avalon.framework.configuration.ConfigurationException;
+import org.apache.plexus.configuration.DefaultConfiguration;
 import org.apache.plexus.service.repository.ComponentHousing;
+import org.apache.plexus.util.SweeperPool;
 
 /**
- *
+ * Pools comnponents
  *
  * @author <a href="mailto:[email protected]">Jason van Zyl</a>
  *
  * @version $Id$
  */
-public class PoolableInstanceManager
-    extends AbstractInstanceManager
+public class PoolableInstanceManager extends AbstractMultipleInstanceManager
 {
-    private SimplePool pool;
+    private SweeperPool pool;
 
-    private int size = 6;
+	private int connections = 0;
+	
+    /**
+     * 
+     */
+    public PoolableInstanceManager()
+    {
+        super();
+    }
 
-    public void initialize()
-        throws Exception
+    public void initialize() throws Exception
     {
-        pool = new SimplePool( size );
+        pool = newSeeperPool(getConfiguration(), null);
+    }
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#configure(org.apache.avalon.framework.configuration.Configuration)
+     */
+    public void configure(Configuration configuration) throws ConfigurationException
+    {
+        super.configure(configuration);
+    }
 
-        for ( int i = 0; i < size; i++ )
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#release(java.lang.Object)
+     */
+    public void release(Object component)
+    {
+    	ComponentHousing housing = removeHousing( component);
+    	if( housing == null )
+    	{
+    		getLogger().warn("Component attempted to be returned to pool, but this object does no appear to be from this pool. Component class=" + component.getClass());
+    		return;
+    	}
+        pool.put( housing );
+		connections --;
+    }
+
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#dispose()
+     */
+    public void dispose()
+    {
+        //@todo really need to wait for all components to be returned.
+        //however blocking on this call may prevent plexus servicing
+        //other requests and hence prevent cleanup. Have to look
+        //at this. For now just assume all connections have been
+        //released.
+        pool.dispose();
+        
+    }
+
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#getComponent()
+     */
+    public Object getComponent() throws Exception
+    {
+        ComponentHousing housing = (ComponentHousing)pool.get();
+        if( housing == null)
         {
-            pool.put( createInstance() );
+        	housing = newHousingInstance();
         }
+        putHousing(housing.getComponent(), housing);
+        connections ++;
+        return housing.getComponent();
     }
 
-    public ComponentHousing getInstance()
-        throws Exception
+    /**
+     * @see org.apache.plexus.service.repository.instance.InstanceManager#getConnections()
+     */
+    public int getConnections()
     {
-        return (ComponentHousing) pool.get();
+        return connections;
+    }
+
+    /**
+      * Create a new ObjectPool based on the provided configurations. Default
+      * hardcoded values are used if neither configurations have a value
+      * for a particular setting.
+      * 
+      * 
+      * @param config the custom configuration for the pool
+      * @param defaultConfig the configuration used to fill out any gaps in
+      * the custom configuration. 
+      * @return a new ObjectPool
+      * @throws ConfigurationException
+      */
+    private SweeperPool newSeeperPool(Configuration config, Configuration defaultConfig)
+        throws ConfigurationException
+    {
+    	if( config==null)
+    		config = new DefaultConfiguration("");
+        if (defaultConfig == null)
+            defaultConfig = new DefaultConfiguration("");
+        int sweepInterval =
+            config.getChild("sweep-interval").getValueAsInteger(
+                defaultConfig.getChild("sweep-interval").getValueAsInteger(5));
+        int minCapacity =
+            config.getChild("min-capacity").getValueAsInteger(
+                defaultConfig.getChild("min-capacity").getValueAsInteger(3));
+        int maxCapacity =
+            config.getChild("max-capacity").getValueAsInteger(
+                defaultConfig.getChild("max-capacity").getValueAsInteger(30));
+        int triggerSize =
+            config.getChild("trigger-size").getValueAsInteger(
+                defaultConfig.getChild("trigger-size").getValueAsInteger(15));
+        int initialCapacity =
+            config.getChild("initial-capacity").getValueAsInteger(
+                defaultConfig.getChild("initial-capacity").getValueAsInteger(10));
+        return new SweeperPool(
+            maxCapacity,
+            minCapacity,
+            initialCapacity,
+            sweepInterval,
+            triggerSize);
+    }
+
+    class ComponentPool extends SweeperPool
+    {
+
+        /**
+         * @param maxSize
+         * @param minSize
+         * @param intialCapacity
+         * @param sweepInterval
+         * @param triggerSize
+         */
+        public ComponentPool(
+            int maxSize,
+            int minSize,
+            int intialCapacity,
+            int sweepInterval,
+            int triggerSize)
+        {
+            super(maxSize, minSize, intialCapacity, sweepInterval, triggerSize);
+        }
+
+        /**
+         * @see org.apache.plexus.util.SweeperPool#objectDisposed(java.lang.Object)
+         */
+        public void objectDisposed(Object obj)
+        {
+               endComponentLifecycle((ComponentHousing) obj);
+        }
+
     }
 }