Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2428 - in development/main/metro/composition/control/src/main/net/dpml/composition: control model

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: mcconnell AT dpml.net
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: svn commit: r2428 - in development/main/metro/composition/control/src/main/net/dpml/composition: control model
  • Date: Wed, 27 Apr 2005 15:07:34 -0400

Author: mcconnell AT dpml.net
Date: Wed Apr 27 15:07:29 2005
New Revision: 2428

Modified:

development/main/metro/composition/control/src/main/net/dpml/composition/control/ComponentController.java

development/main/metro/composition/control/src/main/net/dpml/composition/model/ComponentModel.java
Log:
fix a conflict in svn and update the component model/control separation stuff

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ComponentController.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ComponentController.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ComponentController.java
Wed Apr 27 15:07:29 2005
@@ -18,39 +18,47 @@

package net.dpml.composition.control;

-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.net.URI;
-import java.net.URISyntaxException;
+import java.util.Map;
import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.TreeMap;
+import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
+import java.util.LinkedList;
+import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Logger;
+import java.util.logging.Level;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Observable;

import javax.swing.event.ChangeEvent;

-import net.dpml.activity.Executable;
-import net.dpml.activity.Startable;
-import net.dpml.composition.event.AvailabilityEvent;
-import net.dpml.composition.model.ComponentModel;
-import net.dpml.composition.model.CompositionModel;
import net.dpml.composition.state.DefaultOperation;
import net.dpml.composition.state.DefaultState;
import net.dpml.composition.state.DefaultTransition;
import net.dpml.composition.state.NoSuchHandlerException;
import net.dpml.composition.state.RecursiveInitializationException;
import net.dpml.composition.state.RecursiveTerminationException;
+
+import net.dpml.composition.model.CompositionModel;
+import net.dpml.composition.model.ComponentModel;
+
import net.dpml.parts.control.Monitor;
-import net.dpml.parts.state.DuplicateKeyException;
+import net.dpml.parts.state.State;
+import net.dpml.parts.state.Transition;
import net.dpml.parts.state.Manager;
import net.dpml.parts.state.ResourceUnavailableException;
-import net.dpml.parts.state.State;
+import net.dpml.parts.state.DuplicateKeyException;
+import net.dpml.parts.state.NoSuchTransitionException;
+import net.dpml.parts.state.NoSuchOperationException;
+import net.dpml.parts.state.ValidationException;
+import net.dpml.parts.state.Operation;
import net.dpml.parts.state.StateEvent;
import net.dpml.parts.state.StateListener;
-import net.dpml.parts.state.ValidationException;


/**
@@ -60,23 +68,14 @@
*/
public class ComponentController extends ComponentModel implements Manager
{
- private final Vector m_listeners = new Vector();
private final Map m_handlers = new Hashtable();

- private final Object m_owner;
- private DefaultState m_graph;
-
- private DefaultState m_state;
- private Object m_instance;
-
public ComponentController(
Monitor monitor, CompositionModel model, Object key, Object owner )
throws Exception
{
- super( monitor, model, key );
+ super( monitor, model, key, owner );

- m_owner = owner;
- m_graph = resolveStateGraph( model.getDeploymentClass() );
initialize();
}

@@ -85,24 +84,6 @@
return getClass().getName();
}

- public Object getInstance() throws ResourceUnavailableException
- {
- if( null == m_instance )
- {
- String id = getURI().toString();
- throw new ResourceUnavailableException( id );
- }
- else
- {
- return m_instance;
- }
- }
-
- public void addStateListener( StateListener listener )
- {
- m_listeners.add( listener );
- }
-
/**
* Return an registered transition or operation handler.
*
@@ -176,18 +157,20 @@
*/
public synchronized void initialize() throws ValidationException,
Exception
{
- if( null != m_instance )
+ if( isInitialized() )
{
return;
}

-
- m_instance = getModel().getCompositionController().incarnate( this );
+ if( null == getLocalInstance() )
+ {
+ Object instance =
getModel().getCompositionController().incarnate( this );
+ setLocalInstance( instance );
+ }

List visited = new LinkedList();
DefaultState graph = getStateGraph();
validate( graph );
- m_state = getStateGraph();
boolean flag = true;
while( flag )
{
@@ -228,41 +211,7 @@
throw new RecursiveInitializationException( error );
}
}
-
- AvailabilityEvent event = new AvailabilityEvent( m_instance, true );
- notifyObservers( event );
- }
-
- private DefaultState resolveStateGraph( Class subject ) throws
IllegalAccessException
- {
- try
- {
- Field field = subject.getField( "STATE_GRAPH" );
- return (DefaultState) field.get( null );
- }
- catch( NoSuchFieldException e )
- {
- if( Executable.class.isAssignableFrom( subject ) )
- {
- return EXECUTABLE_OBJECT_GRAPH;
- }
- else if( Startable.class.isAssignableFrom( subject ) )
- {
- return STARTABLE_OBJECT_GRAPH;
- }
- else
- {
- return NULL_OBJECT_GRAPH;
- }
- }
- catch( ClassCastException e )
- {
- final String error =
- "The component is declaring a STATE_GRAPH member "
- + "that is not an instance of
net.dpml.composition.state.DefaultState."
- + "\nObject: " + getURI();
- throw new IllegalArgumentException( error );
- }
+ setInitialized( true );
}

private void validate( DefaultState state ) throws ValidationException
@@ -359,6 +308,7 @@
}
String scheme = uri.getScheme();
String spec = uri.getSchemeSpecificPart();
+
if( "method".equals( scheme ) )
{
if( "null".equals( spec ) )
@@ -367,7 +317,7 @@
}
else
{
- Class c = m_instance.getClass();
+ Class c = getModel().getDeploymentClass();
Method method = locateMethod( c, spec );
}
}
@@ -395,48 +345,6 @@
}

/**
- * Return the current state. The current state is the function of
- * the initialization and subsequent transition actions applied to
- * the state model. The current state established the active
- * state chain as the sequence of states from the current state to
- * root state. Any transitions defined in the active state chain
- * are candidates for execution. Transitions that are logically closer
to the
- * current state override transitions declare higher up in the
- * state chain. This method is exposed via the ServiceManager
- * interface to the controlling application (possibly the enclossing
- * component or the model controller). State instances returned from
- * this method are automatically proxied behind a State invocation
- * handler thereby ensuring the integrity of the state's state and
- * non-disclosure of implemetation features.
- *
- * @return the current state
- */
- public synchronized State getState()
- {
- return getCurrentState().getProxy();
- }
-
- /**
- * Internal utility method that returns a non-proxied reference to the
- * current state.
- *
- * @return the state representing the current state of execution
- */
- protected DefaultState getCurrentState()
- {
- if( null == m_state )
- {
- final String error =
- "State manager has not been initialized.";
- throw new IllegalStateException( error );
- }
- else
- {
- return m_state;
- }
- }
-
- /**
* Apply a transition identified by a supplied transition key. The
* implementation will attempt to locate the transition relative to the
current
* state (taking into account the DefaultState search semantics) from
which
@@ -575,11 +483,12 @@
}
else
{
- Class c = m_instance.getClass();
+ Object instance = getLocalInstance(); //##
+ Class c = instance.getClass();
Method method = locateMethod( c, spec );
Class[] parameters = method.getParameterTypes();
Object[] args = resolveArguments( parameters, state, target
);
- method.invoke( m_instance, args );
+ method.invoke( instance, args );
}
}
else if( "handler".equals( scheme ) )
@@ -625,6 +534,8 @@
*/
private Object[] resolveArguments( Class[] parameters, State state,
State target )
{
+ Object instance = getLocalInstance(); // ##
+
boolean firstStateAssigned = false;
Object[] args = new Object[ parameters.length ];
for( int i=0; i<parameters.length; i++ )
@@ -654,9 +565,9 @@
}
}
}
- else if( m_instance.getClass().isAssignableFrom( c ) )
+ else if( instance.getClass().isAssignableFrom( c ) )
{
- args[i] = m_instance;
+ args[i] = instance;
}
else
{
@@ -671,47 +582,6 @@
}

/**
- * Utility operation to apply a state change. If the supplied state is
- * differnet from the current state the current state will be updated to
- * the supplied value and a notification event issued to the listener
- * assigned under the constructor.
- *
- * @param state the state to assign as the current state
- */
- protected synchronized void setState( DefaultState state )
- {
- if( false == m_state.equals( state ) )
- {
- if( getMonitor().isDebugEnabled() )
- {
- final String message =
- "State change."
- + "\nInstance: " + getURI()
- + "\nOld State: " + m_state.getName()
- + "\nNew State: " + state.getName();
- getMonitor().debug( message );
- }
-
- StateEvent event = new StateEvent( m_instance, m_state, state );
- m_state = state;
- setChanged();
- ChangeEvent change = new ChangeEvent( this );
- notifyObservers( change );
- fireStateEvent( event );
- }
- }
-
- private void fireStateEvent( StateEvent event )
- {
- StateListener[] listeners = (StateListener[]) m_listeners.toArray(
new StateListener[0] );
- for( int i=0; i<listeners.length; i++ )
- {
- StateListener listener = listeners[i];
- listener.stateChanged( event );
- }
- }
-
- /**
* Handles a request for termination by a controller. The implementation
* will attempt to locate a transition named 'terminate' and if located,
* will apply that transition. If the result of the transition if a new
@@ -720,6 +590,10 @@
*/
public synchronized void terminate()
{
+ if( false == isInitialized() )
+ {
+ return;
+ }
try
{
executeTermination();
@@ -732,17 +606,16 @@
}
finally
{
- m_state = null;
- AvailabilityEvent event = new AvailabilityEvent( m_instance,
false );
- notifyObservers( event );
+ setInitialized( false );
+ setState( getStateGraph() );
}
}

synchronized void executeTermination() throws
RecursiveTerminationException
{
- if( null == m_state )
+ if( false == isInitialized() )
{
- return; // we were never initialized
+ return;
}

List visited = new LinkedList();
@@ -825,54 +698,4 @@
throw new ValidationException( error );
}

- /**
- * The operation returns the state instance represening the state graph.
- * @return the root state
- */
- private DefaultState getStateGraph()
- {
- return m_graph;
- }
-
- private static final DefaultState STARTABLE_OBJECT_GRAPH =
createStartableGraph();
- private static final DefaultState EXECUTABLE_OBJECT_GRAPH =
createExecutableGraph();
- private static final DefaultState NULL_OBJECT_GRAPH = createNullGraph();
-
- private static DefaultState createStartableGraph()
- {
- DefaultState root = new DefaultState();
- DefaultState started = root.addState( "started" );
- DefaultState stopped = root.addState( "stopped" );
- try
- {
- root.setInitialization( new URI( "method:start" ), started );
- started.setTerminator( new URI( "method:stop" ), stopped );
- started.addTransition( "stop", new URI( "method:stop" ), stopped
);
- stopped.addTransition( "start", new URI( "method:start" ),
started );
- return root;
- }
- catch( URISyntaxException e )
- {
- return null; // will not happen
- }
- }
-
- private static DefaultState createExecutableGraph()
- {
- DefaultState root = new DefaultState();
- try
- {
- root.setInitialization( new URI( "method:execute" ) );
- return root;
- }
- catch( URISyntaxException e )
- {
- return null; // will not happen
- }
- }
-
- private static DefaultState createNullGraph()
- {
- return new DefaultState( true );
- }
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/model/ComponentModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/model/ComponentModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/model/ComponentModel.java
Wed Apr 27 15:07:29 2005
@@ -21,17 +21,25 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Proxy;
+import java.lang.reflect.Field;
import java.net.URI;
+import java.net.URISyntaxException;
import java.util.Hashtable;
import java.util.Map;
import java.util.Observable;
import java.util.WeakHashMap;
import java.util.Map.Entry;
+import java.util.Vector;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

+import net.dpml.activity.Executable;
+import net.dpml.activity.Startable;
+
import net.dpml.composition.control.CompositionController;
+import net.dpml.composition.state.DefaultState;
+import net.dpml.composition.event.AvailabilityEvent;

import net.dpml.lang.ResourceUnavailableException;

@@ -39,7 +47,9 @@
import net.dpml.parts.control.LifecycleException;
import net.dpml.parts.control.Monitor;

+import net.dpml.parts.state.StateEvent;
import net.dpml.parts.state.StateListener;
+import net.dpml.parts.state.State;

/**
* A lifestyle handler provides support for the aquisition and release
@@ -50,7 +60,7 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Id: LifestyleManager.java 259 2004-10-30 07:24:40Z mcconnell $
*/
-public abstract class ComponentModel extends Observable implements Entry,
Identifiable
+public class ComponentModel extends Observable implements Entry, Identifiable
{
private final Map m_proxies = new WeakHashMap();

@@ -59,14 +69,23 @@
private final CompositionModel m_model;
private final URI m_uri;
private final ContextMap m_context;
+ private final DefaultState m_graph;
+ private DefaultState m_state;
+ private boolean m_initialized = false;
+
+ private transient Object m_instance;
+
+ private final Object m_owner; // not sure if this is needed
+ private final Vector m_listeners = new Vector(); // overlaps with
Observable

private boolean m_disposed = false;

- public ComponentModel( Monitor monitor, CompositionModel model, Object
key )
- throws LifecycleException, InvocationTargetException
+ public ComponentModel( Monitor monitor, CompositionModel model, Object
key, Object owner )
+ throws LifecycleException, InvocationTargetException,
IllegalAccessException
{
m_monitor = monitor;
m_model = model;
+ m_owner = owner;

if( null == key )
{
@@ -95,9 +114,133 @@
}

m_context = new ContextMap( model );
+ m_graph = resolveStateGraph( model.getDeploymentClass() );
+ m_state = m_graph;
+ }
+
+ public boolean isInitialized()
+ {
+ return m_initialized;
+ }
+
+ public void setInitialized( boolean flag )
+ {
+ m_initialized = flag;
+ AvailabilityEvent event = new AvailabilityEvent( m_instance, true );
+ notifyObservers( event );
+ }
+
+ public Object getInstance() throws ResourceUnavailableException
+ {
+ if(( null == m_instance ) || false == isInitialized() )
+ {
+ String id = getURI().toString();
+ throw new ResourceUnavailableException( id );
+ }
+ else
+ {
+ return getLocalInstance();
+ }
+ }
+
+ public Object getLocalInstance()
+ {
+ return m_instance;
+ }
+
+ public void setLocalInstance( Object instance )
+ {
+ m_instance = instance;
+ }
+
+ public void addStateListener( StateListener listener )
+ {
+ m_listeners.add( listener );
+ }
+
+ /**
+ * Utility operation to apply a state change. If the supplied state is
+ * differnet from the current state the current state will be updated to
+ * the supplied value and a notification event issued to the listener
+ * assigned under the constructor.
+ *
+ * @param state the state to assign as the current state
+ */
+ protected synchronized void setState( DefaultState state )
+ {
+ if( false == m_state.equals( state ) )
+ {
+ if( getMonitor().isDebugEnabled() )
+ {
+ final String message =
+ "State change."
+ + "\nInstance: " + getURI()
+ + "\nOld State: " + m_state.getName()
+ + "\nNew State: " + state.getName();
+ getMonitor().debug( message );
+ }
+
+ StateEvent event = new StateEvent( m_instance, m_state, state );
+ m_state = state;
+ setChanged();
+ ChangeEvent change = new ChangeEvent( this );
+ notifyObservers( change );
+ fireStateEvent( event );
+ }
+ }
+
+ private void fireStateEvent( StateEvent event )
+ {
+ StateListener[] listeners = (StateListener[]) m_listeners.toArray(
new StateListener[0] );
+ for( int i=0; i<listeners.length; i++ )
+ {
+ StateListener listener = listeners[i];
+ listener.stateChanged( event );
+ }
+ }
+
+ /**
+ * Return the current state. The current state is the function of
+ * the initialization and subsequent transition actions applied to
+ * the state model. The current state established the active
+ * state chain as the sequence of states from the current state to
+ * root state. Any transitions defined in the active state chain
+ * are candidates for execution. Transitions that are logically closer
to the
+ * current state override transitions declare higher up in the
+ * state chain. This method is exposed via the ServiceManager
+ * interface to the controlling application (possibly the enclossing
+ * component or the model controller). State instances returned from
+ * this method are automatically proxied behind a State invocation
+ * handler thereby ensuring the integrity of the state's state and
+ * non-disclosure of implemetation features.
+ *
+ * @return the current state
+ */
+ public synchronized State getState()
+ {
+ return getCurrentState().getProxy();
+ }
+
+ /**
+ * Internal utility method that returns a non-proxied reference to the
+ * current state.
+ *
+ * @return the state representing the current state of execution
+ */
+ protected DefaultState getCurrentState()
+ {
+ if( null == m_state )
+ {
+ final String error =
+ "State manager has not been initialized.";
+ throw new IllegalStateException( error );
+ }
+ else
+ {
+ return m_state;
+ }
}

- public abstract void addStateListener( StateListener listener );

public Monitor getMonitor()
{
@@ -166,8 +309,6 @@
return getInstance();
}

- public abstract Object getInstance() throws ResourceUnavailableException;
-
/**
* Returns an map containing context values keyed by context entry key
that
* override the default model context entry mapping. The context map is
used
@@ -269,6 +410,89 @@
}
}

+ private DefaultState resolveStateGraph( Class subject ) throws
IllegalAccessException
+ {
+ try
+ {
+ Field field = subject.getField( "STATE_GRAPH" );
+ return (DefaultState) field.get( null );
+ }
+ catch( NoSuchFieldException e )
+ {
+ if( Executable.class.isAssignableFrom( subject ) )
+ {
+ return EXECUTABLE_OBJECT_GRAPH;
+ }
+ else if( Startable.class.isAssignableFrom( subject ) )
+ {
+ return STARTABLE_OBJECT_GRAPH;
+ }
+ else
+ {
+ return NULL_OBJECT_GRAPH;
+ }
+ }
+ catch( ClassCastException e )
+ {
+ final String error =
+ "The component is declaring a STATE_GRAPH member "
+ + "that is not an instance of
net.dpml.composition.state.DefaultState."
+ + "\nObject: " + getURI();
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ /**
+ * The operation returns the state instance represening the state graph.
+ * @return the root state
+ */
+ public DefaultState getStateGraph()
+ {
+ return m_graph;
+ }
+
+ private static final DefaultState STARTABLE_OBJECT_GRAPH =
createStartableGraph();
+ private static final DefaultState EXECUTABLE_OBJECT_GRAPH =
createExecutableGraph();
+ private static final DefaultState NULL_OBJECT_GRAPH = createNullGraph();
+
+ private static DefaultState createStartableGraph()
+ {
+ DefaultState root = new DefaultState();
+ DefaultState started = root.addState( "started" );
+ DefaultState stopped = root.addState( "stopped" );
+ try
+ {
+ root.setInitialization( new URI( "method:start" ), started );
+ started.setTerminator( new URI( "method:stop" ), stopped );
+ started.addTransition( "stop", new URI( "method:stop" ), stopped
);
+ stopped.addTransition( "start", new URI( "method:start" ),
started );
+ return root;
+ }
+ catch( URISyntaxException e )
+ {
+ return null; // will not happen
+ }
+ }
+
+ private static DefaultState createExecutableGraph()
+ {
+ DefaultState root = new DefaultState();
+ try
+ {
+ root.setInitialization( new URI( "method:execute" ) );
+ return root;
+ }
+ catch( URISyntaxException e )
+ {
+ return null; // will not happen
+ }
+ }
+
+ private static DefaultState createNullGraph()
+ {
+ return new DefaultState( true );
+ }
+
/**
* The context map is a wrapper around the model's context map.
* If a local value is declared in this map that value is returned,
otherwise



  • svn commit: r2428 - in development/main/metro/composition/control/src/main/net/dpml/composition: control model, mcconnell, 04/27/2005

Archive powered by MHonArc 2.6.24.

Top of Page