bloritsch 02/01/29 08:18:53
Modified: src/scratchpad/org/apache/avalon/excalibur/system
AbstractContainer.java
src/scratchpad/org/apache/avalon/excalibur/system/handler
ComponentHandler.java FactoryComponentHandler.java
PerThreadComponentHandler.java
PoolableComponentHandler.java
ThreadSafeComponentHandler.java
Log:
add asynchronous start/stop and skeleton of compnent manaagement
Revision Changes Path
1.2 +270 -14
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/AbstractContainer.java
Index: AbstractContainer.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/AbstractContainer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AbstractContainer.java 25 Jan 2002 20:15:11 -0000 1.1
+++ AbstractContainer.java 29 Jan 2002 16:18:53 -0000 1.2
@@ -7,32 +7,33 @@
*/
package org.apache.avalon.excalibur.system;
-import org.apache.avalon.framework.activity.Initializable;
-import org.apache.avalon.framework.activity.Disposable;
-import org.apache.avalon.framework.component.ComponentException;
-import org.apache.avalon.framework.component.ComponentManager;
-import org.apache.avalon.framework.component.Composable;
-import org.apache.avalon.framework.configuration.Configurable;
-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.context.ContextException;
-import org.apache.avalon.framework.context.Contextualizable;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.logger.Logger;
+import org.apache.avalon.framework.activity.*;
+import org.apache.avalon.framework.component.*;
+import org.apache.avalon.framework.configuration.*;
+import org.apache.avalon.framework.context.*;
+import org.apache.avalon.framework.logger.*;
+import org.apache.avalon.excalibur.command.*;
+import org.apache.avalon.excalibur.system.handler.*;
import org.apache.avalon.excalibur.logger.LoggerManager;
import org.apache.avalon.excalibur.event.Queue;
import org.apache.avalon.excalibur.pool.PoolManager;
import org.apache.avalon.excalibur.util.ComponentStateValidator;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
/**
* The Container is an interface used to mark the Containers in your system.
It
* exposes a protected getComponentManager() method so that the Container's
* Manager can expose that to the instantiating class.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/01/25 20:15:11 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/01/29 16:18:53 $
*/
public abstract class AbstractContainer
extends AbstractLogEnabled
@@ -49,6 +50,8 @@
private ClassLoader m_classLoader;
private RoleManager m_roleManager;
private Configuration m_configuration;
+ private List m_components;
+ private Map m_configs;
/**
* Wrap this so that ComponentStateValidator functions properly.
@@ -132,6 +135,16 @@
throws Exception
{
m_validator.checkInitialized();
+
+ Iterator i = m_components.iterator();
+
+ while ( i.hasNext() )
+ {
+ m_commandQueue.enqueue(
+ new InitComponentHandlerCommand( (ComponentHandler) i.next(),
+ getLogger() )
+ );
+ }
}
/**
@@ -140,6 +153,249 @@
public void dispose()
{
m_validator.checkDisposed();
+
+ Iterator i = m_components.iterator();
+
+ while ( i.hasNext() )
+ {
+ try
+ {
+ m_commandQueue.enqueue(
+ new DisposeComponentHandlerCommand( (ComponentHandler)
i.next(),
+ getLogger() )
+ );
+
+ i.remove();
+ }
+ catch ( Exception e )
+ {
+ if ( getLogger().isWarnEnabled() )
+ {
+ getLogger().warn( "Could not dispose component", e );
+ }
+ }
+ }
+ }
+
+ /**
+ * This is the Default ComponentManager for the Container. It provides
+ * a very simple abstraction, and makes it easy for the Container to
manage
+ * the references.
+ */
+ private final static class ContainerComponentManager
+ implements ComponentManager
+ {
+ private final Map m_components;
+ private final Map m_used;
+ private final ComponentManager m_parent;
+
+ protected ContainerComponentManager( Map componentMap )
+ {
+ this( componentMap, null );
+ }
+
+ protected ContainerComponentManager( Map componentMap,
ComponentManager parent )
+ {
+ m_parent = null;
+ m_components = componentMap;
+ m_used = new HashMap( m_components.size() );
+ }
+
+ public Component lookup( String role )
+ throws ComponentException
+ {
+ ComponentHandler handler = (ComponentHandler) m_components.get(
role );
+
+ if ( null == handler )
+ {
+ if ( null != m_parent )
+ {
+ return m_parent.lookup( role );
+ }
+ else
+ {
+ throw new ComponentException( "The role does not exist
in the ComponentManager" );
+ }
+ }
+
+ final Component component;
+
+ try
+ {
+ if ( ! handler.isInitialized() )
+ {
+ handler.initialize();
+ }
+
+ component = handler.get();
+ }
+ catch ( Exception e )
+ {
+ throw new ComponentException( "Could not return a reference
to the Component", e );
+ }
+
+ synchronized ( m_used )
+ {
+ m_used.put( component, handler );
+ }
+
+ return component;
+ }
+
+ public boolean hasComponent( String role )
+ {
+ final boolean hasComponent = m_components.containsKey( role );
+
+ if ( ! hasComponent && null != m_parent )
+ {
+ return m_parent.hasComponent( role );
+ }
+
+ return hasComponent;
+ }
+
+ public void release( Component component )
+ {
+ final ComponentHandler handler;
+
+ synchronized ( m_used )
+ {
+ handler = (ComponentHandler) m_used.remove( component );
+ }
+
+ if ( null == handler && null != m_parent )
+ {
+ m_parent.release( component );
+ return;
+ }
+
+ handler.put( component );
+ }
+ }
+
+ /**
+ * This is the Default ComponentSelector for the Container. It provides
+ * a very simple abstraction, and makes it easy for the Container to
manage
+ * the references.
+ */
+ private final static class ContainerComponentSelector
+ implements ComponentSelector
+ {
+ private final Map m_components;
+ private final Map m_used;
+
+ protected ContainerComponentSelector( Map componentMap )
+ {
+ m_components = componentMap;
+ m_used = new HashMap( m_components.size() );
+ }
+
+ public Component select( Object hint )
+ throws ComponentException
+ {
+ ComponentHandler handler = (ComponentHandler) m_components.get(
hint );
+
+ if ( null == handler )
+ {
+ throw new ComponentException( "The role does not exist in
the ComponentSelector" );
+ }
+
+ final Component component;
+
+ try
+ {
+ if ( ! handler.isInitialized() )
+ {
+ handler.initialize();
+ }
+
+ component = handler.get();
+ }
+ catch ( Exception e )
+ {
+ throw new ComponentException( "Could not return a reference
to the Component", e );
+ }
+
+ synchronized ( m_used )
+ {
+ m_used.put( component, handler );
+ }
+
+ return component;
+ }
+
+ public boolean hasComponent( Object hint )
+ {
+ return m_components.containsKey( hint );
+ }
+
+ public void release( Component component )
+ {
+ final ComponentHandler handler;
+
+ synchronized ( m_used )
+ {
+ handler = (ComponentHandler) m_used.remove( component );
+ }
+
+ handler.put( component );
+ }
+ }
+
+ /**
+ * This is the command class to initialize a ComponentHandler
+ */
+ private final static class InitComponentHandlerCommand implements Command
+ {
+ private final ComponentHandler m_handler;
+ private final Logger m_logger;
+
+ protected InitComponentHandlerCommand( ComponentHandler handler,
Logger logger )
+ {
+ m_handler = handler;
+ m_logger = logger;
+ }
+
+ public void execute()
+ throws Exception
+ {
+ try
+ {
+ if ( ! m_handler.isInitialized() )
+ {
+ m_handler.initialize();
+ }
+ }
+ catch ( Exception e )
+ {
+ if ( m_logger.isErrorEnabled() )
+ {
+ m_logger.error( "Could not initialize ComponentHandler",
e );
+ }
+
+ throw e;
+ }
+ }
+ }
+
+ /**
+ * This is the command class to dispose a ComponentHandler
+ */
+ private final static class DisposeComponentHandlerCommand implements
Command
+ {
+ private final ComponentHandler m_handler;
+ private final Logger m_logger;
+
+ protected DisposeComponentHandlerCommand( ComponentHandler handler,
Logger logger )
+ {
+ m_handler = handler;
+ m_logger = logger;
+ }
+
+ public void execute()
+ {
+ m_handler.dispose();
+ }
}
}
1.3 +20 -1
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/ComponentHandler.java
Index: ComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/ComponentHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ComponentHandler.java 28 Jan 2002 20:54:01 -0000 1.2
+++ ComponentHandler.java 29 Jan 2002 16:18:53 -0000 1.3
@@ -7,6 +7,8 @@
*/
package org.apache.avalon.excalibur.system.handler;
+import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
/**
@@ -14,11 +16,28 @@
* The desire for a ComponentHandler is to manage the instances of a
Component.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/28 20:54:01 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/29 16:18:53 $
* @since 4.0
*/
public interface ComponentHandler
+ extends Initializable, Disposable
{
+ /**
+ * Sometimes Components call other components during their initialization
+ * process. This is a quick test that the ComponentManager will perform
+ * before attempting to use the the ComponentHandler.
+ */
+ boolean isInitialized();
+
+ /**
+ * Gets the current reference to a Component according to the policy of
the
+ * implementation.
+ */
Component get() throws Exception;
+
+ /**
+ * Puts the reference back in the ComponentHandler according to the
policy
+ * of the implementation.
+ */
void put(Component component);
}
1.2 +11 -4
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/FactoryComponentHandler.java
Index: FactoryComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/FactoryComponentHandler.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FactoryComponentHandler.java 28 Jan 2002 20:54:01 -0000 1.1
+++ FactoryComponentHandler.java 29 Jan 2002 16:18:53 -0000 1.2
@@ -7,6 +7,7 @@
*/
package org.apache.avalon.excalibur.system.handler;
+import org.apache.avalon.excalibur.system.Container;
import org.apache.avalon.excalibur.system.RoleManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
@@ -22,7 +23,7 @@
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.1 $ $Date: 2002/01/28 20:54:01 $
+ * @version CVS $Revision: 1.2 $ $Date: 2002/01/29 16:18:53 $
* @since 4.0
*/
class DefaultComponentHandler
@@ -48,13 +49,19 @@
protected DefaultComponentHandler( final Class componentClass,
final Configuration config,
final ComponentManager manager,
- final Context context,
- final RoleManager roles,
- final LoggerManager logkit )
+ final Context context )
throws Exception
{
+ RoleManager roles = (RoleManager) context.get(
Container.ROLE_MANAGER );
+ LoggerManager logkit = (LoggerManager) context.get(
Container.LOGGER_MANAGER );
+
m_factory = new ComponentFactory( componentClass, config, manager,
context, roles, logkit );
m_logger = logkit.getLoggerForCategory("system.handler.factory");
+ }
+
+ public boolean isInitialized()
+ {
+ return m_initialized;
}
/**
1.3 +11 -4
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/PerThreadComponentHandler.java
Index: PerThreadComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/PerThreadComponentHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PerThreadComponentHandler.java 28 Jan 2002 21:09:25 -0000 1.2
+++ PerThreadComponentHandler.java 29 Jan 2002 16:18:53 -0000 1.3
@@ -7,6 +7,7 @@
*/
package org.apache.avalon.excalibur.system.handler;
+import org.apache.avalon.excalibur.system.Container;
import org.apache.avalon.excalibur.system.RoleManager;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Disposable;
@@ -22,7 +23,7 @@
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/28 21:09:25 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/29 16:18:53 $
* @since 4.0
*/
public class PerThreadComponentHandler implements ComponentHandler {
@@ -40,14 +41,20 @@
protected PerThreadComponentHandler ( final Class componentClass,
final Configuration config,
final ComponentManager manager,
- final Context context,
- final RoleManager roles,
- final LoggerManager logkit )
+ final Context context )
throws Exception
{
+ RoleManager roles = (RoleManager) context.get(
Container.ROLE_MANAGER );
+ LoggerManager logkit = (LoggerManager) context.get(
Container.LOGGER_MANAGER );
+
m_factory = new ComponentFactory( componentClass, config, manager,
context, roles, logkit );
m_instance = new ThreadLocalComponent( m_factory );
m_logger = logkit.getLoggerForCategory("system.handler.perthread");
+ }
+
+ public boolean isInitialized()
+ {
+ return m_initialized;
}
/**
1.3 +11 -5
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/PoolableComponentHandler.java
Index: PoolableComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/PoolableComponentHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- PoolableComponentHandler.java 28 Jan 2002 20:54:01 -0000 1.2
+++ PoolableComponentHandler.java 29 Jan 2002 16:18:53 -0000 1.3
@@ -7,6 +7,7 @@
*/
package org.apache.avalon.excalibur.system.handler;
+import org.apache.avalon.excalibur.system.Container;
import org.apache.avalon.excalibur.system.RoleManager;
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.component.Component;
@@ -25,7 +26,7 @@
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/28 20:54:01 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/29 16:18:53 $
* @since 4.0
*/
public class PoolableComponentHandler implements ComponentHandler {
@@ -53,17 +54,22 @@
protected PoolableComponentHandler( final Class componentClass,
final Configuration config,
final ComponentManager manager,
- final Context context,
- final RoleManager roles,
- final LoggerManager logkit,
- final PoolManager poolManager )
+ final Context context )
throws Exception
{
+ RoleManager roles = (RoleManager) context.get(
Container.ROLE_MANAGER );
+ LoggerManager logkit = (LoggerManager) context.get(
Container.LOGGER_MANAGER );
m_factory =
new ComponentFactory( componentClass, config, manager, context,
roles, logkit );
+ PoolManager poolManager = (PoolManager) context.get(
Container.POOL_MANAGER );
m_pool = poolManager.getManagedPool( m_factory,
config.getAttributeAsInteger( "pool-min", 4 ) );
m_logger = logkit.getLoggerForCategory("system.handler.poolable");
+ }
+
+ public boolean isInitialized()
+ {
+ return m_initialized;
}
/**
1.3 +11 -4
jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/ThreadSafeComponentHandler.java
Index: ThreadSafeComponentHandler.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/src/scratchpad/org/apache/avalon/excalibur/system/handler/ThreadSafeComponentHandler.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ThreadSafeComponentHandler.java 28 Jan 2002 20:54:01 -0000 1.2
+++ ThreadSafeComponentHandler.java 29 Jan 2002 16:18:53 -0000 1.3
@@ -7,6 +7,7 @@
*/
package org.apache.avalon.excalibur.system.handler;
+import org.apache.avalon.excalibur.system.Container;
import org.apache.avalon.excalibur.system.RoleManager;
import org.apache.avalon.framework.activity.Startable;
import org.apache.avalon.framework.activity.Disposable;
@@ -22,7 +23,7 @@
* and destroyed correctly.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Berin Loritsch</a>
- * @version CVS $Revision: 1.2 $ $Date: 2002/01/28 20:54:01 $
+ * @version CVS $Revision: 1.3 $ $Date: 2002/01/29 16:18:53 $
* @since 4.0
*/
public class ThreadSafeComponentHandler implements ComponentHandler {
@@ -40,13 +41,19 @@
protected ThreadSafeComponentHandler( final Class componentClass,
final Configuration config,
final ComponentManager manager,
- final Context context,
- final RoleManager roles,
- final LoggerManager logkit )
+ final Context context )
throws Exception
{
+ RoleManager roles = (RoleManager) context.get(
Container.ROLE_MANAGER );
+ LoggerManager logkit = (LoggerManager) context.get(
Container.LOGGER_MANAGER );
+
m_factory = new ComponentFactory( componentClass, config, manager,
context, roles, logkit );
m_logger = logkit.getLoggerForCategory("system.handler.threadsafe");
+ }
+
+ public boolean isInitialized()
+ {
+ return m_initialized;
}
/**
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>