mcconnell 2002/08/31 07:50:11
Modified: assembly/src/java/org/apache/excalibur/merlin/container
DefaultContainer.java
Log:
Updated to seperate out all thread management to a seperate handler that
mediates access to the container. DefaultContainer implementation is now
signoficantly simplified and the thread establishment and coordination logic
is now included in the class ContainerReference.
Revision Changes Path
1.37 +137 -401
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java
Index: DefaultContainer.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/DefaultContainer.java,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- DefaultContainer.java 28 Aug 2002 16:22:50 -0000 1.36
+++ DefaultContainer.java 31 Aug 2002 14:50:11 -0000 1.37
@@ -36,6 +36,7 @@
import org.apache.excalibur.merlin.model.Profile;
import org.apache.excalibur.merlin.model.Resource;
import org.apache.excalibur.merlin.model.builder.XMLContainerCreator;
+import org.apache.excalibur.merlin.container.ContainerResource;
/**
* Default container implementation that manages a registry of componet providers
and
@@ -48,7 +49,7 @@
*/
public class DefaultContainer extends AbstractLogEnabled implements Container,
Contextualizable, Configurable, Structural, Initializable, Startable,
Suspendable,
- Disposable, Runnable, StateListener
+ Disposable, StateListener
{
//=======================================================================
// static
@@ -94,13 +95,13 @@
* be equal to the m_action value and once achieved goes off for a little
* sleep.
*/
- private Integer m_action = new Integer( UNKNOWN );
+ private Integer m_action = new Integer( StateEvent.UNKNOWN );
/**
* The container is managed as a thread under which the current state
* is recorded in the m_state state member.
*/
- private int m_state = UNKNOWN;
+ private int m_state = StateEvent.UNKNOWN;
/**
* The set of state listeners listening to this container.
@@ -113,13 +114,6 @@
private ArrayList m_containerListeners = new ArrayList();
/**
- * The thread that this container will run within - established during
initialization
- * following which the container manager is associated as the container's
context
- * classloader.
- */
- private Thread m_thread;
-
- /**
* The thread group holding the threads of the subsidiary containers.
*/
private ThreadGroup m_threadGroup;
@@ -151,10 +145,6 @@
* {@link Map} (REQUIRED}</li>
* <li>{@link #LOGGING_KEY} the logging manager
* {@link DefaultLoggerManager} (REQUIRED}</li>
- * <li>{@link #STATE_LISTENER_KEY} a container state listener
- * {@link StateListener} (OPTIONAL}</li>
- * <li>{@link #CONTAINER_LISTENER_KEY} a container container listener
- * {@link ContainerListener} (OPTIONAL}</li>
* </ul>
* @param context the service context value
* @exception ContextException if a contextualization error occurs
@@ -166,25 +156,15 @@
m_logging = (DefaultLoggerManager) context.get( LOGGING_KEY );
m_services = (Map) context.get( SERVICES_KEY );
- try
- {
- StateListener listener = (StateListener) context.get(
STATE_LISTENER_KEY );
- addStateListener( listener );
- }
- catch( ContextException e )
- {
- // optional
- }
+ //
+ // set the context classloader
+ //
- try
- {
- ContainerListener listener = (ContainerListener) context.get(
CONTAINER_LISTENER_KEY );
- addContainerListener( listener );
- }
- catch( ContextException e )
- {
- // optional
- }
+ Thread.currentThread().setContextClassLoader( m_manager );
+ getLogger().debug( "container '" + m_descriptor.getName()
+ + "' executing in thread: '" + Thread.currentThread().getName()
+ + "' with context type manager: '" +
Thread.currentThread().getContextClassLoader()
+ + "'.");
m_factory = new ContainerFactory( m_manager, m_logging );
}
@@ -247,116 +227,24 @@
//=======================================================================
/**
- * Initalization of a <code>Container</code>. The implementation launches
- * a new thread of execution that handles the primary initalization actions
- * during which all declared component {@link Profile}
- * and subsidiary {@link ContainerDescriptor} instances are added to the
- * container model. Component profiles are assembled using the
- * container {@link ContainerManager}, followed by the creation and
- * initialization of the subsidiary containers.
+ * Initalization of the <code>Container</code>.
*
- * @exception Exception never throw but declared in order for specilized
- * containers to manage local exceptions. If a container initialization
- * occurs it will raise a ContainerRuntimeException under the thread
- * that is running this container.
+ * @exception IllegalStateException if the container has not been contextualized
or assembled
+ * @exception Exception if an error occurs during the initialization phase
*/
public void initialize() throws Exception
{
- if( m_map == null )
- {
- final String error =
- "Container has not been assembled.";
- throw new IllegalStateException( error );
- }
-
- synchronized( this )
- {
- getLogger().debug("initialization");
- m_thread = new Thread( (Runnable) this );
- m_thread.start();
- while(( m_state < INITIALIZED ) && ( m_error == null ))
- {
- sleep();
- }
- if( m_error != null )
- {
- throw new ContainerException("Initialization failure.", m_error );
- }
- }
- getLogger().debug("initialization complete");
- }
-
- /**
- * Invoked by the parent to initiate the thread after which the thread will
- * monitor action requests arrising from initialize, startup, shutdown and
dispose
- * requests.
- * @exception IllegalStateException if the container has not been contextualized
- */
- public void run() throws IllegalStateException
- {
if( m_manager == null )
{
throw new IllegalStateException("Container has not been
contextualized.");
}
- Thread.currentThread().setContextClassLoader( m_manager );
- try
- {
- handleInitialize();
- while( m_action.intValue() < DISPOSED )
- {
- synchronized( m_action )
- {
- if( m_state != m_action.intValue() )
- {
- switch( m_action.intValue() )
- {
- case STARTED:
- if( m_state == INITIALIZED )
- {
- handleStartup();
- }
- else if( m_state == SUSPENDED )
- {
- handleResume();
- }
- break;
- case SUSPENDED:
- if( m_state == STARTED )
- {
- handleSuspend();
- }
- break;
- case STOPPED:
- if(( m_state == STARTED ) || ( m_state ==
SUSPENDED ))
- {
- handleShutdown();
- }
- break;
- }
- }
- }
- sleep();
- }
- handleDispose();
- }
- catch( Throwable e )
+ if( m_map == null )
{
- final String error = "Unexpected error during container execution.";
- Throwable exception = new ContainerException( error, e );
- handleDispose( exception );
- m_error = exception;
+ final String error =
+ "Container has not been assembled.";
+ throw new IllegalStateException( error );
}
- }
-
- /**
- * Implementation of the initialization method. Initialization is handled after
- * a thread is established so that we can assign the manager as the thread
context
- * classloader.
- * @exception Exception if an error occurs during the initialization phase
- */
- public void handleInitialize() throws Exception
- {
- if( m_state >= INITIALIZED )
+ if( m_state >= StateEvent.INITIALIZED )
{
return;
}
@@ -365,27 +253,37 @@
// creation of the subsidiary containers
//
- getLogger().debug("subsidiary container creation" );
ContainerDescriptor[] containers = m_descriptor.getContainers();
+ getLogger().info("subsidiary container creation (" + containers.length +
")" );
for( int i=0; i<containers.length; i++ )
{
ContainerDescriptor descriptor = containers[i];
- ContainerService service = (ContainerService) m_services.get(
descriptor );
- if( service == null )
+ ContainerResource resource = (ContainerResource) m_services.get(
descriptor );
+ if( resource == null )
{
final String error =
- "Missing container service for descriptor: "
+ "Missing container resource for descriptor: "
+ descriptor.getName();
throw new IllegalStateException( error );
}
- //Resource resource = service.getResource( this );
- //resource.access();
- service.getContainerInstance( this, null );
+
+ //
+ // add ourselves as a state listener to the embedded container
+ // and request its instantiation
+ //
+
+ resource.addStateListener( this );
+ resource.access();
}
- m_state = INITIALIZED;
- fireStateChange( new StateEvent( this, getName(), INITIALIZED ) );
+ //
+ // fire a state event signalling the completion of the initialization stage
+ // and readness to handle install, startup or disposal requests
+ //
+
+ m_state = StateEvent.INITIALIZED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.INITIALIZED ) );
}
//======================================================================
@@ -393,117 +291,23 @@
//======================================================================
/**
- * Request the startup of the container.
+ * Implementation of the container startup procedure.
* @exception Exception if an error occurs during the startup phase
*/
public void start() throws Exception
{
- synchronized( this )
- {
- m_action = new Integer( STARTED );
- getLogger().debug("startup initiated");
- while(( m_state < STARTED ) && ( m_error == null ))
- {
- sleep();
- }
- if( m_error != null )
- {
- throw new ContainerException("Startup failure.", m_error );
- }
- }
- getLogger().debug("startup complete");
- }
-
- /**
- * Suspends the container.
- */
- public void suspend()
- {
- synchronized( this )
- {
- m_action = new Integer( SUSPENDED );
- getLogger().debug("suspension initiated");
- while(( m_state < SUSPENDED ) && ( m_error == null ))
- {
- sleep();
- }
- if( m_error != null )
- {
- throw new ContainerRuntimeException("Suspension failure.", m_error
);
- }
- }
- getLogger().debug("suspension completed");
- }
-
- /**
- * Resumes the container from a suspended state.
- */
- public void resume()
- {
- if( m_state != SUSPENDED )
- {
- throw new IllegalStateException(
- "Container is not suspended.");
- }
-
- synchronized( this )
- {
- m_action = new Integer( STARTED );
- getLogger().debug("suspension initiated");
- while(( m_state == SUSPENDED ) && ( m_error == null ))
- {
- sleep();
- }
- if( m_error != null )
- {
- throw new ContainerRuntimeException("Resumption failure.", m_error
);
- }
- }
- getLogger().debug("resumption completed");
- }
-
-
- /**
- * Request the shutdown of the container.
- * @exception Exception if an error occurs during the shutdown phase
- */
- public void stop() throws Exception
- {
- synchronized( this )
- {
- m_action = new Integer( STOPPED );
- getLogger().debug("shutdown initiated");
- while(( m_state < STOPPED ) && ( m_error == null ))
- {
- sleep();
- }
- if( m_error != null )
- {
- throw new ContainerException("Shutdown failure.", m_error );
- }
- }
- getLogger().debug("shutdown completed");
- }
-
- /**
- * Implementation of the container startup procedure. This is invoked ONCE
- * during the lifetime of the container.
- * @exception Exception if an error occurs during the startup phase
- */
- private void handleStartup() throws Exception
- {
- if( m_state < INITIALIZED )
+ if( m_state < StateEvent.INITIALIZED )
{
throw new IllegalStateException(
"Container has not been initialized.");
}
- if( m_state == STARTED )
+ if( m_state == StateEvent.STARTED )
{
return;
}
- if( m_state > STARTED )
+ if( m_state > StateEvent.STARTED )
{
throw new IllegalStateException(
"Container has already passed through start phase.");
@@ -513,13 +317,14 @@
// request startup of any unstarted components
//
- //m_manager.start();
- m_manager.start( m_map.getStartupGraph() );
+ //m_manager.start( m_map.getStartupGraph() );
+ m_manager.start();
//
// startup all of the subsidiary containers
//
+ getLogger().info("initiating startup of " + m_containers.size() + "
subsidiary containers.");
synchronized( m_containers )
{
Iterator iterator = m_containers.iterator();
@@ -528,32 +333,32 @@
Object next = iterator.next();
if( next instanceof Startable )
{
- ((Startable)next).start();
+ ((Container)next).start();
}
}
}
- m_state = STARTED;
+ m_state = StateEvent.STARTED;
getLogger().debug("container startup complete");
- fireStateChange( new StateEvent( this, getName(), STARTED ) );
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.STARTED ) );
}
/**
* Implementation of the container shutdown process.
*/
- public void handleShutdown()
+ public void stop() throws Exception
{
- if( m_state < STARTED )
+ if( m_state < StateEvent.STARTED )
{
return;
}
- if( m_state == STOPPED )
+ if( m_state == StateEvent.STOPPED )
{
return;
}
- if( m_state > STOPPED )
+ if( m_state > StateEvent.STOPPED )
{
throw new IllegalStateException("Already stopped.");
}
@@ -578,7 +383,7 @@
{
try
{
- ((Startable)next).stop();
+ ((Container)next).stop();
}
catch( Throwable e )
{
@@ -595,31 +400,30 @@
// stop the local components
//
- //m_manager.stop( );
m_manager.stop( m_map.getShutdownGraph() );
- m_state = STOPPED;
+ m_state = StateEvent.STOPPED;
getLogger().debug("container shutdown complete");
- fireStateChange( new StateEvent( this, getName(), STOPPED ) );
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.STOPPED ) );
}
- private void handleSuspend()
+ public void suspend()
{
- if( m_state < INITIALIZED )
+ if( m_state < StateEvent.INITIALIZED )
{
- throw new IllegalStateException(
- "Container has not been initialized.");
+ throw new IllegalStateException(
+ "Container has not been initialized.");
}
- if( m_state == SUSPENDED )
+ if( m_state == StateEvent.SUSPENDED )
{
- return;
+ return;
}
- if( m_state > STOPPED )
+ if( m_state > StateEvent.STOPPED )
{
- throw new IllegalStateException(
- "Container has been stopped.");
+ throw new IllegalStateException(
+ "Container has been stopped.");
}
if( getLogger().isDebugEnabled() )
@@ -636,24 +440,24 @@
Object next = iterator.next();
if( next instanceof Suspendable )
{
- ((Suspendable)next).suspend();
+ ((Container)next).suspend();
}
}
-
- while( !hasAchievedState( SUSPENDED ) )
- {
- sleep();
- }
}
getLogger().debug("container suspension complete");
- m_state = SUSPENDED;
- fireStateChange( new StateEvent( this, getName(), SUSPENDED ) );
+ m_state = StateEvent.SUSPENDED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.SUSPENDED ) );
}
- private void handleResume()
+ /**
+ * Resumes the container from a suspended state.
+ *
+ * @exception IllegalStateException if the container is not suspended
+ */
+ public void resume()
{
- if( m_state != SUSPENDED )
+ if( m_state != StateEvent.SUSPENDED )
{
throw new IllegalStateException(
"Container is not suspended.");
@@ -692,19 +496,14 @@
Object next = iterator.next();
if( next instanceof Suspendable )
{
- ((Suspendable)next).resume();
+ ((Container)next).resume();
}
}
-
- while( !hasAchievedState( STARTED ) )
- {
- sleep();
- }
}
getLogger().debug("container resumption complete");
- m_state = STARTED;
- fireStateChange( new StateEvent( this, getName(), STARTED ) );
+ m_state = StateEvent.STARTED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.STARTED ) );
}
//=======================================================================
@@ -723,7 +522,7 @@
Container container = (Container) event.getSource();
switch( state )
{
- case INITIALIZED:
+ case StateEvent.INITIALIZED:
synchronized( m_containers )
{
m_containers.add( container );
@@ -731,7 +530,7 @@
fireStructuralChange(
new ContainerEvent( this, container, ContainerEvent.ADD ) );
break;
- case DISPOSED:
+ case StateEvent.DISPOSED:
synchronized( m_containers )
{
getLogger().debug(
@@ -748,30 +547,10 @@
//=======================================================================
/**
- * Return the container name.
- *
- * @return the name of the container
- */
- private String getName()
- {
- return m_descriptor.getName();
- }
-
- /**
- * Return the current state of the container.
- *
- * @return the container state
- */
- public int getState()
- {
- return m_state;
- }
-
- /**
* Adds a <code>StateListener</code>.
* @param listener the state listener to add
*/
- protected void addStateListener( StateListener listener )
+ public void addStateListener( StateListener listener )
{
synchronized( m_stateListeners )
{
@@ -783,7 +562,7 @@
* Removes a <code>StateListener</code>.
* @param listener the state listener to remove
*/
- protected void removeStateListener( StateListener listener )
+ public void removeStateListener( StateListener listener )
{
synchronized( m_stateListeners )
{
@@ -795,7 +574,7 @@
* Adds a <code>ContainerListener</code>.
* @param listener the container listener to add
*/
- protected void addContainerListener( ContainerListener listener )
+ public void addContainerListener( ContainerListener listener )
{
synchronized( m_containerListeners )
{
@@ -807,7 +586,7 @@
* Removes a <code>ContainerListener</code>.
* @param listener the container listener to remove
*/
- protected void removeContainerListener( ContainerListener listener )
+ public void removeContainerListener( ContainerListener listener )
{
synchronized( m_containerListeners )
{
@@ -820,9 +599,10 @@
*
* @return the set of exported resources
*/
+/*
public Resource[] getResources()
{
- if( m_state < INITIALIZED )
+ if( m_state < StateEvent.INITIALIZED )
{
throw new IllegalStateException("not-initialized");
}
@@ -852,6 +632,7 @@
}
return (Resource[]) list.toArray( new Resource[0] );
}
+*/
/**
* Returns the set of subsidiary continers container within this container.
@@ -873,9 +654,9 @@
*/
public void install( Profile[] profiles ) throws Exception
{
- if( m_state != SUSPENDED )
+ if( m_state != StateEvent.SUSPENDED )
{
- if( m_state != INITIALIZED )
+ if( m_state != StateEvent.INITIALIZED )
{
throw new IllegalStateException(
"Container not in suspended or initialized state." );
@@ -905,33 +686,15 @@
*/
public void dispose()
{
- synchronized( this )
- {
- m_error = null;
- m_action = new Integer( DISPOSED );
- getLogger().debug("diposal initiated");
- while(( m_state < DISPOSED ) && ( m_error == null ))
- {
- sleep();
- }
- }
+ dispose( null );
getLogger().debug("disposal complete");
-
- }
-
- /**
- * Handle normal disposal of the container.
- */
- private void handleDispose()
- {
- handleDispose( null );
}
/**
* Handle disposal of the container.
* @param error a possible null throwable trigggering the disposal
*/
- private void handleDispose( Throwable error )
+ private void dispose( Throwable error )
{
if( error != null )
{
@@ -939,11 +702,11 @@
getLogger().error( message, error );
}
- if( m_state == STARTED )
+ if( m_state == StateEvent.STARTED )
{
try
{
- handleShutdown();
+ stop();
}
catch( Throwable e )
{
@@ -955,24 +718,20 @@
// dispose of all of the nested containers
//
- synchronized( m_containers )
+ Object[] containers = m_containers.toArray();
+ for( int i=0; i<containers.length; i++ )
{
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
+ Object object = containers[i];
+ if( object instanceof Disposable )
{
- Container container = (Container)iterator.next();
- if( container instanceof Disposable )
- {
- ((Disposable)container).dispose();
- }
+ ((Disposable)object).dispose();
}
}
m_manager.dispose();
-
getLogger().debug("done");
- m_state = DISPOSED;
- fireStateChange( new StateEvent( this, getName(), DISPOSED, error ) );
+ m_state = StateEvent.DISPOSED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(),
StateEvent.DISPOSED, error ) );
}
//=======================================================================
@@ -1052,11 +811,11 @@
* @return the new container
* @exception Exception is an error occurs
*/
- public Container addContainer( String name )
- throws Exception
- {
- return addContainer( name, new ClasspathDescriptor() );
- }
+ //public Container addContainer( String name )
+ // throws Exception
+ //{
+ // return addContainer( name, new ClasspathDescriptor() );
+ //}
/**
* Creation of a new empty container associated as a subsidiary of this container
@@ -1067,12 +826,12 @@
* @return the new container
* @exception Exception is an error occurs
*/
- public Container addContainer( String name, ClasspathDescriptor classpath )
- throws Exception
- {
- return addContainer(
- new ContainerDescriptor( name, m_descriptor ), classpath );
- }
+ //public Container addContainer( String name, ClasspathDescriptor classpath )
+ // throws Exception
+ //{
+ // return addContainer(
+ // new ContainerDescriptor( name, m_descriptor ), classpath );
+ //}
/**
* Utility to create a subsidiary container from a configuration.
@@ -1081,17 +840,17 @@
* @return the new container
* @exception Exception is an error occurs
*/
- public Container addContainer( Configuration config ) throws Exception
- {
- if( !(( m_state == INITIALIZED ) || ( m_state == SUSPENDED )) )
- {
- throw new IllegalStateException(
- "Container not in initialized or suspended state." );
- }
-
- ContainerService service = m_factory.build( config );
- return service.getContainerInstance( this, null );
- }
+ //public Container addContainer( Configuration config ) throws Exception
+ //{
+ // if( !(( m_state == StateEvent.INITIALIZED ) || ( m_state ==
StateEvent.SUSPENDED )) )
+ // {
+ // throw new IllegalStateException(
+ // "Container not in initialized or suspended state." );
+ // }
+ //
+ // ContainerService service = m_factory.build( config );
+ // return service.getContainerInstance( this, null );
+ //}
/**
* Internal utility to create a subsidiary container.
@@ -1100,20 +859,20 @@
* @return the new container
* @exception Exception is an error occurs
*/
- private Container addContainer(
- ContainerDescriptor descriptor,
- ClasspathDescriptor classpath )
- throws Exception
- {
- if( !(( m_state == INITIALIZED ) || ( m_state == SUSPENDED )) )
- {
- throw new IllegalStateException(
- "Container not in initialized or suspended state." );
- }
-
- ContainerService service = m_factory.build( descriptor, classpath );
- return service.getContainerInstance( this, null );
- }
+ //private Container addContainer(
+ // ContainerDescriptor descriptor,
+ // ClasspathDescriptor classpath )
+ // throws Exception
+ //{
+ // if( !(( m_state == StateEvent.INITIALIZED ) || ( m_state ==
StateEvent.SUSPENDED )) )
+ // {
+ // throw new IllegalStateException(
+ // "Container not in initialized or suspended state." );
+ // }
+ //
+ // ContainerService service = m_factory.build( descriptor, classpath );
+ // return service.getContainerInstance( this, null );
+ //}
/**
* Internal utility to sleep a bit.
@@ -1126,29 +885,6 @@
}
catch( Throwable wakeup )
{
- }
- }
-
- /**
- * Internal utility to check if all of the subsidiary containers have
- * achieved a particular state. The implementation tests if ever container
- * has achieved a state greater than or equal to the supplied state.
- * @return TRUE if all of the containers have reached or exceed the supplied
state
- */
- private boolean hasAchievedState( int state )
- {
- synchronized( m_containers )
- {
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
- {
- Container container = (Container)iterator.next();
- if( container.getState() < state )
- {
- return false;
- }
- }
- return true;
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>