mcconnell 2002/08/08 14:30:18
Modified: assembly/demo/src/java/org/apache/excalibur/playground
EmbeddedDemo.java
assembly/src/etc kernel.xml
assembly/src/java/org/apache/excalibur/merlin/assembly
ContainerManager.java
assembly/src/java/org/apache/excalibur/merlin/container
Container.java DefaultContainer.java
StateEvent.java
assembly/src/java/org/apache/excalibur/merlin/kernel
DefaultKernel.java Kernel.java
assembly/src/java/org/apache/excalibur/merlin/model/builder
ContainerBuilder.java
Log:
General enhancements to sysnc/async management.
Revision Changes Path
1.8 +9 -23
jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/EmbeddedDemo.java
Index: EmbeddedDemo.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/EmbeddedDemo.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- EmbeddedDemo.java 8 Aug 2002 10:02:34 -0000 1.7
+++ EmbeddedDemo.java 8 Aug 2002 21:30:16 -0000 1.8
@@ -73,6 +73,7 @@
// Create the kernel with a root container named "work".
//
+ getLogger().info("creating kernel");
m_kernel = new DefaultKernel( );
DefaultContext context = new DefaultContext( m_context );
context.put( DefaultKernel.PATH_KEY, "work" );
@@ -84,6 +85,7 @@
// Get the root container from the kernel we just created.
//
+ getLogger().debug("retriving root");
Container root = m_kernel.getRootContainer();
//
@@ -92,18 +94,8 @@
// add this to the root container to define another new sub-container.
//
- ReferenceDescriptor containerInterface =
- new ReferenceDescriptor(
"org.apache.excalibur.merlin.container.Container" );
- ContainerDescriptor cd = (ContainerDescriptor) manager.getProfile(
containerInterface );
- Container container;
- if( cd != null )
- {
- container = root.createSubContainer( "admin", cd, new
ClasspathDescriptor() );
- }
- else
- {
- throw new IllegalStateException("Manager returned a null container
profile.");
- }
+ getLogger().debug("adding subcontainer: admin");
+ Container container = root.createSubContainer( "admin" );
//
// Add a component to the container programatically.
@@ -113,12 +105,6 @@
// container.
//
- //DependencyDescriptor descriptor =
- // new DependencyDescriptor(
- // "my-component",
- // new ReferenceDescriptor(
"org.apache.excalibur.playground.SimpleService" ) );
- //Profile profile = manager.getProfile( descriptor );
-
Profile profile = manager.getProfile(
new ReferenceDescriptor( "org.apache.excalibur.playground.SimpleService"
) );
@@ -128,9 +114,9 @@
if( profile != null )
{
- getLogger().info( "dynamic profile: " + profile );
+ getLogger().debug( "dynamic profile: " + profile );
container.install( new Profile[]{ profile } );
- getLogger().info("installation sucessfull" );
+ getLogger().debug("installation sucessfull" );
}
else
{
@@ -145,13 +131,13 @@
public void start() throws Exception
{
getLogger().info("starting");
- m_kernel.startup();
+ m_kernel.start();
}
- public void stop()
+ public void stop() throws Exception
{
getLogger().info("stopping");
- m_kernel.shutdown();
+ m_kernel.stop();
}
public void dispose()
1.27 +8 -5 jakarta-avalon-excalibur/assembly/src/etc/kernel.xml
Index: kernel.xml
===================================================================
RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/kernel.xml,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- kernel.xml 8 Aug 2002 10:02:34 -0000 1.26
+++ kernel.xml 8 Aug 2002 21:30:17 -0000 1.27
@@ -21,7 +21,7 @@
the corresponds to the name of the logging file.
-->
- <logging priority="WARN" target="default">
+ <logging priority="INFO" target="default">
<target name="kernel">
<file location="kernel.log" />
</target>
@@ -30,7 +30,7 @@
<categories priority="INFO">
<category priority="WARN" name="logging" />
<category priority="WARN" name="loader" />
- <category priority="INFO" name="export" />
+ <category priority="WARN" name="export" />
</categories>
<!--
@@ -147,7 +147,7 @@
enabled="true"
activation="true">
- <categories priority="DEBUG"/>
+ <categories priority="INFO"/>
<configuration>
<message>This is a custom message.</message>
@@ -156,10 +156,13 @@
</component>
<!--
- Demonstration of a component that contains an embedded kernel.
+ Demonstration of a component that contains an embedded kernel that
programatically
+ adds a container or two, and a new component type. To enable this demo -
change the
+ enabled attribute on the component element to true.
-->
<component name="embedder"
- class="org.apache.excalibur.playground.EmbeddedDemo" activation="true">
+ class="org.apache.excalibur.playground.EmbeddedDemo" enabled="false"
activation="true">
+ <categories priority="INFO"/>
<context>
<import key="avalon:home" name="avalon:home"/>
<import key="classloader" name="classloader"/>
1.8 +14 -44
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java
Index: ContainerManager.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ContainerManager.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- ContainerManager.java 8 Aug 2002 10:02:35 -0000 1.7
+++ ContainerManager.java 8 Aug 2002 21:30:17 -0000 1.8
@@ -240,16 +240,6 @@
public void contextualize( Context context ) throws ContextException
{
m_context = context;
-
- try
- {
- m_categories = (CategoriesDescriptor) context.get(
CATEGORIES_DESCRIPTOR_KEY );
- }
- catch( ContextException e )
- {
- // optional
- }
-
super.contextualize( context );
}
@@ -262,24 +252,6 @@
XMLContainerUtil creator = new XMLContainerUtil();
//
- // take care of logging category declarations from the configuration
- // if not already supplied under the context
- //
-
- if( m_categories == null )
- {
- Category loader = new Category( "loader", "WARN", null );
- Category assembly = new Category( "loader.assembly" );
- Category types = new Category( "loader.types" );
-
- m_categories = new CategoriesDescriptor(
- m_name, "INFO", null, new Category[]{ loader, assembly, types } );
- }
-
- String path = getPath().replace('/','.').substring(1);
- getLoggingManager().addCategories( path, m_categories );
-
- //
// start internal initialization
//
@@ -343,8 +315,9 @@
//======================================================================
/**
- * Method invoked by the container's container to signal the activation of
- * all components.
+ * Method invoked by the managers container to signal the activation of
+ * all components. This method may be invoked multiple times during a
+ * the life of the manager.
*
* @exception Exception if a start related error occurs
*/
@@ -368,10 +341,6 @@
getLocalLogger().info( profile + " [activating]");
resource.access();
}
- else
- {
- getLocalLogger().info( profile + " [already running]");
- }
}
else
{
@@ -430,28 +399,30 @@
public ContainerManager createContainerManager(
String name,
- ContainerDescriptor descriptor,
- ClasspathDescriptor classpath,
- Logger logger )
+ ClasspathDescriptor classpath )
{
try
{
ContainerManager loader = new ContainerManager( this, name );
DefaultContext context = new DefaultContext( m_context );
- context.put( ContainerManager.CATEGORIES_DESCRIPTOR_KEY,
descriptor.getCategories() );
context.put( TypeManager.CLASSPATH_DESCRIPTOR_KEY, classpath );
context.makeReadOnly();
- loader.enableLogging( logger );
+ if( this instanceof KernelManager )
+ {
+ loader.enableLogging( getLogger() );
+ }
+ else
+ {
+ loader.enableLogging( getLogger().getChildLogger( name ) );
+ }
loader.contextualize( context );
loader.initialize();
return loader;
}
catch( Throwable e )
{
- final String error = "error creating manager for container descriptor:
"
- + descriptor.getName()
- + " in manager: " + getPath();
+ final String error = "error creating manager for: " + getPath() + "/" +
name;
throw new TypeRuntimeException( error, e );
}
}
@@ -778,7 +749,6 @@
{
return (Resource) m_resources.get( profile );
}
-
/**
* Returns the set of profiles capable of supporting the supplied service.
1.11 +34 -8
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/Container.java
Index: Container.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/Container.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- Container.java 8 Aug 2002 10:02:35 -0000 1.10
+++ Container.java 8 Aug 2002 21:30:17 -0000 1.11
@@ -29,10 +29,9 @@
* @version $Revision$ $Date$
* @see DefaultContainer
*/
-public interface Container extends Controller
+public interface Container
{
-
/**
* Static state enumeration value indicating that the state of a container is
unknown.
*/
@@ -52,17 +51,22 @@
static final int STARTED = 2;
/**
+ * Static state enumeration value indicating that a container has been suspended.
+ */
+ static final int SUSPENDED = 3;
+
+ /**
* Static state enumeration value indicating that a container has completed
* the shutdown of all subsidiary containers and the internal components
* have been shutdown.
*/
- static final int STOPPED = 3;
+ static final int STOPPED = 4;
/**
* Static state enumeration value indicating that a container and all
* subsidiary containers have been disposed of.
*/
- static final int DISPOSED = 4;
+ static final int DISPOSED = 5;
/**
* Return the container name.
@@ -97,7 +101,29 @@
* Add and assemble the supplied set of profiles.
* @param profiles the profiles to assemble
*/
- public void install( Profile[] profiles ) throws Exception;
+ void install( Profile[] profiles )
+ throws Exception;
+
+ /**
+ * Creation of a new empty container associated as a subsidiary of this container
+ * using the same container profile as this container and an empty classpath.
+ *
+ * @param name the name to assign to the new container
+ * @exception Exception is an error occurs
+ */
+ Container createSubContainer( String name )
+ throws Exception;
+
+ /**
+ * Creation of a new empty container associated as a subsidiary of this container
+ * using the same container profile as this container.
+ *
+ * @param name the name to assign to the new container
+ * @param classpath the container classpath
+ * @exception Exception is an error occurs
+ */
+ Container createSubContainer( String name, ClasspathDescriptor classpath )
+ throws Exception;
/**
* Creation of a new empty container associated as a subsidiary of this
container.
@@ -108,6 +134,6 @@
* @exception Exception is an error occurs
*/
public Container createSubContainer(
- String name, ContainerDescriptor descriptor, ClasspathDescriptor classpath )
throws Exception;
-
+ String name, ContainerDescriptor descriptor, ClasspathDescriptor classpath )
+ throws Exception;
}
1.27 +399 -138
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.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- DefaultContainer.java 8 Aug 2002 10:02:35 -0000 1.26
+++ DefaultContainer.java 8 Aug 2002 21:30:17 -0000 1.27
@@ -38,6 +38,7 @@
import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.activity.Executable;
import org.apache.avalon.framework.activity.Startable;
+import org.apache.avalon.framework.activity.Suspendable;
import org.apache.avalon.framework.CascadingRuntimeException;
import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.DefaultConfiguration;
@@ -87,7 +88,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$ $Date$
*/
-public class DefaultContainer extends AbstractLogEnabled implements Container,
Contextualizable, Configurable, Initializable, Disposable, Runnable, StateListener
+public class DefaultContainer extends AbstractLogEnabled implements Container,
Contextualizable, Configurable, Initializable, Startable, Suspendable, Disposable,
Runnable, StateListener
{
//=======================================================================
// static
@@ -118,6 +119,11 @@
*/
public static final String CONFIGURATIONS_KEY = "configurations";
+ /**
+ * Context key used to locate the logging manager.
+ */
+ public static final String LOGGING_KEY = "logging";
+
private static final Resources REZ =
ResourceManager.getPackageResources( DefaultContainer.class );
@@ -185,6 +191,10 @@
private Configuration[] m_configs;
+ private DefaultLoggerManager m_logging;
+
+ private Throwable m_error;
+
//=======================================================================
// Contextualizable
//=======================================================================
@@ -198,6 +208,8 @@
* a {@link ContainerManager} (REQUIRED}</li>
* <li>{@link #DESCRIPTOR_KEY} the container meta data
* {@link ContainerDescriptor} (REQUIRED}</li>
+ * <li>{@link #LOGGING_KEY} the logging manager
+ {@link DefaultLoggerManager} (REQUIRED}</li>
* <li>{@link #CONFIGURATIONS_KEY} the set of subsidiary container
* configurations {@link Configuration}[] (OPTIONAL}</li>
* <li>{@link #STATE_LISTENER_KEY} a container state listener
@@ -211,6 +223,7 @@
{
m_manager = (ContainerManager) context.get( MANAGER_KEY );
m_descriptor = (ContainerDescriptor) context.get( DESCRIPTOR_KEY );
+ m_logging = (DefaultLoggerManager) context.get( LOGGING_KEY );
try
{
@@ -262,10 +275,43 @@
}
//=======================================================================
- // Runnable
+ // Initializable
//=======================================================================
/**
+ * Initalization of a <code>Container</code>. The implementation launches
+ * a new thread of execution within which the primary initalization actions
+ * are undertaken 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.
+ *
+ * @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.
+ */
+ public void initialize() throws Exception
+ {
+ 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.
@@ -288,10 +334,20 @@
{
case STARTED:
if( m_state == INITIALIZED )
- handleStartup();
+ {
+ handleStartup();
+ }
+ else if( m_state == SUSPENDED )
+ {
+ handleResume();
+ }
break;
- case STOPPED:
+ case SUSPENDED:
if( m_state == STARTED )
+ handleSuspend();
+ break;
+ case STOPPED:
+ if(( m_state == STARTED ) || ( m_state ==
SUSPENDED ))
handleShutdown();
break;
}
@@ -306,33 +362,10 @@
final String error = "Unexpected error during container execution.";
Throwable exception = new ContainerException( error, e );
handleDispose( exception );
+ m_error = exception;
}
}
- //=======================================================================
- // Initializable
- //=======================================================================
-
- /**
- * Initalization of a <code>Container</code>. The implementation launches
- * a new thread of execution within which the primary initalization actions
- * are undertaken 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.
- *
- * @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.
- */
- public void initialize() throws Exception
- {
- m_thread = new Thread( (Runnable) this );
- m_thread.start();
- }
-
/**
* Implementation of the initialization method. Initialization is handled after
* a thread is established so that we can assign the manager as the thread
context
@@ -343,8 +376,6 @@
if( m_state >= INITIALIZED )
return;
- getLogger().debug( "initialization" );
-
//
// initiate component assembly
//
@@ -375,22 +406,9 @@
{
final Configuration conf = m_configs[i];
final Container container = createContainer( conf );
- //m_containers.add( container );
}
- getLogger().debug("commence wait" );
- while( !hasAchievedState( INITIALIZED ) )
- {
- try
- {
- sleep();
- }
- catch( Throwable e )
- {
- }
- }
m_state = INITIALIZED;
- getLogger().debug("initialized" );
fireStateChange( new StateEvent( this, INITIALIZED ) );
}
@@ -401,16 +419,95 @@
/**
* Request the startup of the container.
*/
- public void startup() throws Exception
+ public void start() throws Exception
{
- synchronized( m_action )
+ 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.
+ */
+ 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.
+ * Implementation of the container startup procedure. This is invoked ONCE
+ * during the lifetime of the container.
*/
private void handleStartup() throws Exception
{
@@ -429,33 +526,9 @@
getLogger().debug("container startup");
//
- // startup all of the components in this container
- // before starting up any of the nested containers
+ // list the profiles in the startup graph
//
- start();
-
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
- {
- ((Container)iterator.next()).startup();
- }
-
- while( !hasAchievedState( STARTED ) )
- sleep();
-
- getLogger().debug("container startup complete");
- m_state = STARTED;
- fireStateChange( new StateEvent( this, STARTED ) );
- }
-
- /**
- * Activate all local components.
- *
- * @exception Exception if a start related error occurs
- */
- private void start() throws Exception
- {
if( getLogger().isInfoEnabled() )
{
Profile[] profiles = m_manager.getStartupGraph( false );
@@ -476,22 +549,40 @@
getLogger().info( "startup" );
}
}
+
+ //
+ // request startup of any unstarted compoents
+ //
+
m_manager.start();
- }
- /**
- * Request the shutdown of the container.
- */
- public void shutdown()
- {
- synchronized( m_action )
+ //
+ // statup all of the subsidiary containers
+ //
+
+ synchronized( m_containers )
{
- m_action = new Integer( STOPPED );
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
+ {
+ Object next = iterator.next();
+ if( next instanceof Startable )
+ {
+ ((Startable)next).start();
+ }
+ }
+
+ while( !hasAchievedState( STARTED ) )
+ sleep();
}
+
+ getLogger().debug("container startup complete");
+ m_state = STARTED;
+ fireStateChange( new StateEvent( this, STARTED ) );
}
/**
- * Impleementation of the container shutdown process.
+ * Implementation of the container shutdown process.
*/
public void handleShutdown()
{
@@ -512,30 +603,35 @@
// the components in this container
//
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
+ synchronized( m_containers )
{
- ((Container)iterator.next()).shutdown();
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
+ {
+ Object next = iterator.next();
+ if( next instanceof Startable )
+ {
+ try
+ {
+ ((Startable)next).stop();
+ }
+ catch( Throwable e )
+ {
+ final String warning =
+ "Failed to stop sub-container: "
+ + ((Container)next).getName();
+ getLogger().warn( warning, e );
+ }
+ }
+ }
+ while( !hasAchievedState( STOPPED ) )
+ sleep();
}
- stop();
-
- while( !hasAchievedState( STOPPED ) )
- sleep();
-
- getLogger().debug("container shutdown complete");
- m_state = STOPPED;
- fireStateChange( new StateEvent( this, STOPPED ) );
- }
+ //
+ // list all of the local components to stop
+ //
- /**
- * Method invoked by the container's container to signal the deactivation of
- * all components.
- *
- * @exception Exception if a stop related error occurs
- */
- private void stop()
- {
if( getLogger().isInfoEnabled() )
{
Profile[] profiles = m_manager.getShutdownGraph();
@@ -557,7 +653,103 @@
getLogger().info( "shutdown" );
}
}
+
+ //
+ // stop the local components
+ //
+
m_manager.stop();
+
+ getLogger().debug("container shutdown complete");
+ m_state = STOPPED;
+ fireStateChange( new StateEvent( this, STOPPED ) );
+ }
+
+ private void handleSuspend()
+ {
+ if( m_state < INITIALIZED )
+ throw new IllegalStateException(
+ "Container has not been initialized.");
+
+ if( m_state == SUSPENDED )
+ return;
+
+ if( m_state > STOPPED )
+ throw new IllegalStateException(
+ "Container has been stopped.");
+
+ if( getLogger().isDebugEnabled() )
+ getLogger().debug("container suspension");
+
+ synchronized( m_containers )
+ {
+ Iterator iterator = m_containers.iterator();
+
+ while( iterator.hasNext() )
+ {
+ Object next = iterator.next();
+ if( next instanceof Suspendable )
+ {
+ ((Suspendable)next).suspend();
+ }
+ }
+
+ while( !hasAchievedState( SUSPENDED ) )
+ sleep();
+ }
+
+ getLogger().debug("container suspension complete");
+ m_state = SUSPENDED;
+ fireStateChange( new StateEvent( this, SUSPENDED ) );
+ }
+
+ private void handleResume()
+ {
+ if( m_state != SUSPENDED )
+ throw new IllegalStateException(
+ "Container is not suspended.");
+
+ if( getLogger().isDebugEnabled() )
+ getLogger().debug("container resuming");
+
+ //
+ // reapply start to the manager
+ //
+
+ try
+ {
+ m_manager.start();
+ }
+ catch( Throwable e )
+ {
+ final String warning = "Container type manager raised an error while
resuming.";
+ getLogger().warn( warning, e );
+ }
+
+ //
+ // resume subsidiary containers
+ //
+
+ synchronized( m_containers )
+ {
+ Iterator iterator = m_containers.iterator();
+
+ while( iterator.hasNext() )
+ {
+ Object next = iterator.next();
+ if( next instanceof Suspendable )
+ {
+ ((Suspendable)next).resume();
+ }
+ }
+
+ while( !hasAchievedState( STARTED ) )
+ sleep();
+ }
+
+ getLogger().debug("container resumption complete");
+ m_state = STARTED;
+ fireStateChange( new StateEvent( this, STARTED ) );
}
//=======================================================================
@@ -578,14 +770,20 @@
case INITIALIZED:
getLogger().debug(
"subsidiary container initialized: " + container.getName() );
+ synchronized( m_containers )
+ {
+ m_containers.add( container );
+ }
fireStructuralChange(
new ContainerEvent( this, container, ContainerEvent.ADD ) );
break;
case DISPOSED:
- getLogger().debug(
+ synchronized( m_containers )
+ {
+ getLogger().debug(
"removing subsidiary container: " + container.getName() );
- //container.removeStateListener( this );
- m_containers.remove( container );
+ m_containers.remove( container );
+ }
fireStructuralChange(
new ContainerEvent( this, container, ContainerEvent.REMOVE ) );
}
@@ -675,16 +873,19 @@
{
list.add( local[i] );
}
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
+ synchronized( m_containers )
{
- Container container = (Container)iterator.next();
- Resource[] resources = container.getResources();
- for( int j=0; j<resources.length; j++ )
- {
- Resource resource = resources[j];
- if( !list.contains( resource ) )
- list.add( resources[j] );
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
+ {
+ Container container = (Container)iterator.next();
+ Resource[] resources = container.getResources();
+ for( int j=0; j<resources.length; j++ )
+ {
+ Resource resource = resources[j];
+ if( !list.contains( resource ) )
+ list.add( resources[j] );
+ }
}
}
return (Resource[]) list.toArray( new Resource[0] );
@@ -697,7 +898,10 @@
*/
public Container[] getContainers()
{
- return (Container[]) m_containers.toArray( new Container[0] );
+ synchronized( m_containers )
+ {
+ return (Container[]) m_containers.toArray( new Container[0] );
+ }
}
/**
@@ -707,6 +911,10 @@
*/
public void install( Profile[] profiles ) throws Exception
{
+ if( m_state != SUSPENDED )
+ if( m_state != INITIALIZED )
+ throw new IllegalStateException( "Container not in suspended or
initialized state." );
+
for( int i=0; i<profiles.length; i++ )
{
m_manager.addProfile( profiles[i] );
@@ -723,10 +931,18 @@
*/
public void dispose()
{
- synchronized( m_action )
+ synchronized( this )
{
+ m_error = null;
m_action = new Integer( DISPOSED );
+ getLogger().debug("diposal initiated");
+ while(( m_state < DISPOSED ) && ( m_error == null ))
+ {
+ sleep();
+ }
}
+ getLogger().debug("disposal complete");
+
}
/**
@@ -764,20 +980,19 @@
// dispose of all of the nested containers
//
- getLogger().debug("dispose");
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
+ synchronized( m_containers )
{
- Container container = (Container)iterator.next();
- if( container instanceof Disposable )
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
{
- ((Disposable)container).dispose();
+ Container container = (Container)iterator.next();
+ if( container instanceof Disposable )
+ {
+ ((Disposable)container).dispose();
+ }
}
}
- while( !hasAchievedState( DISPOSED ) )
- sleep();
-
m_manager.dispose();
getLogger().debug("done");
@@ -851,9 +1066,44 @@
}
/**
+ * Creation of a new empty container associated as a subsidiary of this container
+ * using the same container profile as this container and an empty classpath.
+ *
+ * @param name the name to assign to the new container
+ * @exception Exception is an error occurs
+ */
+ public Container createSubContainer(
+ String name )
+ throws Exception
+ {
+ return createContainer(
+ name, m_descriptor, new ClasspathDescriptor(), new Configuration[0], new
Configuration[0] );
+ }
+
+
+ /**
+ * Creation of a new empty container associated as a subsidiary of this container
+ * using the same container profile as this container.
+ *
+ * @param name the name to assign to the new container
+ * @param classpath the container classpath
+ * @exception Exception is an error occurs
+ */
+ public Container createSubContainer(
+ String name,
+ ClasspathDescriptor classpath )
+ throws Exception
+ {
+ return createContainer(
+ name, m_descriptor, classpath, new Configuration[0], new Configuration[0]
);
+ }
+
+ /**
* Creation of a new empty container associated as a subsidiary of this
container.
*
+ * @param name the name to assign to the new container
* @param descriptor the container meta descriptor
+ * @param classpath the container classpath
* @exception Exception is an error occurs
*/
public Container createSubContainer(
@@ -862,7 +1112,12 @@
ClasspathDescriptor classpath )
throws Exception
{
- return createContainer( name, descriptor, classpath, new Configuration[0],
new Configuration[0] );
+ if( m_state != SUSPENDED )
+ if( m_state != INITIALIZED )
+ throw new IllegalStateException( "Container not in initialized or
suspended state." );
+
+ return createContainer(
+ name, descriptor, classpath, new Configuration[0], new Configuration[0] );
}
/**
@@ -883,12 +1138,19 @@
try
{
//
+ // create the logging categories for the container
+ //
+
+ CategoriesDescriptor categories = descriptor.getCategories();
+ String base = m_manager.getPath().replace('/','.').substring(1) + "." +
name;
+ m_logging.addCategories( base, categories );
+
+ //
// create the manager
//
final ContainerManager manager =
- m_manager.createContainerManager(
- name, descriptor, classpath, getLogger().getChildLogger( name ) );
+ m_manager.createContainerManager( name, classpath );
//
// populate the descriptor with the components it contains
@@ -922,6 +1184,7 @@
DefaultContext context = new DefaultContext();
context.put( MANAGER_KEY, manager );
context.put( DESCRIPTOR_KEY, descriptor );
+ context.put( LOGGING_KEY, m_logging );
context.put( CONFIGURATIONS_KEY, containers );
context.put( STATE_LISTENER_KEY, this );
context.makeReadOnly();
@@ -930,11 +1193,6 @@
createContainerInstance(
manager, descriptor.getType().getInfo().getImplementationKey() );
- synchronized( m_containers )
- {
- m_containers.add( container );
- }
-
final Logger logger = getLogger().getChildLogger( name );
container.enableLogging( logger );
container.contextualize( context );
@@ -1047,13 +1305,16 @@
*/
private boolean hasAchievedState( int state )
{
- Iterator iterator = m_containers.iterator();
- while( iterator.hasNext() )
+ synchronized( m_containers )
{
- Container container = (Container)iterator.next();
- if( container.getState() < state )
- return false;
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
+ {
+ Container container = (Container)iterator.next();
+ if( container.getState() < state )
+ return false;
+ }
+ return true;
}
- return true;
}
}
1.3 +1 -1
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StateEvent.java
Index: StateEvent.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/StateEvent.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- StateEvent.java 5 Aug 2002 12:39:37 -0000 1.2
+++ StateEvent.java 8 Aug 2002 21:30:17 -0000 1.3
@@ -40,7 +40,7 @@
*
* @param container the source container
* @param state int value of (@link Container#INITIALIZED}, {@link
Container#STARTED},
- * {@link Container#STOPPED} or {@link Container#DISPOSED}
+ * {@link Container#SUSPENDED}, {@link Container#STOPPED} or {@link
Container#DISPOSED}
*/
public StateEvent( Container container, int state )
{
1.32 +58 -128
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java
Index: DefaultKernel.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/DefaultKernel.java,v
retrieving revision 1.31
retrieving revision 1.32
diff -u -r1.31 -r1.32
--- DefaultKernel.java 8 Aug 2002 10:02:35 -0000 1.31
+++ DefaultKernel.java 8 Aug 2002 21:30:17 -0000 1.32
@@ -104,7 +104,7 @@
File <strong>base</strong> = new File( <font
color="darkred"/>"."</font> );
DefaultContext <strong>context</strong> = new DefaultContext();
- <strong>context</strong>.put( DefaultKernel.APPLICATION_DIR_KEY,
<strong>base</strong> );
+ <strong>context</strong>.put( DefaultKernel.DIR_KEY, <strong>base</strong>
);
<strong>context</strong>.makeReadOnly();
<font color="gray">//
@@ -145,7 +145,7 @@
* @version $Revision$ $Date$
*/
public class DefaultKernel
- implements Kernel, Contextualizable, Configurable, Initializable, Startable,
Disposable, StateListener
+ implements Kernel, Contextualizable, Configurable, Initializable, Startable,
Disposable
{
//=======================================================================
// static
@@ -209,7 +209,7 @@
private Logger m_localLogger;
/**
- * The kernel path.
+ * The kernel relative path.
*/
private String m_path;
@@ -224,13 +224,21 @@
*/
private static DefaultLoggerManager m_logging;
+ /**
+ * The kernel manager's base path.
+ */
+ private String m_base;
+
+ private ContainerManager m_parent;
//=======================================================================
// Contextualizable
//=======================================================================
/**
- * Invoked by the bootstrap process to supply the root directory.
+ * Invoked by the bootstrap process to supply the root directory and
+ * optional a path identifying the name of the root container.
+ *
* @param context the context object containing the inital parameters
* @exception ContextException if the supplied does not contain a
* DIR_KEY value.
@@ -282,46 +290,59 @@
if( Thread.currentThread().getContextClassLoader() instanceof
ContainerManager )
{
m_root = false;
+ m_parent =
+ (ContainerManager)Thread.currentThread().getContextClassLoader();
+ m_base = m_parent.getPath().replace('/','.').substring(1) + "." +
name;
}
else
{
m_root = true;
LoggingDescriptor logging =
m_creator.createLoggingDescriptor( m_config.getChild("logging"),
name );
- CategoriesDescriptor categories =
- m_creator.createCategoriesDescriptor( name,
m_config.getChild("categories") );
m_logging = new DefaultLoggerManager( logging );
+ m_base = name;
}
- DefaultContext ctx = new DefaultContext( m_context );
+ //
+ // Setup the logging categories for the kernel
+ //
+
+ CategoriesDescriptor categories =
+ m_creator.createCategoriesDescriptor( name,
m_config.getChild("categories") );
+ getLoggingManager().addCategories( m_base, categories );
+
+ //
+ // Create the kernel type manager.
+ // Create a context object container the logging manager and the
+ // categories to be applied relative to the manager's path, include
+ // the extension directives and classpath descriptor.
+ //
ExtensionsDescriptor extensions =
m_creator.createExtensionsDescriptor( m_config.getChild("extensions")
);
ClasspathDescriptor classpath =
m_creator.createClasspathDescriptor( m_config.getChild("classpath") );
- LoggingDescriptor loggingDescriptor =
- m_creator.createLoggingDescriptor( m_config.getChild("logging"), name
);
- CategoriesDescriptor categories =
- m_creator.createCategoriesDescriptor( name,
m_config.getChild("categories") );
- m_logger = getLoggingManager().getLoggerForCategory( m_path );
+ m_logger = getLoggingManager().getLoggerForCategory( m_base );
m_localLogger = m_logger.getChildLogger("kernel");
m_manager = new KernelManager( m_path );
m_manager.enableLogging( m_logger );
+ DefaultContext ctx = new DefaultContext( m_context );
ctx.put( KernelManager.LOGGING_KEY, m_logging );
- ctx.put( ContainerManager.CATEGORIES_DESCRIPTOR_KEY, categories );
ctx.put( ContainerManager.EXTENSIONS_DESCRIPTOR_KEY, extensions );
ctx.put( ContainerManager.CLASSPATH_DESCRIPTOR_KEY, classpath );
m_manager.contextualize( ctx );
m_manager.initialize();
Thread.currentThread().setContextClassLoader( m_manager );
-
-
getLogger().info("kernel established: " + name );
+
m_container = createContainer( config );
+ m_initialized = true;
+
+ getLogger().info("kernel initialization complete");
}
catch( Throwable e )
@@ -329,11 +350,6 @@
final String error = "kernel establishment failure";
throw new KernelException( error, e );
}
-
-
- while( !m_initialized )
- sleep();
-
}
/**
@@ -408,10 +424,10 @@
final ClasspathDescriptor classpath =
m_creator.createClasspathDescriptor( config.getChild("classpath") );
final ContainerManager manager =
- m_manager.createContainerManager( name, descriptor, classpath,
m_logger );
+ m_manager.createContainerManager( name, classpath );
//
- // populate the descriptor with the components it contains
+ // populate the container descriptor with the components it contains
//
final Configuration[] components = config.getChildren("component");
@@ -443,8 +459,8 @@
final DefaultContext context = new DefaultContext();
context.put( DefaultContainer.MANAGER_KEY, manager );
context.put( DefaultContainer.DESCRIPTOR_KEY, descriptor );
+ context.put( DefaultContainer.LOGGING_KEY, m_logging );
context.put( DefaultContainer.CONFIGURATIONS_KEY,
config.getChildren("container") );
- context.put( DefaultContainer.STATE_LISTENER_KEY, this );
context.makeReadOnly();
final DefaultContainer container = createContainerInstance( m_manager,
classname );
@@ -487,21 +503,6 @@
*/
public void start() throws Exception
{
- startup();
- }
-
- public void stop()
- {
- shutdown();
- }
-
- //=======================================================================
- // Controller
- //=======================================================================
-
-
- public void startup() throws Exception
- {
if( !m_initialized )
throw new IllegalStateException("not initialized");
if( m_stopped )
@@ -514,7 +515,8 @@
try
{
- m_container.startup();
+ m_container.start();
+ m_started = true;
}
catch( Throwable e )
{
@@ -523,17 +525,12 @@
throw new KernelException( error, e );
}
- getLogger().info("startup initiated");
-
- while( !m_started )
- sleep();
-
if( getLogger().isInfoEnabled() )
getLogger().info("started");
}
- public void shutdown()
- {
+ public void stop() throws Exception
+ {
if( !m_initialized )
throw new IllegalStateException("not initialized");
if( m_stopped )
@@ -541,15 +538,16 @@
if( !m_started )
throw new IllegalStateException("not started");
- m_container.shutdown();
- if( getLogger().isInfoEnabled() )
- getLogger().info("shutdown intiated");
-
- while( !m_stopped )
- sleep();
-
- if( getLogger().isInfoEnabled() )
- getLogger().info("stopped");
+ try
+ {
+ m_container.stop();
+ m_stopped = true;
+ }
+ catch( Throwable e )
+ {
+ final String error = "Unepected error while stopping root container.";
+ getLogger().warn( error, e );
+ }
}
//=======================================================================
@@ -565,57 +563,6 @@
if( m_container != null )
{
m_container.dispose();
- while( !m_disposed )
- sleep();
- }
- }
-
- //=======================================================================
- // StateListener
- // Listens to the state of the root container.
- //=======================================================================
-
- /**
- * Method invoked when the root container state changes.
- */
- public void stateChanged( StateEvent event )
- {
- int state = event.getState();
- switch( state )
- {
- case Container.INITIALIZED:
- m_initialized = true;
- getLogger().info("initilialized");
- try
- {
- verify();
- getLogger().info( "verified" );
- Logger export = getLogger().getChildLogger( "export" );
- if( export.isInfoEnabled() )
- {
- getLogger().info( "listing exportable resources" );
- Resource[] resources = getResources();
- for( int i=0; i<resources.length; i++ )
- {
- export.info( resources[i].getPath() );
- }
- }
- }
- catch( Throwable e )
- {
- getLogger().error("verification failure", e );
- m_container.dispose();
- }
- break;
- case Container.STARTED:
- m_started = true;
- break;
- case Container.STOPPED:
- m_stopped = true;
- break;
- case Container.DISPOSED:
- m_disposed = true;
- break;
}
}
@@ -630,7 +577,10 @@
public Resource[] getResources()
{
- return m_container.getResources();
+ synchronized( m_container )
+ {
+ return m_container.getResources();
+ }
}
/**
@@ -664,24 +614,4 @@
getLogger().debug("commencing assembly verification");
verifier.verifyAssembly( profiles );
}
-
- //=======================================================================
- // internals
- //=======================================================================
-
-
- /**
- * Internel utility to sleep a bit.
- */
- private void sleep()
- {
- try
- {
- Thread.currentThread().sleep( 100 );
- }
- catch( Throwable wakeup )
- {
- }
- }
-
}
1.12 +2 -2
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Kernel.java
Index: Kernel.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/Kernel.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Kernel.java 4 Aug 2002 06:43:20 -0000 1.11
+++ Kernel.java 8 Aug 2002 21:30:17 -0000 1.12
@@ -22,7 +22,7 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
* @version $Revision$ $Date$
*/
-public interface Kernel extends Controller
+public interface Kernel
{
/**
1.2 +2 -2
jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ContainerBuilder.java
Index: ContainerBuilder.java
===================================================================
RCS file:
/home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/builder/ContainerBuilder.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ContainerBuilder.java 8 Aug 2002 10:00:50 -0000 1.1
+++ ContainerBuilder.java 8 Aug 2002 21:30:18 -0000 1.2
@@ -19,7 +19,7 @@
import org.apache.excalibur.merlin.model.ContainerDescriptor;
/**
- * A ProfileBuilder is responsible for building {@link Profile}
+ * A ProfileBuilder is responsible for building {@link ContainerDescriptor}
* objects from Configuration objects.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephen McConnell</a>
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>