notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
svn commit: r2308 - in development/main/metro: composition/control/src/main/net/dpml/composition/control composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test/net/dpml/test state/api/src/main/net/dpml/state state/impl/src/main/net/dpml/state/impl state/impl/src/test/net/dpml/state/impl
- From: mcconnell AT dpml.net
- To: notify-dpml AT lists.ibiblio.org
- Subject: svn commit: r2308 - in development/main/metro: composition/control/src/main/net/dpml/composition/control composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test/net/dpml/test state/api/src/main/net/dpml/state state/impl/src/main/net/dpml/state/impl state/impl/src/test/net/dpml/state/impl
- Date: Mon, 18 Apr 2005 15:33:40 -0400
Author: mcconnell AT dpml.net
Date: Mon Apr 18 15:33:37 2005
New Revision: 2308
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/StateManagerInvocationHandler.java
development/main/metro/composition/testing/activity/src/main/net/dpml/test/Component.java
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ComponentTestCase.java
development/main/metro/state/api/src/main/net/dpml/state/StateManager.java
development/main/metro/state/api/src/main/net/dpml/state/Transition.java
development/main/metro/state/impl/src/main/net/dpml/state/impl/AbstractStateManager.java
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultState.java
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultTransition.java
development/main/metro/state/impl/src/test/net/dpml/state/impl/DefaultStateTestCase.java
Log:
Improve the state management code in terms of how initialization and
temrination is handled.
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/StateManagerInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/StateManagerInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/StateManagerInvocationHandler.java
Mon Apr 18 15:33:37 2005
@@ -262,7 +262,7 @@
return AVALIABLE;
}
- public void apply( String key )
+ public boolean apply( String key )
{
throw new NoSuchTransitionException( key );
}
Modified:
development/main/metro/composition/testing/activity/src/main/net/dpml/test/Component.java
==============================================================================
---
development/main/metro/composition/testing/activity/src/main/net/dpml/test/Component.java
(original)
+++
development/main/metro/composition/testing/activity/src/main/net/dpml/test/Component.java
Mon Apr 18 15:33:37 2005
@@ -124,29 +124,41 @@
//
DefaultState root = new DefaultState();
- DefaultState initialized = root.addInitialState( "initialized" );
+ DefaultState initialized = root.addState( "initialized" );
DefaultState available = root.addState( "available" );
DefaultState started = available.addState( "started" );
DefaultState stopped = available.addState( "stopped" );
DefaultState terminated = root.addTerminalState( "terminated" );
//
- // create the operations and add then under transitions
- // (currently declaring method based execution because this is the
- // only strategy implementated but the idea is to support registered
- // handlers and/or delegation to identified parts)
+ // create the handler declarations and add then under transitions
+ // (we are declaring method based execution because this is the
+ // only strategy currently implementated but the idea is to support
+ // registered handlers and/or delegation to identified parts)
//
try
{
+ URI initialize = new URI( "method:null" );
URI terminate = new URI( "method:terminate" );
URI start = new URI( "method:start" );
URI stop = new URI( "method:stop" );
- root.addTerminatingTransition( "terminate", terminate,
terminated );
+ //
+ // add system transitions dealing with initilization and
+ // termination
+ //
+
+ root.addTerminatingTransition( terminate, terminated );
+ root.addInitializingTransition( initialize, initialized );
+ started.addTerminatingTransition( stop, stopped );
+
+ //
+ // add user (application) transitions
+ //
+
initialized.addTransition( "start", start, started );
started.addTransition( "stop", stop, stopped );
- started.addTerminatingTransition( "terminate", stop, stopped );
stopped.addTransition( "start", start, started );
}
catch( URISyntaxException e )
Modified:
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ComponentTestCase.java
==============================================================================
---
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ComponentTestCase.java
(original)
+++
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ComponentTestCase.java
Mon Apr 18 15:33:37 2005
@@ -61,7 +61,7 @@
{
String name = transitions[i];
Transition transition = state.getTransition( name );
- if( false == transition.isTerminating() )
+ if( transition.isUserTransition() )
{
manager.apply( name );
break;
Modified:
development/main/metro/state/api/src/main/net/dpml/state/StateManager.java
==============================================================================
---
development/main/metro/state/api/src/main/net/dpml/state/StateManager.java
(original)
+++
development/main/metro/state/api/src/main/net/dpml/state/StateManager.java
Mon Apr 18 15:33:37 2005
@@ -46,7 +46,8 @@
* Applies a state transition identified by a supplied transition key.
*
* @param key the key identifying the transition to apply to the
component's controller
+ * @return TRUE of the transition was applied
* @exception if a transition error occurs
*/
- void apply( String key ) throws Exception;
+ boolean apply( String key ) throws Exception;
}
Modified:
development/main/metro/state/api/src/main/net/dpml/state/Transition.java
==============================================================================
--- development/main/metro/state/api/src/main/net/dpml/state/Transition.java
(original)
+++ development/main/metro/state/api/src/main/net/dpml/state/Transition.java
Mon Apr 18 15:33:37 2005
@@ -19,8 +19,8 @@
package net.dpml.state;
/**
- * The State interface is an interface representing an immutable state of
- * a component instance.
+ * The Transition interface delcares the target state and system or user
+ * mode in which this transition exists.
*
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
*/
@@ -33,9 +33,16 @@
State getTargetState();
/**
- * Return true if this transition can participate in a termination.
- * @return the transition names
- */
- boolean isTerminating();
+ * Returns TRUE if the transition is a system transition.
+ *
+ * @return TRUE if system transition
+ */
+ boolean isSystemTransition();
+ /**
+ * Returns TRUE if the transition is a user transition.
+ *
+ * @return TRUE if user transition
+ */
+ boolean isUserTransition();
}
Modified:
development/main/metro/state/impl/src/main/net/dpml/state/impl/AbstractStateManager.java
==============================================================================
---
development/main/metro/state/impl/src/main/net/dpml/state/impl/AbstractStateManager.java
(original)
+++
development/main/metro/state/impl/src/main/net/dpml/state/impl/AbstractStateManager.java
Mon Apr 18 15:33:37 2005
@@ -106,13 +106,23 @@
*/
public synchronized void initialize() throws Exception
{
- try
+ m_state = getStateModel();
+ if( m_state.isTerminal() )
{
- m_state = getStateModel().getInitialState();
+ return;
}
- catch( Throwable e )
+
+ boolean flag = true;
+ while( flag )
{
- m_state = getStateModel();
+ try
+ {
+ flag = apply( "initialize" );
+ }
+ catch( NoSuchTransitionException e )
+ {
+ flag = false;
+ }
}
}
@@ -154,27 +164,36 @@
* current current state and all listeners will be notified of a state
change.
*
* @param key the transition key
+ * @return TRUE if the transition was executed
* @exception if a error occurs in transition execution
*/
- public void apply( String key ) throws Exception
+ public boolean apply( String key ) throws Exception
{
DefaultState state = getCurrentState();
DefaultTransition transition = state.getNamedTransition( key );
Object handler = transition.getHandler();
DefaultState target = transition.getTransitionTarget();
- if( getLogger().isLoggable( Level.FINE ) )
+ if( state.equals( target ) )
+ {
+ return false;
+ }
+ else
{
- final String message =
- "applying "
- + handler.toString()
- + "' to '"
- + state.getName()
- + "'";
- getLogger().fine( message );
- }
- Logger logger = getLogger();
- execute( handler, state, target, logger );
- setState( target );
+ if( getLogger().isLoggable( Level.FINE ) )
+ {
+ final String message =
+ "applying "
+ + handler.toString()
+ + "' to '"
+ + state.getName()
+ + "'";
+ getLogger().fine( message );
+ }
+ Logger logger = getLogger();
+ execute( handler, state, target, logger );
+ setState( target );
+ return true;
+ }
}
private void execute( Object handler, State state, State target, Logger
logger ) throws Exception
@@ -205,12 +224,19 @@
// invoke the named method on the component instance
//
- Class c = m_instance.getClass();
String spec = uri.getSchemeSpecificPart();
- Method method = locateMethod( c, spec );
- Class[] parameters = method.getParameterTypes();
- Object[] args = resolveArguments( parameters, state,
target, logger );
- method.invoke( m_instance, args );
+ if( "null".equals( spec ) )
+ {
+ return;
+ }
+ else
+ {
+ Class c = m_instance.getClass();
+ Method method = locateMethod( c, spec );
+ Class[] parameters = method.getParameterTypes();
+ Object[] args = resolveArguments( parameters, state,
target, logger );
+ method.invoke( m_instance, args );
+ }
}
else
{
Modified:
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultState.java
==============================================================================
---
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultState.java
(original)
+++
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultState.java
Mon Apr 18 15:33:37 2005
@@ -45,7 +45,6 @@
private final DefaultState m_parent;
private final boolean m_terminal;
- private DefaultState m_initial;
private final Map m_transitions = new Hashtable();
private final Map m_states = new Hashtable();
private final State m_proxy;
@@ -65,10 +64,6 @@
public DefaultState( boolean terminal )
{
this( null, "root", terminal );
- if( terminal )
- {
- m_initial = this;
- }
}
/**
@@ -119,19 +114,6 @@
}
/**
- * Return TRUE if this state is the initial state. A state graph may have
- * only one initial state. During ionitialization of a StateManger, the
- * AbstractStatemanager implementation will attempt to locate the initial
- * state and assign it as the current state.
- *
- * @return true if this state is the initial state
- */
- protected boolean isInitial()
- {
- return this.equals( getInitialState() );
- }
-
- /**
* Return the terminal status of this state. If a state is termin if
cannot
* contain sub-states or transitions.
*
@@ -143,27 +125,6 @@
}
/**
- * Return the inital state is the state graph.
- *
- * @return the initial state
- * @exception IllegalStateException if the inital state has not been
declared
- */
- public DefaultState getInitialState()
- {
- if( null != m_parent )
- {
- return m_parent.getInitialState();
- }
- else if( null == m_initial )
- {
- final String error =
- "Initial state has not been declared.";
- throw new IllegalStateException( error );
- }
- return m_initial;
- }
-
- /**
* Returns an array of transtion names declared in this state and all
* parent states.
*
@@ -200,35 +161,7 @@
*/
public DefaultState addState( String key )
{
- return addState( this, key, false, false );
- }
-
- /**
- * Add a new initial sub-state to the set of states contained within this
- * state. If the supplied key is not unique within the scope of the graph
- * an exception will be thrown. If the graph's initial state has already
been
- * delcared an exception will be thrown.
- *
- * @param key the key identifying the new state
- * @return the created state
- */
- public DefaultState addInitialState( String key )
- {
- return addState( this, key, true, false );
- }
-
- /**
- * Add a new initial terminal sub-state to the set of states contained
within this
- * state. If the supplied key is not unique within the scope of the graph
- * an exception will be thrown. If the graph's initial state has already
been
- * delcared an exception will be thrown.
- *
- * @param key the key identifying the new state
- * @return the created state
- */
- public DefaultState addInitialTerminalState( String key )
- {
- return addState( this, key, true, true );
+ return addState( this, key, false );
}
/**
@@ -241,7 +174,7 @@
*/
public DefaultState addTerminalState( String key )
{
- return addState( this, key, false, true );
+ return addState( this, key, true );
}
/**
@@ -251,7 +184,6 @@
*
* @param parent the enclosing state
* @param key the key identifying the new state
- * @param initial true if this state is to be assinged as the default
initial state
* @param terminal true if this is a terminal state
* @return the created state
* @exception IllegalStateException if the parent state is a terminal
state
@@ -259,11 +191,11 @@
* @exception IllegalArgumentException if the initial parameter is true
and an initial
* state has already beeen declared
*/
- private DefaultState addState( DefaultState parent, String key, boolean
initial, boolean terminal )
+ private DefaultState addState( DefaultState parent, String key, boolean
terminal )
{
if( m_parent != null )
{
- return m_parent.addState( parent, key, initial, terminal );
+ return m_parent.addState( parent, key, terminal );
}
else
{
@@ -282,22 +214,8 @@
}
else
{
- if( initial )
- {
- if( m_initial != null )
- {
- final String error =
- "Initial state already assigned."
- + "\nInitial: " + m_initial.getName();
- throw new IllegalArgumentException( error );
- }
- }
DefaultState state = new DefaultState( parent, key, terminal
);
m_states.put( key, state );
- if( initial )
- {
- m_initial = state;
- }
return state;
}
}
@@ -380,45 +298,67 @@
}
/**
- * Add a transition to the state. Transition keys are unique within the
scope
- * of the state under which the transition is assigned. Transitions with
the
- * same name as a transition within a parent state will take precedence
when
- * selcting transitions.
+ * A terminating transition is transition with the reserver name
'terminate'.
+ * Terminating transitions are the same as classic transition and subject
to
+ * the same restrictions concenring name scoping (i.e. at most one
transition
+ * named 'terminate' may be assigned to a particular state). A
terminating
+ * transition within the scope of the current state chain will be fired
automatically
+ * in the event of a request to the state manager for manager
termination. If the
+ * result of the application of the teerminal transition is a state
change to a
+ * non-terminal state, the state manager will attempt to locate and apply
terminal
+ * transitions until either no terminating traistion is found or a
terminal state
+ * is reached.
*
- * @param key the transition key
- * @param handler the object to be assinged as the handler of the
transition action
+ * @param handler the object to be assigned as the handler of the
transition action
* @param target the transition target state
*/
- public void addTransition( String key, Object handler, DefaultState
target )
+ public void addTerminatingTransition( Object handler, DefaultState
target )
{
- addTransition( key, handler, target, false );
+ addTransition( "terminate", handler, target, true );
}
/**
- * Add a terminating transition to the state. Transition keys are unique
within the scope
+ * A initializing transition is transition with the reserver name
'initialize'.
+ * Initializing transitions are the same as classic transition and
subject to
+ * the same restrictions concerning name scoping (i.e. at most one
transition
+ * named 'initialize' may be assigned to a particular state). An
initializing
+ * transition within the scope of the current state chain will be fired
automatically
+ * in the event of a request to the state manager for manager
initialization. If the
+ * result of the application of the initialization transition is a state
change to a
+ * non-terminal state, the state manager will attempt to locate and apply
initiazation
+ * transitions until no further initilizations transitions are reachable.
+ *
+ * @param handler the object to be assigned as the handler of the
transition action
+ * @param target the transition target state
+ */
+ public void addInitializingTransition( Object handler, DefaultState
target )
+ {
+ addTransition( "initialize", handler, target, true );
+ }
+
+ /**
+ * Add a transition to the state. Transition keys are unique within the
scope
* of the state under which the transition is assigned. Transitions with
the
* same name as a transition within a parent state will take precedence
when
- * selcting transitions. Terminating transitions are a class of
transition that
- * contribute to the termination of a system and may be applied
automatically by the
- * AbstractStateManager following a termination request by a controlling
system.
+ * selcting transitions.
*
* @param key the transition key
* @param handler the object to be assinged as the handler of the
transition action
* @param target the transition target state
*/
- public void addTerminatingTransition( String key, Object handler,
DefaultState target )
+ public void addTransition( String key, Object handler, DefaultState
target )
{
- addTransition( key, handler, target, true );
+ addTransition( key, handler, target, false );
}
/**
- * Internal operation to add a new transtion to this state.
+ * Internal function to add a transition to the state.
+ *
* @param key the transition key
- * @param handler the transition handler
- * @param target the transition target
- * @param terminating TRUE if this is a terminating transition
+ * @param handler the object to be assinged as the handler of the
transition action
+ * @param target the transition target state
*/
- private void addTransition( String key, Object handler, DefaultState
target, boolean terminating )
+ private void addTransition( String key, Object handler, DefaultState
target, boolean system )
{
if( isTerminal() )
{
@@ -430,12 +370,22 @@
{
throw new DuplicateKeyException( key );
}
- DefaultTransition transition = new DefaultTransition( handler,
target, terminating );
+ if( false == system )
+ {
+ if( "initialize".equals( key ) || "terminate".equals( key ) )
+ {
+ final String error =
+ "The supplied key is a reserved transition name."
+ + "\nKey: " + key;
+ throw new IllegalArgumentException( error );
+ }
+ }
+ DefaultTransition transition = new DefaultTransition( handler,
target, system );
m_transitions.put( key, transition );
}
/**
- * Return the fisrt transition matching the supplied key in this state
graph. The search
+ * Return the first transition matching the supplied key in this state
graph. The search
* for a matching transition proceeds from the local state upwards uptil
the root state is
* reached unless a local or intermidiate transition matches the supplied
key.
*
@@ -565,15 +515,10 @@
String name = state.getName();
buffer.append( "\n" + offset );
buffer.append( "state: " + name );
- if( state.isInitial() )
- {
- buffer.append( " (initial)" );
- }
if( state.isTerminal() )
{
buffer.append( " (terminal)" );
}
-
String[] transitions = state.getLocalTransitionNames();
for( int i=0; i<transitions.length; i++ )
{
@@ -581,6 +526,14 @@
DefaultTransition transition = state.getNamedTransition( t );
State target = transition.getTargetState();
buffer.append( "\n " + offset + "transition:" + t + " -->
state:" + target.getName() );
+ if( "initialize".equals( t ) )
+ {
+ buffer.append( " (system initializer)" );
+ }
+ else if( "terminate".equals( t ) )
+ {
+ buffer.append( " (system terminator)" );
+ }
}
DefaultState[] states = state.getStates();
Modified:
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultTransition.java
==============================================================================
---
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultTransition.java
(original)
+++
development/main/metro/state/impl/src/main/net/dpml/state/impl/DefaultTransition.java
Mon Apr 18 15:33:37 2005
@@ -27,8 +27,8 @@
import net.dpml.state.Transition;
/**
- * The State interface is an interface representing an immutable state of
- * a component instance.
+ * The DefualtTransition class associated a transition handler and a target
+ * state.
*
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
*/
@@ -36,32 +36,59 @@
{
private final DefaultState m_target;
private final Object m_handler;
- private final boolean m_terminating;
+ private final boolean m_system;
- protected DefaultTransition( Object handler, DefaultState target,
boolean terminating )
+ protected DefaultTransition( Object handler, DefaultState target,
boolean system )
{
m_handler = handler;
m_target = target;
- m_terminating = terminating;
+ m_system = system;
}
+ /**
+ * Return the handler associated with this transition.
+ * @return the transition handler
+ */
public Object getHandler()
{
return m_handler;
}
+ /**
+ * Return the target of this transition.
+ * @return the transition target
+ */
public State getTargetState()
{
return getTransitionTarget();
}
- public DefaultState getTransitionTarget()
+ /**
+ * Returns TRUE if the transition is a system transition.
+ *
+ * @return TRUE if system transition
+ */
+ public boolean isSystemTransition()
{
- return m_target;
+ return m_system;
}
- public boolean isTerminating()
+ /**
+ * Returns TRUE if the transition is a user transition.
+ *
+ * @return TRUE if user transition
+ */
+ public boolean isUserTransition()
{
- return m_terminating;
+ return !isSystemTransition();
+ }
+
+ /**
+ * Return the target of this transition.
+ * @return the transition target
+ */
+ public DefaultState getTransitionTarget()
+ {
+ return m_target;
}
}
Modified:
development/main/metro/state/impl/src/test/net/dpml/state/impl/DefaultStateTestCase.java
==============================================================================
---
development/main/metro/state/impl/src/test/net/dpml/state/impl/DefaultStateTestCase.java
(original)
+++
development/main/metro/state/impl/src/test/net/dpml/state/impl/DefaultStateTestCase.java
Mon Apr 18 15:33:37 2005
@@ -40,7 +40,7 @@
//
DefaultState root = new DefaultState();
- DefaultState initialized = root.addInitialState( "initialized" );
+ DefaultState initialized = root.addState( "initialized" );
DefaultState available = root.addState( "available" );
DefaultState started = available.addState( "started" );
DefaultState stopped = available.addState( "stopped" );
@@ -50,10 +50,14 @@
// create the operations and add then under transitions
//
+ Operation initialize = new Operation( "initialize" );
Operation terminate = new Operation( "terminate" );
Operation start = new Operation( "start" );
Operation stop = new Operation( "stop" );
- root.addTerminatingTransition( "terminate", terminate, terminated );
+
+ root.addInitializingTransition( initialize, initialized );
+ root.addTerminatingTransition( terminate, terminated );
+
initialized.addTransition( "start", start, started );
started.addTransition( "stop", stop, stopped );
stopped.addTransition( "start", start, started );
- svn commit: r2308 - in development/main/metro: composition/control/src/main/net/dpml/composition/control composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test/net/dpml/test state/api/src/main/net/dpml/state state/impl/src/main/net/dpml/state/impl state/impl/src/test/net/dpml/state/impl, mcconnell, 04/18/2005
Archive powered by MHonArc 2.6.24.