notify-dpml AT lists.ibiblio.org
Subject: DPML Notify
List archive
svn commit: r2295 - in development/main/metro: . composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/activity composition/testing/activity/src composition/testing/activity/src/main composition/testing/activity/src/main/net composition/testing/activity/src/main/net/dpml composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test composition/testing/activity/src/test/net composition/testing/activity/src/test/net/dpml composition/testing/activity/src/test/net/dpml/test
- From: mcconnell AT dpml.net
- To: notify-dpml AT lists.ibiblio.org
- Subject: svn commit: r2295 - in development/main/metro: . composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/activity composition/testing/activity/src composition/testing/activity/src/main composition/testing/activity/src/main/net composition/testing/activity/src/main/net/dpml composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test composition/testing/activity/src/test/net composition/testing/activity/src/test/net/dpml composition/testing/activity/src/test/net/dpml/test
- Date: Sat, 16 Apr 2005 19:50:28 -0400
Author: mcconnell AT dpml.net
Date: Sat Apr 16 19:50:25 2005
New Revision: 2295
Added:
development/main/metro/composition/testing/activity/
development/main/metro/composition/testing/activity/build.properties
development/main/metro/composition/testing/activity/build.xml
development/main/metro/composition/testing/activity/src/
development/main/metro/composition/testing/activity/src/main/
development/main/metro/composition/testing/activity/src/main/net/
development/main/metro/composition/testing/activity/src/main/net/dpml/
development/main/metro/composition/testing/activity/src/main/net/dpml/test/
development/main/metro/composition/testing/activity/src/main/net/dpml/test/ActivityComponent.java
development/main/metro/composition/testing/activity/src/test/
development/main/metro/composition/testing/activity/src/test/net/
development/main/metro/composition/testing/activity/src/test/net/dpml/
development/main/metro/composition/testing/activity/src/test/net/dpml/test/
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ActivityTestCase.java
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/CompositionModel.java
development/main/metro/composition/control/src/main/net/dpml/composition/models/Holder.java
development/main/metro/index.xml
Log:
Add support for component based declaration of an instance controller.
Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
Sat Apr 16 19:50:25 2005
@@ -464,7 +464,7 @@
for( int i=0; i<interfaces.length; i++ )
{
Class service = interfaces[i];
- ServiceDescriptor descriptor = createServiceDescriptor( service
);
+ ServiceDescriptor descriptor = createServiceDescriptor( subject,
service );
if( null != descriptor )
{
list.add( descriptor );
@@ -473,16 +473,21 @@
return (ServiceDescriptor[]) list.toArray( new ServiceDescriptor[0]
);
}
- public ServiceDescriptor createServiceDescriptor( Class subject )
+ public ServiceDescriptor createServiceDescriptor( Class type, Class
subject )
{
- String type = subject.getName();
- if( type.startsWith( "java." ) )
+ String classname = subject.getName();
+ Class parent = subject.getDeclaringClass();
+ if( classname.startsWith( "java." ) )
{
return null; // ignore java.* interfaces
}
+ else if( type == parent )
+ {
+ return null; // ignore immediate inner interfaces
+ }
else
{
- return new ServiceDescriptor( type );
+ return new ServiceDescriptor( classname );
}
}
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
Sat Apr 16 19:50:25 2005
@@ -31,10 +31,14 @@
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.logging.Logger;
+import java.util.Observer;
+import java.util.Observable;
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
+import javax.swing.event.ChangeEvent;
+
import net.dpml.automation.part.Part;
import net.dpml.automation.control.PartHandler;
@@ -76,7 +80,7 @@
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
* @version $Revision: 1.2 $ $Date: 2004/03/17 10:30:09 $
*/
-public class CompositionController extends CompositionPartHandler implements
Controller
+public class CompositionController extends CompositionPartHandler implements
Controller, Observer
{
//--------------------------------------------------------------------
// static
@@ -123,6 +127,14 @@
}
//--------------------------------------------------------------------
+ // Observer
+ //--------------------------------------------------------------------
+
+ public void update( Observable observable, Object event )
+ {
+ }
+
+ //--------------------------------------------------------------------
// Controller
//--------------------------------------------------------------------
@@ -227,6 +239,12 @@
}
}
+ public Object getProcessController( Holder holder )
+ throws LifecycleException, InvocationTargetException
+ {
+ return m_factory.getProcessController( holder );
+ }
+
private EntryTable getEntryTable( CompositionModel model, URI uri )
throws UnknownSchemaException
{
final String scheme = uri.getScheme();
@@ -246,6 +264,22 @@
}
/**
+ * Add a part to the collection of parts managed by this controller.
+ *
+ * @param uri a uri identifying the part to add
+ * @return the model of the part
+ */
+ public Model getModel( URI uri )
+ throws IOException, DelegationException, ModelException,
PartNotFoundException
+ {
+ Part part = loadPart( uri );
+ ClassLoader anchor = net.dpml.logging.Logger.class.getClassLoader();
+ URI partition = getPartition();
+ ClassLoader classloader = new CompositionClassLoader( partition,
anchor );
+ return getModel( classloader, part, null );
+ }
+
+ /**
* Return the model for a supplied part.
*
* @param parent the parent classloader
@@ -278,7 +312,14 @@
ClassLoader parent = getClassLoader( partition, classloader,
profile );
if( null == model )
{
- return new CompositionModel( this, partition, parent,
profile, key );
+ if( null == key )
+ {
+ return new CompositionModel( this, partition, parent,
profile );
+ }
+ else
+ {
+ return new CompositionModel( this, partition, parent,
profile, key );
+ }
}
else
{
@@ -287,6 +328,10 @@
}
else if( part instanceof ValueDirective )
{
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
final ValueDirective directive = (ValueDirective) part;
return new ValueModel( key, this, classloader, directive, model
);
}
@@ -438,32 +483,6 @@
}
}
- public Object incarnate( Holder holder ) throws LifecycleException,
InvocationTargetException
- {
- return m_factory.incarnate( holder );
- }
-
- public void etherialize( Object instance )
- {
- if( null == instance )
- {
- return;
- }
- else if( Proxy.isProxyClass( instance.getClass() ) )
- {
- Object handler = Proxy.getInvocationHandler( instance );
- if( handler instanceof Disposable )
- {
- Disposable disposable = (Disposable) handler;
- disposable.dispose();
- }
- }
- else
- {
- m_factory.etherialize( instance );
- }
- }
-
//--------------------------------------------------------------------
// CompositionController
//--------------------------------------------------------------------
@@ -479,9 +498,18 @@
public Logger getLogChannel( CompositionModel model )
{
+ return getLogChannel( model, null );
+ }
+
+ public Logger getLogChannel( CompositionModel model, String category )
+ {
URI uri = model.getURI();
String path = model.getURI().getSchemeSpecificPart();
String channel = path.replace( '/', '.' );
+ if( category != null )
+ {
+ channel = channel + "." + category;
+ }
return Logger.getLogger( channel );
}
@@ -492,6 +520,32 @@
return m_system.getLoggingManager().getLoggerForCategory( path );
}
+ public Object incarnate( Holder holder ) throws LifecycleException,
InvocationTargetException
+ {
+ return m_factory.incarnate( holder );
+ }
+
+ public void etherialize( Object instance )
+ {
+ if( null == instance )
+ {
+ return;
+ }
+ else if( Proxy.isProxyClass( instance.getClass() ) )
+ {
+ Object handler = Proxy.getInvocationHandler( instance );
+ if( handler instanceof Disposable )
+ {
+ Disposable disposable = (Disposable) handler;
+ disposable.dispose();
+ }
+ }
+ else
+ {
+ m_factory.etherialize( instance );
+ }
+ }
+
/**
* Return the monitor assigned to this controller.
*
@@ -502,11 +556,16 @@
return m_monitor;
}
+ private URI getPartition()
+ {
+ return m_partition;
+ }
+
private URI getPartition( Model model )
{
if( null == model )
{
- return m_partition;
+ return getPartition();
}
else
{
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionManager.java
Sat Apr 16 19:50:25 2005
@@ -154,59 +154,6 @@
}
}
- private URI getLauchTargetURI( String[] arguments )
- {
- if( arguments.length == 0 )
- {
- return null;
- }
- else if( arguments.length == 1 )
- {
- String spec = arguments[0];
- return createURI( spec );
- }
- else
- {
- final String error =
- "Multi-part loading not supported at this time.";
- throw new UnsupportedOperationException( error );
- }
- }
-
- private CommandLine getCommandLine( String[] args )
- {
- try
- {
- Options options = buildCommandLineOptions();
- CommandLineParser parser = new GnuParser();
- return parser.parse( options, args, false );
- }
- catch( Throwable e )
- {
- URI uri = getURI();
- final String error =
- "Commandline parsing error.";
- throw new ControlRuntimeException( uri, error, e );
- }
- }
-
- private void addRootPart( URI uri )
- {
- try
- {
- addPart( uri, "root" );
- }
- catch( Throwable e )
- {
- URI control = getURI();
- final String error =
- "Unable to establish the model for the part."
- + "\nPart: " + uri
- + "\nController: " + getURI();
- throw new ControlRuntimeException( control, error, e );
- }
- }
-
//--------------------------------------------------------------------
// SystemManager
//--------------------------------------------------------------------
@@ -217,13 +164,27 @@
* @param uri a uri identifying the part to add
* @return the model of the part
*/
+ public Model addPart( URI uri )
+ throws IOException, DelegationException, ModelException,
PartNotFoundException
+ {
+ Model model = getModel( uri);
+ addModel( model );
+ return model;
+ }
+
+ /**
+ * Add a part to the collection of parts managed by this controller.
+ *
+ * @param uri a uri identifying the part to add
+ * @return the model of the part
+ */
public Model addPart( URI uri, String key )
throws IOException, DelegationException, ModelException,
PartNotFoundException
{
Part part = loadPart( uri );
ClassLoader classloader = getClassLoader();
Model model = getModel( classloader, part, key );
- m_models.add( model );
+ addModel( model );
return model;
}
@@ -315,6 +276,59 @@
//
}
+ private URI getLauchTargetURI( String[] arguments )
+ {
+ if( arguments.length == 0 )
+ {
+ return null;
+ }
+ else if( arguments.length == 1 )
+ {
+ String spec = arguments[0];
+ return createURI( spec );
+ }
+ else
+ {
+ final String error =
+ "Multi-part loading not supported at this time.";
+ throw new UnsupportedOperationException( error );
+ }
+ }
+
+ private CommandLine getCommandLine( String[] args )
+ {
+ try
+ {
+ Options options = buildCommandLineOptions();
+ CommandLineParser parser = new GnuParser();
+ return parser.parse( options, args, false );
+ }
+ catch( Throwable e )
+ {
+ URI uri = getURI();
+ final String error =
+ "Commandline parsing error.";
+ throw new ControlRuntimeException( uri, error, e );
+ }
+ }
+
+ private void addRootPart( URI uri )
+ {
+ try
+ {
+ addPart( uri, "root" );
+ }
+ catch( Throwable e )
+ {
+ URI control = getURI();
+ final String error =
+ "Unable to establish the model for the part."
+ + "\nPart: " + uri
+ + "\nController: " + getURI();
+ throw new ControlRuntimeException( control, error, e );
+ }
+ }
+
/**
* Create a shutdown hook that will trigger shutdown of the supplied
plugin.
* @param thread the application thread
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifecycleHandler.java
Sat Apr 16 19:50:25 2005
@@ -25,6 +25,8 @@
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import javax.swing.event.ChangeListener;
+
import net.dpml.automation.control.LifecycleException;
import net.dpml.automation.control.LifecycleRuntimeException;
import net.dpml.automation.control.Monitor;
@@ -148,6 +150,82 @@
}
/**
+ * Execute the incarnation sequence and return a new
+ * component instance.
+ *
+ * @return a new component instance
+ */
+ public Object getProcessController( Holder holder ) throws
LifecycleException, InvocationTargetException
+ {
+ if( getMonitor().isDebugEnabled() )
+ {
+ final String message =
+ "Instantiating controller for ["
+ + holder.getURI()
+ + "].";
+ getMonitor().debug( message );
+ }
+ CompositionModel model = holder.getModel();
+ URI uri = holder.getURI();
+
+ Class subject = model.getDeploymentClass();
+ ClassLoader classloader = subject.getClassLoader();
+ Class control = getInnerClass( subject, "Controller" );
+ if( null == control )
+ {
+ return null;
+ }
+
+ Constructor constructor = getConstructor( control );
+ Class[] classes = constructor.getParameterTypes();
+ Object[] args = new Object[ classes.length ];
+ Object instance = holder.getValue();
+
+ for( int i=0; i<classes.length; i++ )
+ {
+ Class c = classes[i];
+ if( java.util.logging.Logger.class.isAssignableFrom( c ) )
+ {
+ args[i] = model.getCompositionController().getLogChannel(
model, "control" );
+ }
+ else if( Logger.class.isAssignableFrom( c ) )
+ {
+ args[i] =
model.getCompositionController().getLoggingChannel( model );
+ }
+ else if( subject.isAssignableFrom( c ) )
+ {
+ args[i] = instance;
+ }
+ else if( ChangeListener.class.isAssignableFrom( c ) )
+ {
+ args[i] = holder;
+ }
+ else
+ {
+ final String error =
+ "The controller class ["
+ + control.getName()
+ + "] in the component ["
+ + subject.getName()
+ + "] decares an unsupported constructor parameter type ["
+ + c.getName()
+ + "].";
+ throw new LifecycleRuntimeException( error );
+ }
+ }
+
+ try
+ {
+ return constructor.newInstance( args );
+ }
+ catch( Throwable e )
+ {
+ throw new LifecycleException( model, e );
+ }
+ }
+
+
+ /**
* Apply the etherialization process to the supplied instance.
*
* @param object the object to etherialize
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/LifestyleHandler.java
Sat Apr 16 19:50:25 2005
@@ -114,14 +114,22 @@
*/
public Holder aquire( CompositionModel model, Object key ) throws
LifecycleException, InvocationTargetException
{
+ if( null == model )
+ {
+ throw new NullPointerException( "model" );
+ }
+ if( null == key )
+ {
+ throw new NullPointerException( "key" );
+ }
Holder holder = model.getInstanceTable().get( key );
if( null == holder )
{
if( getMonitor().isDebugEnabled() )
{
final String message =
- "Initiating creation of identifiable instance ["
- + holder.getURI()
+ "Initiating creation of identifiable instance in ["
+ + model.getURI()
+ "].";
getMonitor().debug( message );
}
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/CompositionModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/CompositionModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/CompositionModel.java
Sat Apr 16 19:50:25 2005
@@ -86,6 +86,22 @@
* @param name the name of the model
*/
public CompositionModel(
+ CompositionController controller, URI partition, ClassLoader
classloader, ComponentProfile profile )
+ throws ModelException
+ {
+ this( controller, null, partition, classloader, profile,
profile.getName() );
+ }
+
+ /**
+ * Creation of a new root component model.
+ *
+ * @param controller the model controller
+ * @param partition a name defining the partition that this model exists
within
+ * @param classloader the classloader established for this model
+ * @param profile the component profile from which initial default values
are established
+ * @param name the name of the model
+ */
+ public CompositionModel(
CompositionController controller, URI partition, ClassLoader
classloader, ComponentProfile profile, String name )
throws ModelException
{
Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/Holder.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/Holder.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/Holder.java
Sat Apr 16 19:50:25 2005
@@ -26,6 +26,10 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Hashtable;
+import java.util.Observable;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
import net.dpml.automation.control.Monitor;
import net.dpml.automation.control.LifecycleException;
@@ -43,7 +47,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 class Holder implements Entry, Identifiable
+public class Holder extends Observable implements Entry, Identifiable,
ChangeListener
{
private final Map m_proxies = new WeakHashMap();
@@ -53,6 +57,7 @@
private final URI m_uri;
private final ContextMap m_context;
private final Object m_instance;
+ private final Object m_manager;
private boolean m_disposed = false;
@@ -91,6 +96,11 @@
m_context = new ContextMap( model );
m_instance = model.getCompositionController().incarnate( this );
+
+ CompositionController controller = model.getCompositionController();
+ super.addObserver( controller );
+
+ m_manager = model.getCompositionController().getProcessController(
this );
}
public Object getKey()
@@ -98,6 +108,12 @@
return m_key;
}
+ public void stateChanged( ChangeEvent event )
+ {
+ setChanged();
+ notifyObservers( event );
+ }
+
public CompositionModel getModel()
{
return m_model;
@@ -117,6 +133,11 @@
return m_uri;
}
+ public Object getProcessController()
+ {
+ return m_manager;
+ }
+
/**
* Create, register and return a proxy to the instance managed by this
* holder. The implementation will register the proxy as a weak reference
@@ -136,7 +157,7 @@
}
/**
- * Unsupported operated.
+ * Unsupported operation.
* @param value ignored
* @return nothing
* @exception UnsupportedOperationException is always thrown
Added: development/main/metro/composition/testing/activity/build.properties
==============================================================================
--- (empty file)
+++ development/main/metro/composition/testing/activity/build.properties
Sat Apr 16 19:50:25 2005
@@ -0,0 +1,2 @@
+
+project.test.fork = true
Added: development/main/metro/composition/testing/activity/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/composition/testing/activity/build.xml Sat
Apr 16 19:50:25 2005
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-composition-testing-activity" default="install"
basedir="."
+ xmlns:transit="antlib:net.dpml.transit"
xmlns:x="plugin:dpml/magic/dpml-magic-core">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="build" depends="standard.build">
+
+ <!-- create the component types -->
+ <types xmlns="plugin:dpml/composition/dpml-composition-builder">
+ <type class="net.dpml.test.ActivityComponent"/>
+ </types>
+
+ <!-- creation of a component for reference by uri -->
+ <component xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.test.ActivityComponent"
+ name="test"/>
+
+ <!-- creation of a component for local testing -->
+ <component xmlns="plugin:dpml/composition/dpml-composition-builder"
+ type="net.dpml.test.ActivityComponent"
+ name="test"
+ dest="target/test/test.part"/>
+
+ </target>
+
+</project>
Added:
development/main/metro/composition/testing/activity/src/main/net/dpml/test/ActivityComponent.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/activity/src/main/net/dpml/test/ActivityComponent.java
Sat Apr 16 19:50:25 2005
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2005 Stephen J. McConnell.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.test;
+
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Logger;
+import java.lang.reflect.Method;
+
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+
+/**
+ * Experimental component dealing with activitiy state management.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ */
+public class ActivityComponent
+{
+ //------------------------------------------------------------------
+ // static
+ //------------------------------------------------------------------
+
+ public static final boolean TYPE_THREADSAFE_CAPABLE = true;
+
+ //------------------------------------------------------------------
+ // state
+ //------------------------------------------------------------------
+
+ private final Logger m_logger;
+
+ //------------------------------------------------------------------
+ // constructor
+ //------------------------------------------------------------------
+
+ /**
+ * Creation of a component that describes an activity model.
+ *
+ * @param logger the logging channel assigned by the container
+ */
+ public ActivityComponent( final Logger logger )
+ {
+ m_logger = logger;
+ }
+
+ private Logger getLogger()
+ {
+ return m_logger;
+ }
+
+ //------------------------------------------------------------------
+ // Activity
+ //------------------------------------------------------------------
+
+ public static class Controller
+ {
+ public static final State AVAILABLE = new Available();
+ public static final State STARTED = new Started();
+ public static final State STOPPED = new Stopped();
+ public static final State TERMINATED = new Terminated();
+
+ protected final ActivityComponent m_instance;
+ protected final ChangeListener m_listener;
+ protected final Logger m_logger;
+
+ protected State m_state = AVAILABLE;
+
+ public Controller( ActivityComponent instance, Logger logger,
ChangeListener listener )
+ {
+ m_instance = instance;
+ m_listener = listener;
+ m_logger = logger;
+ }
+
+ public synchronized State getState()
+ {
+ return m_state;
+ }
+
+ public synchronized void initialize()
+ {
+ m_logger.info( "initializing" );
+ if( m_state == AVAILABLE )
+ {
+ m_instance.start();
+ setState( STARTED );
+ }
+ else
+ {
+ final String error =
+ "Cannot initialize from state: " + m_state;
+ throw new IllegalStateException( error );
+ }
+ m_logger.info( "initialized" );
+ }
+
+ public synchronized void terminate()
+ {
+ m_logger.info( "terminating" );
+ if( m_state == STARTED )
+ {
+ m_instance.stop();
+ }
+ setState( TERMINATED );
+ m_logger.info( "terminated" );
+ }
+
+ public synchronized void invoke( Method method ) throws Exception
+ {
+ State state = (State) method.invoke( m_state, new Object[]{
m_instance } );
+ setState( state );
+ }
+
+ private synchronized void setState( State state )
+ {
+ if( m_state != state )
+ {
+ m_state = state;
+ ChangeEvent event = new ChangeEvent( this );
+ m_listener.stateChanged( event );
+ }
+ }
+ }
+
+ //------------------------------------------------------------------
+ // state transitions
+ //------------------------------------------------------------------
+
+
+ private void start()
+ {
+ getLogger().info( "started" );
+ }
+
+ private void stop()
+ {
+ getLogger().info( "stopped" );
+ }
+
+ //------------------------------------------------------------------
+ // states
+ //------------------------------------------------------------------
+
+ public static class State{}
+
+ public static class Available extends State{}
+
+ public static class Started extends Available
+ {
+ public State stop( ActivityComponent activity )
+ {
+ activity.stop();
+ return Controller.STOPPED;
+ }
+ }
+
+ public static class Stopped extends Available
+ {
+ public State start( ActivityComponent activity )
+ {
+ activity.start();
+ return Controller.STARTED;
+ }
+ }
+
+ public static class Terminated extends State
+ {
+ }
+}
Added:
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ActivityTestCase.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/activity/src/test/net/dpml/test/ActivityTestCase.java
Sat Apr 16 19:50:25 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ * Copyright 1999-2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.dpml.test;
+
+import java.net.URI;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Map.Entry;
+import java.lang.reflect.Method;
+
+import junit.framework.TestCase;
+
+import net.dpml.automation.model.Model;
+import net.dpml.composition.unit.CompositionHelper;
+import net.dpml.composition.models.Holder;
+
+/**
+ * Test a simple component case.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: AbstractDescriptorTestCase.java 1556 2005-01-22 12:43:42Z
niclas $
+ */
+public class ActivityTestCase extends TestCase
+{
+ /**
+ * Test the construction of the example component and the invocation of
+ * an operation on the example service interface.
+ */
+ public void testManagedComponent() throws Exception
+ {
+ Holder holder = getComponentHolder();
+ ActivityComponent.Controller manager =
+ (ActivityComponent.Controller) holder.getProcessController();
+ manager.initialize();
+ Method[] transitions = getTransitions( manager );
+ for( int i=0; i<transitions.length; i++ )
+ {
+ Method method = transitions[i];
+ System.out.println( "# transition: " + method.getName() );
+ }
+ manager.terminate();
+ holder.dispose();
+ }
+
+ private Method[] getTransitions( ActivityComponent.Controller manager )
+ {
+ List list = new ArrayList();
+ Method[] methods = manager.getState().getClass().getMethods();
+ for( int i=0; i<methods.length; i++ )
+ {
+ Method method = methods[i];
+ if( method.getDeclaringClass() != Object.class )
+ {
+ Class returnType = method.getReturnType();
+ if( null != returnType )
+ {
+ list.add( method );
+ }
+ }
+ }
+ return (Method[]) list.toArray( new Method[0] );
+ }
+
+ Holder getComponentHolder() throws Exception
+ {
+ CompositionHelper helper = new CompositionHelper( true );
+ URI uri = helper.toURI( "test.part" );
+ Model model = helper.getCompositionManager().getModel( uri );
+ return (Holder) helper.getCompositionManager().create( model );
+ }
+}
+
+
Modified: development/main/metro/index.xml
==============================================================================
--- development/main/metro/index.xml (original)
+++ development/main/metro/index.xml Sat Apr 16 19:50:25 2005
@@ -514,6 +514,25 @@
</plugins>
</project>
+ <project basedir="composition/testing/activity">
+ <info>
+ <group>dpml/test</group>
+ <name>dpml-composition-testing-activity</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ <type>part</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-composition-unit" runtime="false"/>
+ </dependencies>
+ <plugins>
+ <include key="dpml-composition-builder"/>
+ </plugins>
+ </project>
+
<project basedir="composition/testing/unit">
<info>
<group>dpml/test</group>
- svn commit: r2295 - in development/main/metro: . composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/control/src/main/net/dpml/composition/models composition/testing/activity composition/testing/activity/src composition/testing/activity/src/main composition/testing/activity/src/main/net composition/testing/activity/src/main/net/dpml composition/testing/activity/src/main/net/dpml/test composition/testing/activity/src/test composition/testing/activity/src/test/net composition/testing/activity/src/test/net/dpml composition/testing/activity/src/test/net/dpml/test, mcconnell, 04/16/2005
Archive powered by MHonArc 2.6.24.