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;
+ }
+
}