You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2003/01/09 04:59:39 UTC
cvs commit: avalon-sandbox/merlin/src/test/org/apache/avalon/playground StandardComponent.xinfo
mcconnell 2003/01/08 19:59:39
Modified: merlin kernel.xml
merlin/src/java/org/apache/avalon/merlin/block Block.java
DefaultBlock.java
merlin/src/java/org/apache/avalon/merlin/container
Container.java DefaultContainer.java
merlin/src/test/org/apache/avalon/playground
StandardComponent.xinfo
Added: merlin/src/java/org/apache/avalon/merlin/container
StateEvent.java StateListener.java
Log:
Addition of support for per-thread containers.
Revision Changes Path
1.12 +1 -1 avalon-sandbox/merlin/kernel.xml
Index: kernel.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/kernel.xml,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- kernel.xml 8 Jan 2003 20:57:48 -0000 1.11
+++ kernel.xml 9 Jan 2003 03:59:39 -0000 1.12
@@ -15,7 +15,7 @@
</logging>
<categories>
- <category name="/sys" priority="DEBUG"/>
+ <category name="/sys" priority="INFO"/>
</categories>
<!--
1.6 +26 -2 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java
Index: Block.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- Block.java 27 Dec 2002 16:38:54 -0000 1.5
+++ Block.java 9 Jan 2003 03:59:39 -0000 1.6
@@ -62,7 +62,31 @@
* @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
* @version $Revision$ $Date$
*/
-public interface Block extends Appliance, Container
+//public interface Block extends Appliance, Container
+public interface Block extends Appliance
{
static final String AVALON_BLOCK_KEY = "Avalon-Block";
+
+ /**
+ * Startup the block and startup all subsidiary blocks.
+ * @exception Exception if a startup error occurs
+ */
+ void startup() throws Exception;
+
+ /**
+ * Suspend the block and all subsidiary blocks.
+ */
+ void suspend();
+
+ /**
+ * Resume the block and all subsidiary blocks.
+ */
+ void resume();
+
+ /**
+ * Shutdown the block.
+ * @exception Exception if a shutdown error occurs
+ */
+ void shutdown() throws Exception;
+
}
1.11 +242 -14 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java
Index: DefaultBlock.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- DefaultBlock.java 7 Jan 2003 04:24:16 -0000 1.10
+++ DefaultBlock.java 9 Jan 2003 03:59:39 -0000 1.11
@@ -4,8 +4,9 @@
import java.io.File;
import java.io.IOException;
-import java.util.jar.JarFile;
import java.net.URL;
+import java.util.List;
+import java.util.ArrayList;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.jar.JarFile;
@@ -24,6 +25,7 @@
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.framework.activity.Disposable;
import org.apache.avalon.framework.context.Context;
import org.apache.avalon.framework.context.Contextualizable;
import org.apache.avalon.framework.context.ContextException;
@@ -33,6 +35,8 @@
import org.apache.avalon.merlin.container.DefaultContainer;
import org.apache.avalon.merlin.container.ContainerDescriptor;
import org.apache.avalon.merlin.container.Container;
+import org.apache.avalon.merlin.container.StateListener;
+import org.apache.avalon.merlin.container.StateEvent;
import org.apache.avalon.meta.info.Type;
import org.apache.avalon.meta.info.builder.XMLTypeCreator;
import org.apache.avalon.meta.info.StageDescriptor;
@@ -47,11 +51,11 @@
* responsible for the establishment of a containment heirachy that
* represents the implemetation model for the block.
*/
-public class DefaultBlock extends DefaultAppliance implements Block
+public class DefaultBlock extends DefaultAppliance implements Block, Runnable, StateListener
{
- //==============================================================
+ //-------------------------------------------------------------------------------
// static
- //==============================================================
+ //-------------------------------------------------------------------------------
public static final Attributes.Name BLOCK_PACKAGE = new Attributes.Name( "Block-Package" );
public static final Attributes.Name OLD_BLOCK_NAME = new Attributes.Name( "Block-Name" );
@@ -84,17 +88,52 @@
}
- //==============================================================
+ //-------------------------------------------------------------------------------
// state
- //==============================================================
+ //-------------------------------------------------------------------------------
+ /**
+ * The root container instance that this block is managing.
+ */
private Container m_container;
+ /**
+ * Flag holding the assembled state of the block.
+ */
private boolean m_assembled = false;
- //==============================================================
+ /**
+ * The thread in which we will run the container.
+ */
+ private Thread m_thread;
+
+ /**
+ * Flag holding the running state of the block.
+ */
+ private boolean m_running = false;
+
+ /**
+ * The container is managed as a thread under which the current state
+ * is recorded in the m_state state member.
+ */
+ private int m_state = StateEvent.UNKNOWN;
+
+ /**
+ * The thread periodically checks for state change requests enter in
+ * the m_action state member and attempts to bring the m_state value to
+ * be equal to the m_action value and once achieved goes off for a
+ * sleep.
+ */
+ private Integer m_action = new Integer( StateEvent.UNKNOWN );
+
+ /**
+ * An error raised by the managed container.
+ */
+ private BlockException m_error;
+
+ //-------------------------------------------------------------------------------
// constructor
- //==============================================================
+ //-------------------------------------------------------------------------------
public DefaultBlock(
EngineClassLoader engine, LifestyleService lifestyle, AssemblyService assembly,
@@ -102,11 +141,88 @@
throws ApplianceException
{
super( engine, lifestyle, assembly, context, system, logger );
+ m_thread = new Thread( this, super.getPath() );
+ m_thread.setContextClassLoader( engine );
+ m_thread.start();
}
- //==============================================================
- // Block
- //==============================================================
+ //-------------------------------------------------------------------------------
+ // Runnable
+ //-------------------------------------------------------------------------------
+
+ /**
+ * Starts the thread of execution for the block. This operation is
+ * invoked by the container constructor.
+ */
+ public void run()
+ {
+ if( !m_running )
+ {
+ m_running = true;
+ }
+
+ try
+ {
+
+ //
+ // while desired state of the hosted container is something
+ // other than DISPOSED, check if the desired state is different
+ // from the current state reported by the container, and if
+ // so initiate a container state change
+ //
+
+ while( m_action.intValue() < StateEvent.DISPOSED )
+ {
+ synchronized( m_action )
+ {
+ if( m_state != m_action.intValue() )
+ {
+ switch( m_action.intValue() )
+ {
+ case StateEvent.STARTED:
+ if( m_state == StateEvent.INITIALIZED )
+ {
+ m_container.startup();
+ }
+ else if( m_state == StateEvent.SUSPENDED )
+ {
+ m_container.resume();
+ }
+ break;
+ case StateEvent.SUSPENDED:
+ if( m_state == StateEvent.STARTED )
+ {
+ m_container.suspend();
+ }
+ break;
+ case StateEvent.STOPPED:
+ if( ( m_state == StateEvent.STARTED )
+ || ( m_state == StateEvent.SUSPENDED ) )
+ {
+ m_container.shutdown();
+ }
+ break;
+ }
+ }
+ }
+ sleep();
+ }
+ if( m_container instanceof Disposable )
+ {
+ ((Disposable)m_container).dispose();
+ }
+ }
+ catch( Throwable e )
+ {
+ final String error = "Unexpected error during container execution.";
+ m_error = new BlockException( error, e );
+ terminate();
+ }
+ }
+
+ //-------------------------------------------------------------------------------
+ // Appliance
+ //-------------------------------------------------------------------------------
/**
* Assemble the appliance. The implementation extends the default
@@ -135,6 +251,7 @@
{
m_assembled = true;
m_container = (Container) super.access();
+ m_container.addStateListener( this );
m_container.assemble();
}
catch( Throwable e )
@@ -151,6 +268,29 @@
*/
public void terminate()
{
+ synchronized( this )
+ {
+ if( m_error == null )
+ {
+ m_action = new Integer( StateEvent.DISPOSED );
+ while( ( m_state < StateEvent.DISPOSED ) && ( m_error == null ) )
+ {
+ sleep();
+ }
+ }
+ else
+ {
+ if( getLogger().isErrorEnabled() )
+ {
+ getLogger().error( "terminating due to container error", m_error );
+ }
+ if( m_container instanceof Disposable )
+ {
+ ((Disposable)m_container).dispose();
+ }
+ }
+ }
+
if( m_container != null )
{
release( m_container );
@@ -160,7 +300,7 @@
}
//-------------------------------------------------------------------------------
- // Container
+ // Block
//-------------------------------------------------------------------------------
/**
@@ -173,7 +313,56 @@
{
throw new IllegalStateException( "assembly" );
}
- m_container.startup();
+
+ synchronized( this )
+ {
+ m_action = new Integer( StateEvent.STARTED );
+ while( ( m_state < StateEvent.STARTED ) && ( m_error == null ) )
+ {
+ sleep();
+ }
+ if( m_error != null )
+ {
+ throw m_error;
+ }
+ }
+ }
+
+ /**
+ * Request for the container to suspend all subsidiary containers
+ * and all contained components.
+ */
+ public void suspend()
+ {
+ synchronized( this )
+ {
+ m_action = new Integer( StateEvent.SUSPENDED );
+ while( ( m_state < StateEvent.SUSPENDED ) && ( m_error == null ) )
+ {
+ sleep();
+ }
+ }
+ }
+
+ /**
+ * Request for the container to resume all subsidiary containers
+ * and all contained components.
+ */
+ public void resume()
+ {
+ if( m_state != StateEvent.SUSPENDED )
+ {
+ throw new IllegalStateException( "not-suspended." );
+ }
+
+ synchronized( this )
+ {
+ m_action = new Integer( StateEvent.STARTED );
+ while( ( m_state == StateEvent.SUSPENDED ) && ( m_error == null ) )
+ {
+ sleep();
+ }
+ }
}
/**
@@ -186,6 +375,45 @@
{
throw new IllegalStateException( "assembly" );
}
- m_container.shutdown();
+ synchronized( this )
+ {
+ m_action = new Integer( StateEvent.STOPPED );
+ while( ( m_state < StateEvent.STOPPED ) && ( m_error == null ) )
+ {
+ sleep();
+ }
+ if( m_error != null )
+ {
+ throw m_error;
+ }
+ }
+ }
+
+ /**
+ * Method invoked when a container state changes.
+ * @param event the state event
+ */
+ public void stateChanged( StateEvent event )
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug("state event: [" + event.getState() + "]" );
+ }
+ m_state = event.getState();
+ }
+
+ /**
+ * Internal utility to sleep a bit.
+ */
+ private void sleep()
+ {
+ try
+ {
+ Thread.currentThread().sleep( 100 );
+ }
+ catch( Throwable wakeup )
+ {
+ // return
+ }
}
}
1.4 +25 -1 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/Container.java
Index: Container.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/Container.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- Container.java 27 Dec 2002 16:41:06 -0000 1.3
+++ Container.java 9 Jan 2003 03:59:39 -0000 1.4
@@ -85,10 +85,34 @@
*/
void startup() throws Exception;
+ /**
+ * Request for the container to suspend all subsidiary containers
+ * and all contained components.
+ */
+ void suspend();
+
+ /**
+ * Request for the container to resume all subsidiary containers
+ * and all contained components.
+ */
+ void resume();
+
/**
* Shutdown all subsidiary containers and all components in this container.
* @exception Exception if a shutdown error occurs
*/
void shutdown() throws Exception;
+
+ /**
+ * Adds a <code>StateListener</code> to the container.
+ * @param listener the state listener to add
+ */
+ void addStateListener( StateListener listener );
+
+ /**
+ * Removes a <code>StateListener</code> from the container.
+ * @param listener the state listener to remove
+ */
+ void removeStateListener( StateListener listener );
}
1.12 +324 -57 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/DefaultContainer.java
Index: DefaultContainer.java
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/DefaultContainer.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- DefaultContainer.java 28 Dec 2002 08:06:43 -0000 1.11
+++ DefaultContainer.java 9 Jan 2003 03:59:39 -0000 1.12
@@ -140,6 +140,17 @@
*/
private Configuration m_targets;
+ /**
+ * State event listener list.
+ */
+ private List m_listeners = new ArrayList();
+
+ /**
+ * The container is managed as a thread under which the current state
+ * is recorded in the m_state state member.
+ */
+ private int m_state = StateEvent.UNKNOWN;
+
//==============================================================
// Contextualizable
//==============================================================
@@ -193,7 +204,6 @@
if( getLogger().isDebugEnabled() )
{
getLogger().debug( "initialization: " + m_path + " (" + profiles.length + ")" );
- //getLogger().debug( "configuration array:\n" + ConfigurationUtil.list( m_targets ) );
}
for( int i=0; i<profiles.length; i++ )
@@ -269,13 +279,199 @@
*/
public void assemble() throws AssemblyException
{
+ if( m_state < StateEvent.INITIALIZED )
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "assembly" );
+ }
+
+ assembleComponents();
+ assembleContainers();
+
+ m_state = StateEvent.INITIALIZED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.INITIALIZED ) );
+ }
+ }
+
+ /**
+ * Startup the components in this container and startup all subsidiary
+ * containers.
+ * @exception Exception if a startup error occurs
+ */
+ public void startup() throws Exception
+ {
+ if( m_state < StateEvent.INITIALIZED )
+ {
+ throw new IllegalStateException(
+ "Container has not been initialized." );
+ }
+
+ if( m_state == StateEvent.STARTED )
+ {
+ return;
+ }
+
+ if( m_state > StateEvent.STARTED )
+ {
+ throw new IllegalStateException(
+ "Container has already passed through start phase." );
+ }
+
if( getLogger().isDebugEnabled() )
{
- getLogger().debug( "assembly" );
+ getLogger().debug( "startup" );
}
-
- assembleComponents();
- assembleContainers();
+
+ startupComponents();
+ startupContainers();
+
+ m_state = StateEvent.STARTED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.STARTED ) );
+ }
+
+ /**
+ * Request for the container to suspend all subsidiary containers
+ * and all contained components.
+ */
+ public void suspend()
+ {
+ if( m_state < StateEvent.INITIALIZED )
+ {
+ throw new IllegalStateException(
+ "Container has not been initialized." );
+ }
+
+ if( m_state == StateEvent.SUSPENDED )
+ {
+ return;
+ }
+
+ if( m_state > StateEvent.STOPPED )
+ {
+ throw new IllegalStateException(
+ "Container has been stopped." );
+ }
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "container suspension" );
+ }
+
+ suspendContainers();
+ suspendComponents();
+
+ getLogger().debug( "container suspension complete" );
+ m_state = StateEvent.SUSPENDED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.SUSPENDED ) );
+ }
+
+ /**
+ * Request for the container to resume all subsidiary containers
+ * and all contained components.
+ */
+ public void resume()
+ {
+ if( m_state != StateEvent.SUSPENDED )
+ {
+ throw new IllegalStateException(
+ "Container is not suspended." );
+ }
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "container resuming" );
+ }
+
+ //
+ // resume subsidiary containers
+ //
+
+ resumeComponents();
+ resumeContainers();
+
+ getLogger().debug( "container resumption complete" );
+ m_state = StateEvent.STARTED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.STARTED ) );
+ }
+
+
+ /**
+ * Shutdown all subsidiary containers and all components in this container.
+ * @exception Exception if a shutdown error occurs
+ */
+ public void shutdown() throws Exception
+ {
+ if( m_state < StateEvent.STARTED )
+ {
+ return;
+ }
+
+ if( m_state == StateEvent.STOPPED )
+ {
+ return;
+ }
+
+ if( m_state > StateEvent.STOPPED )
+ {
+ throw new IllegalStateException( "Already stopped." );
+ }
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "shutdown" );
+ }
+
+ //
+ // shutdown all of the nested containers before stopping
+ // the components in this container
+ //
+
+ shutdownContainers();
+ shutdownComponents();
+
+ m_state = StateEvent.STOPPED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.STOPPED ) );
+ }
+
+ /**
+ * Disposal of the container.
+ */
+ public void dispose()
+ {
+ if( m_state == StateEvent.DISPOSED )
+ {
+ return;
+ }
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "disposal" );
+ }
+
+ disposeContainers();
+ disposeComponents();
+
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "cleanup" );
+ }
+
+ m_state = StateEvent.DISPOSED;
+ fireStateChange( new StateEvent( this, m_descriptor.getName(), StateEvent.DISPOSED, null ) );
+
+ m_engine = null;
+ m_descriptor = null;
+ m_componentMap.clear();
+ m_components.clear();
+ m_componentMap = null;
+ m_components = null;
+ m_containerMap.clear();
+ m_containers.clear();
+ m_containerMap = null;
+ m_containers = null;
+ m_partition = null;
+ m_path = null;
}
/**
@@ -308,21 +504,6 @@
}
/**
- * Startup the components in this container and startup all subsidiary
- * containers.
- * @exception Exception if a startup error occurs
- */
- public void startup() throws Exception
- {
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "startup" );
- }
- startupComponents();
- startupContainers();
- }
-
- /**
* Startup the components in this container.
* @exception Exception if a startup error occurs
*/
@@ -383,17 +564,75 @@
}
/**
- * Shutdown all subsidiary containers and all components in this container.
- * @exception Exception if a shutdown error occurs
+ * Startup the components in this container.
+ * @exception Exception if a startup error occurs
*/
- public void shutdown() throws Exception
+ private void suspendComponents()
{
- if( getLogger().isDebugEnabled() )
+ // not implemented - more thinking needed about the
+ // concepts of deployment strategies
+ }
+
+ /**
+ * Startup the containers in this container.
+ * @exception Exception if a startup error occurs
+ */
+ private void suspendContainers()
+ {
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
{
- getLogger().debug( "shutdown" );
+ Appliance appliance = (Appliance) iterator.next();
+ Container container = (Container) m_containerMap.get( appliance );
+ try
+ {
+ container.suspend();
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Could not suspend a subsidiary container: "
+ + appliance.getName()
+ + " in container: " + this;
+ throw new ContainerRuntimeException( error, e );
+ }
+ }
+ }
+
+ /**
+ * Startup the components in this container.
+ * @exception Exception if a startup error occurs
+ */
+ private void resumeComponents()
+ {
+ // not implemented - more thinking needed about the
+ // concepts of deployment strategies
+ }
+
+ /**
+ * Startup the containers in this container.
+ * @exception Exception if a startup error occurs
+ */
+ private void resumeContainers()
+ {
+ Iterator iterator = m_containers.iterator();
+ while( iterator.hasNext() )
+ {
+ Appliance appliance = (Appliance) iterator.next();
+ Container container = (Container) m_containerMap.get( appliance );
+ try
+ {
+ container.resume();
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Could not resume of a subsidiary container: "
+ + appliance.getName()
+ + " in container: " + this;
+ throw new ContainerRuntimeException( error, e );
+ }
}
- shutdownContainers();
- shutdownComponents();
}
/**
@@ -454,33 +693,6 @@
}
/**
- * Disposal of the container.
- */
- public void dispose()
- {
- if( getLogger().isDebugEnabled() )
- {
- getLogger().debug( "disposal" );
- }
-
- disposeContainers();
- disposeComponents();
-
- m_engine = null;
- m_descriptor = null;
- m_componentMap.clear();
- m_components.clear();
- m_componentMap = null;
- m_components = null;
- m_containerMap.clear();
- m_containers.clear();
- m_containerMap = null;
- m_containers = null;
- m_partition = null;
- m_path = null;
- }
-
- /**
* Release all of the components in this container.
*/
private void disposeComponents()
@@ -527,9 +739,64 @@
{
final String error =
"Could not shutdown a subsidiary container: "
- + appliance.getName()
- + " in container: " + this;
+ + appliance.getName();
getLogger().warn( error, e );
+ }
+ }
+ }
+
+ /**
+ * Adds a <code>StateListener</code>.
+ * @param listener the state listener to add
+ */
+ public void addStateListener( StateListener listener )
+ {
+ synchronized( m_listeners )
+ {
+ m_listeners.add( listener );
+ }
+ }
+
+ /**
+ * Removes a <code>StateListener</code>.
+ * @param listener the state listener to remove
+ */
+ public void removeStateListener( StateListener listener )
+ {
+ synchronized( m_listeners )
+ {
+ m_listeners.remove( listener );
+ }
+ }
+
+ /**
+ * Notifies all state listeners of a change in the state of the container.
+ * @param event the state event.
+ */
+ protected void fireStateChange( StateEvent event )
+ {
+ synchronized( m_listeners )
+ {
+ StateListener[] listeners =
+ (StateListener[])m_listeners.toArray( new StateListener[ 0 ] );
+ for( int i = 0; i < listeners.length; i++ )
+ {
+ StateListener listener = listeners[ i ];
+ try
+ {
+ listener.stateChanged( event );
+ }
+ catch( Exception e )
+ {
+ m_listeners.remove( listener );
+ final String warning =
+ "State listener raised on error on notification. Removing listener: "
+ + listener;
+ if( getLogger().isWarnEnabled() )
+ {
+ getLogger().warn( warning );
+ }
+ }
}
}
}
1.1 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/StateEvent.java
Index: StateEvent.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software
* itself, if and wherever such third-party acknowledgments
* normally appear.
*
* 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
* must not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.avalon.merlin.container;
import java.util.EventObject;
/**
* The <code>StateEvent</code> is an event raised by a component
* signally a change in state.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2003/01/09 03:59:39 $
*/
public class StateEvent extends EventObject
{
//============================================================
// static
//============================================================
/**
* Static state enumeration value indicating that the state of a container is unknown.
*/
public static final int UNKNOWN = 0;
/**
* Static state enumeration value indicating that a container has been initialized,
* all of its subsidiary containers have been initialized, and all component profiles
* have been assembled.
*/
public static final int INITIALIZED = 1;
/**
* Static state enumeration value indicating that a container has completed
* lifecycle processing on all components requesting startup establishment.
*/
public static final int STARTED = 2;
/**
* Static state enumeration value indicating that a container has been suspended.
*/
public 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.
*/
public static final int STOPPED = 4;
/**
* Static state enumeration value indicating that a container and all
* subsidiary containers have been disposed of.
*/
public static final int DISPOSED = 5;
//============================================================
// state
//============================================================
/**
* Container state.
*/
private final int m_state;
/**
* Error condition
*/
private Throwable m_error;
/**
* The name of the container.
*/
private String m_name;
//============================================================
// constructor
//============================================================
/**
* Creation of a new StateEvent.
*
* @param source the source container
* @param name the name of the soource container
* @param state int value of (@link #INITIALIZED}, {@link #STARTED},
* {@link #SUSPENDED}, {@link #STOPPED} or {@link #DISPOSED}
*/
public StateEvent( Object source, String name, int state )
{
this( source, name, state, null );
}
/**
* Creation of a new StateEvent.
*
* @param source the source container
* @param name the name of the soource container
* @param state int value of (@link #INITIALIZED}, {@link #STARTED},
* {@link #STOPPED} or {@link #DISPOSED}
* @param error an error condition triggering the state change
*/
public StateEvent( Object source, String name, int state, Throwable error )
{
super( source );
m_state = state;
m_name = name;
m_error = error;
}
//============================================================
// StateEvent
//============================================================
/**
* Returns the name of the container raising the event.
* @return the container name
*/
public String getName()
{
return m_name;
}
/**
* Returns the state that the component has raised inidicating
* that the component has completed transitioning to that state.
* @return the state
*/
public int getState()
{
return m_state;
}
/**
* Returns a throwable causing the state change. This is normally a
* null value. If not null, the transition was a result of an error
* condition.
* @return the error condition
*/
public Throwable getError()
{
return m_error;
}
}
1.1 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/StateListener.java
Index: StateListener.java
===================================================================
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software
* itself, if and wherever such third-party acknowledgments
* normally appear.
*
* 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
* must not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.avalon.merlin.container;
/**
* A <code>StateListener</code> listens to <code>StateEvent</code> events.
* @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
* @version $Revision: 1.1 $ $Date: 2003/01/09 03:59:39 $
*/
public interface StateListener
{
/**
* Method invoked when a container state changes.
* @param event the state event
*/
void stateChanged( StateEvent event );
}
1.6 +1 -1 avalon-sandbox/merlin/src/test/org/apache/avalon/playground/StandardComponent.xinfo
Index: StandardComponent.xinfo
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/src/test/org/apache/avalon/playground/StandardComponent.xinfo,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- StandardComponent.xinfo 20 Dec 2002 11:58:01 -0000 1.5
+++ StandardComponent.xinfo 9 Jan 2003 03:59:39 -0000 1.6
@@ -29,7 +29,7 @@
<context type="org.apache.avalon.playground.StandardContext">
<attributes>
- <attribute key="urn:assembly:lifecycle.context.extension"
+ <attribute key="urn:assembly:lifecycle.context.strategy"
value="org.apache.avalon.playground.Contextualizable"/>
</attributes>
</context>
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>