Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2412 - 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/management composition/control/src/main/net/dpml/composition/models composition/control/src/test/net/dpml/composition/management composition/part/src/main/net/dpml/composition/state composition/part/src/test/net/dpml/composition/state composition/testing/test composition/testing/test/src/main/net/dpml/test/config composition/testing/test/src/main/net/dpml/test/state composition/testing/test/src/test/net/dpml/composition/testing composition/testing/test/src/test/net/dpml/test/config composition/testing/test/src/test/net/dpml/test/state parts/src/main/net/dpml/parts/control parts/src/main/net/dpml/parts/model parts/src/main/net/dpml/parts/state

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: r2412 - 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/management composition/control/src/main/net/dpml/composition/models composition/control/src/test/net/dpml/composition/management composition/part/src/main/net/dpml/composition/state composition/part/src/test/net/dpml/composition/state composition/testing/test composition/testing/test/src/main/net/dpml/test/config composition/testing/test/src/main/net/dpml/test/state composition/testing/test/src/test/net/dpml/composition/testing composition/testing/test/src/test/net/dpml/test/config composition/testing/test/src/test/net/dpml/test/state parts/src/main/net/dpml/parts/control parts/src/main/net/dpml/parts/model parts/src/main/net/dpml/parts/state
  • Date: Tue, 26 Apr 2005 06:01:29 -0400

Author: mcconnell AT dpml.net
Date: Tue Apr 26 06:01:25 2005
New Revision: 2412

Added:

development/main/metro/composition/control/src/main/net/dpml/composition/management/AvailabilityEvent.java

development/main/metro/parts/src/main/net/dpml/parts/state/ResourceUnavailableException.java
development/main/metro/parts/src/main/net/dpml/parts/state/StateEvent.java

development/main/metro/parts/src/main/net/dpml/parts/state/StateListener.java
Removed:

development/main/metro/composition/control/src/main/net/dpml/composition/management/ExecutableManager.java

development/main/metro/composition/control/src/main/net/dpml/composition/management/NullManager.java

development/main/metro/composition/control/src/main/net/dpml/composition/management/StartableManager.java

development/main/metro/composition/control/src/test/net/dpml/composition/management/DefaultManagerTestCase.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/ApplianceInvocationHandler.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/ConsoleMonitor.java

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

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

development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.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/control/ManagerInvocationHandler.java

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

development/main/metro/composition/control/src/main/net/dpml/composition/management/DefaultManager.java

development/main/metro/composition/control/src/main/net/dpml/composition/management/ValueManager.java

development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java

development/main/metro/composition/part/src/main/net/dpml/composition/state/DefaultState.java

development/main/metro/composition/part/src/test/net/dpml/composition/state/DefaultStateTestCase.java
development/main/metro/composition/testing/test/build.xml

development/main/metro/composition/testing/test/src/main/net/dpml/test/config/ConfigurableContainer.java

development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagedComponent.java

development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagingContainer.java

development/main/metro/composition/testing/test/src/test/net/dpml/composition/testing/CompositeTestCase.java

development/main/metro/composition/testing/test/src/test/net/dpml/test/config/ConfigurationTestCase.java

development/main/metro/composition/testing/test/src/test/net/dpml/test/state/ManagementTestCase.java
development/main/metro/parts/src/main/net/dpml/parts/control/Monitor.java
development/main/metro/parts/src/main/net/dpml/parts/model/Model.java
development/main/metro/parts/src/main/net/dpml/parts/state/Manager.java
Log:
Cutting, bumping, reshuffling, ... this is an interim commit (that builds)
but is subject to additional reengineering concerning the management of parts
and instance level controls.

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
Tue Apr 26 06:01:25 2005
@@ -621,7 +621,7 @@
{
Method method = methods[i];
String name = method.getName();
- if( false == "addObserver".equals( name ) )
+ if( name.startsWith( "get" ) )
{
EntryDescriptor descriptor = createEntryDescriptor(
method );
list.add( descriptor );

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ApplianceInvocationHandler.java
Tue Apr 26 06:01:25 2005
@@ -26,6 +26,8 @@

import net.dpml.parts.control.Disposable;

+import net.dpml.composition.management.DefaultManager;
+
/**
* The ApplianceInvocationHandler class represents an instance of a
component.
* It is responsible for the incarnation, runtime management, execution, and
@@ -41,9 +43,8 @@
// state
//-------------------------------------------------------------------

- private final Holder m_holder;
+ private final DefaultManager m_manager;
private boolean m_disposed = false;
- private Object m_instance;

//-------------------------------------------------------------------
// constructor
@@ -54,12 +55,11 @@
*
* @param holder the instance holder
*/
- ApplianceInvocationHandler( Holder holder )
+ ApplianceInvocationHandler( DefaultManager manager )
throws Exception
{
- assertNotNull( holder, "holder" );
- m_holder = holder;
- m_instance = holder.getValue();
+ assertNotNull( manager, "manager" );
+ m_manager = manager ;
}

//-------------------------------------------------------------------
@@ -86,7 +86,8 @@

try
{
- return method.invoke( m_instance, args );
+ Object instance = m_manager.getInstance();
+ return method.invoke( instance, args );
}
catch( Throwable e )
{
@@ -100,7 +101,7 @@

public URI getURI()
{
- return m_holder.getURI();
+ return m_manager.getURI();
}

public void dispose()
@@ -108,8 +109,7 @@
if( !m_disposed )
{
m_disposed = true;
- m_instance = null;
- m_holder.release( this );
+ m_manager.release( this );
}
}


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
Tue Apr 26 06:01:25 2005
@@ -51,6 +51,7 @@
import net.dpml.composition.models.CompositionModel;
import net.dpml.composition.models.ValueModel;

+import net.dpml.composition.management.DefaultManager;
import net.dpml.composition.management.ValueManager;

import net.dpml.system.SystemContext;
@@ -302,18 +303,17 @@
}
}

- public Manager getManager( Model model ) throws Exception
+ public Manager getManager( Object controller, Model model ) throws
Exception
{
- return getManager( model, null );
+ return getManager( controller, model, null );
}

- public Manager getManager( Model model, Object key ) throws Exception
+ public Manager getManager( Object controller, Model model, Object key )
throws Exception
{
if( model instanceof CompositionModel )
{
CompositionModel componentModel = (CompositionModel) model;
- Holder holder = getHolder( componentModel , key );
- return getManager( holder );
+ return (Manager) getDefaultManager( componentModel , key,
controller );
}
else if(( model instanceof ValueModel ) )
{
@@ -342,12 +342,6 @@
}
}

- public Manager getManager( Holder holder )
- throws LifecycleException, InvocationTargetException
- {
- return m_lifecycleHandler.getManager( holder );
- }
-
/**
* Create and return a new instance of the component represented
* by the supplied model using the assigned lifestyle policy.
@@ -391,34 +385,15 @@
if( model instanceof CompositionModel )
{
CompositionModel componentModel = (CompositionModel) model;
-
- //
- // PROBLEM HERE!
- // The holder needs to be available aware. Available events
need to
- // generated by the manager of instance and the holder registers
itself
- // as a listener to the manager. When the manager posts an
available
- // event it includes the instance. In turn the holder can
notify proxies
- // of changes to availability status and state change.
- //
- //
- // SECOND ISSUE!
- // The controller needs to handle the initialization and
termination
- // operations. The component can then take over intermidiate
state
- // management functions. The best way to do that would be to
have the
- // component declare a static state model, and to supply a
Manager as a
- // constructor argument. The manager implementation would notify
the
- // instance of its initiaization and termination.
- //
-
- Holder holder = getHolder( componentModel , key );
+ DefaultManager manager = getDefaultManager( componentModel ,
key, null );
if( policy )
{
- InvocationHandler handler = new ApplianceInvocationHandler(
holder );
- return holder.getProxy( handler );
+ InvocationHandler handler = new ApplianceInvocationHandler(
manager );
+ return manager.getProxy( handler );
}
else
{
- return holder.getValue();
+ return manager.getInstance();
}
}
else
@@ -431,15 +406,16 @@
}
}

- public Holder getHolder( CompositionModel model, Object key ) throws
LifecycleException, InvocationTargetException
+ private DefaultManager getDefaultManager( CompositionModel model, Object
key, Object owner )
+ throws Exception
{
if( null == key )
{
- return m_lifestyleHandler.aquire( model );
+ return (DefaultManager) m_lifestyleHandler.aquire( model, owner );
}
else
{
- return m_lifestyleHandler.aquire( model, key );
+ return (DefaultManager) m_lifestyleHandler.aquire( model, key,
owner );
}
}


Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ConsoleMonitor.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ConsoleMonitor.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ConsoleMonitor.java
Tue Apr 26 06:01:25 2005
@@ -115,6 +115,17 @@
}

/**
+ * Log the supplied info level message.
+ * @param message the message to log
+ * @param throwable the exception
+ */
+ public void warn( String message, Throwable throwable )
+ {
+ write( "WARN ", message );
+ throwable.printStackTrace();
+ }
+
+ /**
* Log the supplied error level message.
* @param message the message to log
* @param throwable the exception

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ContextInvocationHandler.java
Tue Apr 26 06:01:25 2005
@@ -24,6 +24,7 @@

import net.dpml.parts.control.LifecycleException;
import net.dpml.parts.model.ModelException;
+import net.dpml.parts.state.StateListener;

import net.dpml.composition.models.CompositionModel;

@@ -102,22 +103,42 @@
else
{
String name = method.getName();
- if( Void.TYPE.equals( method.getReturnType() )
- && ( null != args )
- && ( args.length == 1 )
- && "addObserver".equals( name )
- && ( args[0] instanceof Observer ) )
- {
- Observer observer = (Observer) args[0];
- getHolder().addObserver( observer );
- return null;
- }
- else
+ if( name.startsWith( "get" ) )
{
String key = getKeyFromMethod( method );
Holder.ContextMap map = getHolder().getContextMap();
return map.getValue( key, args );
}
+ else if( null != args )
+ {
+ if( args.length > 0 )
+ {
+ if( "addObserver".equals( name ) )
+ {
+ Observer observer = (Observer) args[0];
+ getHolder().addObserver( observer );
+ return null;
+ }
+ else if( "addStateListener".equals( name ) )
+ {
+ StateListener listener = (StateListener) args[0];
+ getHolder().addStateListener( listener );
+ return null;
+ }
+ else
+ {
+ throw new NoSuchMethodException( name );
+ }
+ }
+ else
+ {
+ throw new NoSuchMethodException( name );
+ }
+ }
+ else
+ {
+ throw new NoSuchMethodException( name );
+ }
}
}


Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/DefaultMonitor.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/DefaultMonitor.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/DefaultMonitor.java
Tue Apr 26 06:01:25 2005
@@ -105,6 +105,15 @@
}

/**
+ * Log the supplied info level message.
+ * @param message the message to log
+ */
+ public void warn( String message, Throwable throwable )
+ {
+ m_logger.warn( message, throwable );
+ }
+
+ /**
* Log the supplied error level message.
* @param message the message to log
* @param throwable the exception

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/Holder.java
Tue Apr 26 06:01:25 2005
@@ -34,11 +34,12 @@
import net.dpml.composition.models.CompositionModel;
import net.dpml.composition.models.ContextTable;

+import net.dpml.lang.ResourceUnavailableException;
+
import net.dpml.parts.control.Identifiable;
import net.dpml.parts.control.LifecycleException;
import net.dpml.parts.control.Monitor;
-
-import net.dpml.parts.state.Manager;
+import net.dpml.parts.state.StateListener;

/**
* A lifestyle handler provides support for the aquisition and release
@@ -49,7 +50,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 extends Observable implements Entry, Identifiable,
ChangeListener
+public abstract class Holder extends Observable implements Entry,
Identifiable
{
private final Map m_proxies = new WeakHashMap();

@@ -58,7 +59,6 @@
private final CompositionModel m_model;
private final URI m_uri;
private final ContextMap m_context;
- private final Object m_instance;

private boolean m_disposed = false;

@@ -96,20 +96,18 @@
}

m_context = new ContextMap( model );
- m_instance = model.getCompositionController().incarnate( this );
- CompositionController controller = model.getCompositionController();
- super.addObserver( controller );
}

- public Object getKey()
+ public abstract void addStateListener( StateListener listener );
+
+ public Monitor getMonitor()
{
- return m_key;
+ return m_monitor;
}

- public void stateChanged( ChangeEvent event )
+ public Object getKey()
{
- setChanged();
- notifyObservers( event );
+ return m_key;
}

public CompositionModel getModel()
@@ -166,9 +164,11 @@
*/
public Object getValue()
{
- return m_instance;
+ 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
@@ -207,7 +207,15 @@
}
m_proxies.clear();
controller.getInstanceTable().remove( this );
- controller.etherialize( m_instance );
+ try
+ {
+ Object instance = getInstance();
+ controller.etherialize( instance );
+ }
+ catch( IllegalStateException e )
+ {
+ // pass
+ }
}
}


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
Tue Apr 26 06:01:25 2005
@@ -38,11 +38,6 @@

import net.dpml.composition.models.CompositionModel;

-import net.dpml.composition.management.NullManager;
-import net.dpml.composition.management.ValueManager;
-import net.dpml.composition.management.ExecutableManager;
-import net.dpml.composition.management.StartableManager;
-
import net.dpml.composition.info.Type;

import net.dpml.logging.Logger;
@@ -179,6 +174,7 @@
*
* @return the state manager (possibly null)
*/
+ /*
public Manager getManager( Holder holder ) throws LifecycleException,
InvocationTargetException
{
if( getMonitor().isDebugEnabled() )
@@ -258,7 +254,7 @@
throw new LifecycleException( model, e );
}
}
-
+ */

/**
* Apply the etherialization process to the supplied instance.

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
Tue Apr 26 06:01:25 2005
@@ -24,6 +24,7 @@
import net.dpml.parts.control.Monitor;

import net.dpml.composition.models.CompositionModel;
+import net.dpml.composition.management.DefaultManager;

/**
* A lifestyle handler provides support for the aquisition and release
@@ -49,7 +50,7 @@
* @param model the model from which new or existing instances will be
resolved
* @return the key to the resolved instance
*/
- public Holder aquire( CompositionModel model ) throws
LifecycleException, InvocationTargetException
+ public Holder aquire( CompositionModel model, Object owner ) throws
Exception
{
final String lifestyle = model.getLifestylePolicy();
if( getMonitor().isDebugEnabled() )
@@ -66,7 +67,7 @@
{
synchronized( model )
{
- Holder holder = new Holder( m_monitor, model, null );
+ Holder holder = new DefaultManager( m_monitor, model, null,
owner );
Object key = holder.getKey();
if( getMonitor().isDebugEnabled() )
{
@@ -80,18 +81,18 @@
return holder;
}
}
- else if( "thread".equals( lifestyle ) )
- {
- throw new UnsupportedOperationException( "thread" );
- }
else if( "model".equals( lifestyle ) || "singleton".equals(
lifestyle ) )
{
synchronized( model )
{
String key = CompositionController.SELF;
- return aquire( model, key );
+ return aquire( model, key, owner );
}
}
+ else if( "thread".equals( lifestyle ) )
+ {
+ throw new UnsupportedOperationException( "thread" );
+ }
else
{
final String error =
@@ -111,7 +112,8 @@
* @param model the model from which new or existing instances will be
resolved
* @return the key to the resolved instance
*/
- public Holder aquire( CompositionModel model, Object key ) throws
LifecycleException, InvocationTargetException
+ public Holder aquire( CompositionModel model, Object key, Object owner )
+ throws Exception
{
if( null == model )
{
@@ -122,6 +124,7 @@
throw new NullPointerException( "key" );
}
Holder holder =
model.getCompositionController().getInstanceTable().get( model, key );
+
if( null == holder )
{
if( getMonitor().isDebugEnabled() )
@@ -132,7 +135,7 @@
+ "].";
getMonitor().debug( message );
}
- holder = new Holder( m_monitor, model, key );
+ holder = new DefaultManager( m_monitor, model, key, owner );
if( getMonitor().isDebugEnabled() )
{
final String message =

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/ManagerInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/ManagerInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/ManagerInvocationHandler.java
Tue Apr 26 06:01:25 2005
@@ -31,7 +31,7 @@

import net.dpml.composition.data.ValueDirective;

-import net.dpml.composition.management.NullManager;
+import net.dpml.composition.state.DefaultState;

import net.dpml.lang.DelegationRuntimeException;

@@ -112,7 +112,7 @@
}
catch( NoSuchMethodException e )
{
- return m_holder.getValue();
+ return null;
}
catch( Throwable e )
{
@@ -128,14 +128,14 @@
}
catch( NoSuchMethodException e )
{
- return NullManager.AVAILABLE;
+ return TERMINAL_STATE;
}
catch( Throwable e )
{
throw handleInvocationThrowable( method, e );
}
}
- else if( "apply".equals( name ) || "execute".equals( name ) )
+ else if( "apply".equals( name ) || "getInstance".equals( name ) ||
"execute".equals( name ) )
{
try
{
@@ -210,4 +210,7 @@
}
return e;
}
+
+ private static final State TERMINAL_STATE = new DefaultState( true );
+
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/PartsInvocationHandler.java
Tue Apr 26 06:01:25 2005
@@ -227,7 +227,7 @@

CompositionModel model = (CompositionModel) provider;
Controller controller = model.getController();
- Holder holder = getHolder( model, args );
+ Holder holder = getHolder( model, args, proxy );
ClassLoader classloader = model.getClassLoader();
SystemContext system = getSystemContext();
ContextManagerInvocationHandler handler =
@@ -254,7 +254,7 @@
else
{
CompositionModel model = (CompositionModel) provider;
- return getManager( model, args );
+ return getManager( model, args, proxy );
}

/*
@@ -408,37 +408,26 @@
}
}

- private Manager getManager( CompositionModel model, Object[] args )
throws Exception
+ private Holder getHolder( CompositionModel model, Object[] args, Object
owner ) throws Exception
+ {
+ return (Holder) getManager( model, args, owner );
+ }
+
+ private Manager getManager( CompositionModel model, Object[] args,
Object owner ) throws Exception
{
CompositionController controller = model.getCompositionController();
if( null == args )
{
- return controller.getManager( model );
+ return controller.getManager( owner, model );
}
else if( args.length == 0 )
{
- return controller.getManager( model );
+ return controller.getManager( owner, model );
}
else
{
- return controller.getManager( model, args[0] );
+ return controller.getManager( owner, model, args[0] );
}
}

- private Holder getHolder( CompositionModel model, Object[] args ) throws
Exception
- {
- CompositionController controller = model.getCompositionController();
- if( null == args )
- {
- return (Holder) controller.getHolder( model, null );
- }
- else if( args.length == 0 )
- {
- return (Holder) controller.getHolder( model, null );
- }
- else
- {
- return (Holder) controller.getHolder( model, args[0] );
- }
- }
}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/management/AvailabilityEvent.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/management/AvailabilityEvent.java
Tue Apr 26 06:01:25 2005
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2005 Stephen 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.composition.management;
+
+import java.util.EventObject;
+
+/**
+ * Exception thrown if a requested resource is unavailable.
+ *
+ */
+public class AvailabilityEvent extends EventObject
+{
+ private final boolean m_available;
+
+ /**
+ * Creation of a new availability event.
+ * @param source the subject object
+ * @param available if TRUE the object is available otherwise
+ * the object is no longer available and consuming systems should
+ * release any reference to the source and this event
+ */
+ public AvailabilityEvent( Object source, boolean available )
+ {
+ super( source );
+ m_available = available;
+ }
+
+ public boolean isAvailable()
+ {
+ return m_available;
+ }
+}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/management/DefaultManager.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/management/DefaultManager.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/management/DefaultManager.java
Tue Apr 26 06:01:25 2005
@@ -25,63 +25,89 @@
import java.util.List;
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.composition.state.*;
+import net.dpml.composition.models.CompositionModel;
+import net.dpml.composition.control.Holder;
+
+import net.dpml.activity.Executable;
+import net.dpml.activity.Startable;

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.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.control.Monitor;
+import net.dpml.parts.control.LifecycleException;
+import net.dpml.parts.state.StateEvent;
+import net.dpml.parts.state.StateListener;
+
/**
* The State interface is an interface representing an immutable state of
* a component instance.
*
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
*/
-public class DefaultManager extends Observable implements Manager
+public class DefaultManager extends Holder implements Manager
{
- private final DefaultState m_graph;
+ 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;
- private Map m_handlers = new Hashtable();
- private Logger m_logger;

- /**
- * Creation of a new DefaultManager.
- * @param graph the root state of a state graph
- * @param logger the assigned logging channel
- * @param listener a change listener
- * @param instance the managed instance
- */
- public DefaultManager( DefaultState graph, Logger logger, Object
instance )
+ public DefaultManager(
+ Monitor monitor, CompositionModel model, Object key, Object owner )
+ throws Exception
{
- if( null == logger )
- {
- throw new NullPointerException( "logger" );
- }
- if( null == instance )
+ super( monitor, model, key );
+
+ m_owner = owner;
+ m_graph = resolveStateGraph( model.getDeploymentClass() );
+ initialize();
+ }
+
+ public String getName()
+ {
+ return getClass().getName();
+ }
+
+ public Object getInstance() throws ResourceUnavailableException
+ {
+ if( null == m_instance )
{
- throw new NullPointerException( "instance" );
+ String id = getURI().toString();
+ throw new ResourceUnavailableException( id );
}
- if( null == graph )
+ else
{
- throw new NullPointerException( "graph" );
+ return m_instance;
}
- m_instance = instance;
- m_logger = logger;
- m_graph = graph;
+ }
+
+ public void addStateListener( StateListener listener )
+ {
+ m_listeners.add( listener );
}

/**
@@ -147,7 +173,7 @@
* If the root state is not terminal the implementation will invoke a
* transiton named "initalize". If the transition results in a modified
* state, the implementation will continue to recursivly invoke
- * initialize operations until a non-initializable state is established
+ * initialize operations until a non-initializing state is established
* as the current state.
*
* @return the initialized object
@@ -155,8 +181,16 @@
* @exception Exception if an error is raised by a handler assigned to
* and invoked initialization transition
*/
- public synchronized Object initialize() throws ValidationException,
Exception
+ public synchronized void initialize() throws ValidationException,
Exception
{
+ if( null != m_instance )
+ {
+ return;
+ }
+
+
+ m_instance = getModel().getCompositionController().incarnate( this );
+
List visited = new LinkedList();
DefaultState graph = getStateGraph();
validate( graph );
@@ -201,11 +235,49 @@
throw new RecursiveInitializationException( error );
}
}
- return m_instance;
+
+ 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 );
+ }
}

private void validate( DefaultState state ) throws ValidationException
{
+ if( null == state )
+ {
+ throw new NullPointerException( "state" );
+ }
DefaultTransition init = state.getInitialization();
if( null != init )
{
@@ -414,27 +486,29 @@
DefaultState state = getCurrentState();
URI handler = transition.getHandlerURI();
DefaultState target = transition.getTransitionTarget();
- if( state.equals( target ) )
+
+ if( getMonitor().isDebugEnabled() )
{
- return false;
+ final String message =
+ "applying ["
+ + handler.toString()
+ + "] to state ["
+ + state.getName()
+ + "]";
+ getMonitor().debug( message );
}
- else
+
+ execution( handler, state, target );
+
+ if( state != target )
{
- if( getLogger().isLoggable( Level.FINE ) )
- {
- final String message =
- "applying ["
- + handler.toString()
- + "] to state ["
- + state.getName()
- + "]";
- getLogger().fine( message );
- }
- Logger logger = getLogger();
- execution( handler, state, target, logger );
setState( target );
return true;
}
+ else
+ {
+ return false;
+ }
}

/**
@@ -457,16 +531,15 @@
}
else
{
- if( getLogger().isLoggable( Level.FINE ) )
+ if( getMonitor().isDebugEnabled() )
{
final String message =
"executing operation ["
+ handler.toString()
+ "]";
- getLogger().fine( message );
+ getMonitor().debug( message );
}
- Logger logger = getLogger();
- execution( handler, state, null, logger );
+ execution( handler, state, null );
}
}

@@ -487,10 +560,9 @@
* @param handler the object describing the handler
* @param state the current state
* @param target the target of the transition
- * @param logger the assigned logging channel
* @excetion Exception of an invocation or handler error occurs
*/
- private void execution( URI uri, State state, State target, Logger
logger ) throws Exception
+ private void execution( URI uri, State state, State target ) throws
Exception
{
if( null == uri )
{
@@ -513,7 +585,7 @@
Class c = m_instance.getClass();
Method method = locateMethod( c, spec );
Class[] parameters = method.getParameterTypes();
- Object[] args = resolveArguments( parameters, state, target,
logger );
+ Object[] args = resolveArguments( parameters, state, target
);
method.invoke( m_instance, args );
}
}
@@ -534,7 +606,7 @@
Class c = h.getClass();
Method method = locateMethod( c, "handle" );
Class[] parameters = method.getParameterTypes();
- Object[] args = resolveArguments( parameters, state, target,
logger );
+ Object[] args = resolveArguments( parameters, state, target
);
method.invoke( h, args );
}
}
@@ -556,10 +628,9 @@
* @param parameters the array of method parameter arguments
* @param state the current state
* @param target the transition target state (possible null when handling
operations)
- * @param logger the assinged logging channel
* @return the populated object array
*/
- private Object[] resolveArguments( Class[] parameters, State state,
State target, Logger logger )
+ private Object[] resolveArguments( Class[] parameters, State state,
State target )
{
boolean firstStateAssigned = false;
Object[] args = new Object[ parameters.length ];
@@ -568,7 +639,8 @@
Class c = parameters[i];
if( Logger.class.isAssignableFrom( c ) )
{
- args[i] = logger;
+ CompositionModel model = getModel();
+ args[i] = model.getCompositionController().getLogChannel(
model );
}
else if( State.class.isAssignableFrom( c ) )
{
@@ -617,20 +689,32 @@
{
if( false == m_state.equals( state ) )
{
- if( getLogger().isLoggable( Level.FINE ) )
+ if( getMonitor().isDebugEnabled() )
{
final String message =
- "changing state from '"
- + m_state.getName()
- + "' to '"
- + state.getName()
- + "'";
- getLogger().fine( 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 event = new ChangeEvent( this );
- notifyObservers( event );
+ 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 );
}
}

@@ -651,11 +735,13 @@
{
// recusive termination path
String error = e.getMessage();
- getLogger().log( Level.WARNING, error );
+ getMonitor().warn( error );
}
finally
{
m_state = null;
+ AvailabilityEvent event = new AvailabilityEvent( m_instance,
false );
+ notifyObservers( event );
}
}

@@ -686,7 +772,7 @@
catch( Exception e )
{
flag = false;
- getLogger().log( Level.WARNING, "Ignoring termination
handler error", e );
+ getMonitor().warn( "Ignoring termination handler error",
e );
}
}
else
@@ -718,15 +804,6 @@
}

/**
- * Utility operation to return the logging channel assigned by the
container.
- * @return the logging channel
- */
- protected Logger getLogger()
- {
- return m_logger;
- }
-
- /**
* Utility to locate athe first public method with the supplied name in
the
* supplied class.
* @param c the class to introspect
@@ -763,4 +840,46 @@
{
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/management/ValueManager.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/management/ValueManager.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/management/ValueManager.java
Tue Apr 26 06:01:25 2005
@@ -18,6 +18,7 @@

package net.dpml.composition.management;

+import java.net.URI;
import java.util.Map.Entry;

import net.dpml.parts.state.Manager;
@@ -43,15 +44,24 @@
m_model = model;
}

+ public String getName()
+ {
+ return getClass().getName();
+ }
+
+ public URI getURI()
+ {
+ return m_model.getURI();
+ }
+
/**
* Initialize the component.
*/
- public Object initialize() throws Exception
+ public void initialize() throws Exception
{
if( false == m_initialized )
{
m_initialized = true;
- return m_model.getValue();
}
else
{
@@ -62,6 +72,25 @@
}

/**
+ * Return the instance managed by this manager.
+ * @return the managed instance
+ */
+ public Object getInstance()
+ {
+ if( m_initialized )
+ {
+ return m_model.getValue();
+ }
+ else
+ {
+ final String error =
+ "Manager has not been initialized.";
+ throw new IllegalStateException( error );
+ }
+ }
+
+
+ /**
* Return the current state of the component.
* @return the current state
*/

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/models/AbstractModel.java
Tue Apr 26 06:01:25 2005
@@ -87,18 +87,18 @@
/**
* Return a Manager for the default instance.
*/
- public Manager getManager() throws Exception
+ public Manager getManager( Object owner ) throws Exception
{
- return getCompositionController().getManager( this );
+ return getCompositionController().getManager( owner, this );
}

/**
* Return a Manager for an identified instance.
* @param id the instance identity
*/
- public Manager getManager( Object id ) throws Exception
+ public Manager getManager( Object owner, Object id ) throws Exception
{
- return getCompositionController().getManager( this, id );
+ return getCompositionController().getManager( owner, this, id );
}

//--------------------------------------------------------------

Modified:
development/main/metro/composition/part/src/main/net/dpml/composition/state/DefaultState.java
==============================================================================
---
development/main/metro/composition/part/src/main/net/dpml/composition/state/DefaultState.java
(original)
+++
development/main/metro/composition/part/src/main/net/dpml/composition/state/DefaultState.java
Tue Apr 26 06:01:25 2005
@@ -341,7 +341,7 @@
{
throw new DuplicateKeyException( key );
}
- validateTransition( "transition", key, uri, target );
+ validateTransition( TRANSITION, key, uri, target );
DefaultTransition transition = new DefaultTransition( uri, target );
m_transitions.put( key, transition );
}
@@ -369,6 +369,21 @@
* fired. This process will continue until a state is established that
does not
* delcare an initializor.
*
+ * @param target the target initialization state
+ */
+ public void setInitialization( URI uri )
+ {
+ setInitialization( uri, this );
+ }
+
+ /**
+ * Optionally set the initializer for this state. During the state
manager
+ * initialization phase an initializer declared on the assigned state
model
+ * will be invoked. If the current state is modified as a result of
invocation
+ * of an initializer, any initializer associated with the new state will
be
+ * fired. This process will continue until a state is established that
does not
+ * delcare an initializor.
+ *
* @param uri the uri identifying the handler to be assigned as the
handler
* of the initialization action
* @param target the target initialization state
@@ -803,50 +818,71 @@
}
}

- /**
- * Utility operation to test if a supplied state instance is an
- * instance from this state graph.
- *
- * @param state the instance to evalue
- * @return TRUE if the instance is a member else FALSE
- */
- private boolean isaMemberOfGraph( DefaultState state )
- {
- DefaultState[] states = getAllStates();
- for( int i=0; i<states.length; i++ )
- {
- DefaultState s = states[i];
- if( s == state ) return true;
- }
- return false;
- }
-
private void validateTransition( String role, String key, URI uri,
DefaultState target )
{
- if( null == target )
+ validateIsaMember( role, key, target );
+ validateNonNullTarget( role, key, target );
+ if( role.equals( TERMINATOR ) )
{
- throw new NullPointerException( "target" );
+ validateNotSelf( role, key, target );
}
- String line = "";
- String uriLine = "";
- if( null != key )
+ else if( role.equals( TRANSITION ) )
{
- line = "\nKey: " + key;
+ validateNotSelf( role, key, target );
+ validateNonTerminal( role, key, target );
}
- if( null != uri )
+ }
+
+ private void validateNotSelf( String role, String key, DefaultState
target )
+ {
+ if( this == target )
{
- uriLine = "\nURI: " + uri;
+ String keyLine = "";
+ if( null != key )
+ {
+ keyLine = "\nKey: " + key;
+ }
+ final String error =
+ "Cannot add " + role
+ + " because "
+ + "the containing state and target state are the same."
+ + "\nState: " + getName()
+ + "\nTarget: " + target.getName()
+ + keyLine;
+ throw new IllegalArgumentException( error );
}
- if( isTerminal() && ( false == role.equals( TERMINATOR ) ) )
+ }
+
+ private void validateNonTerminal( String role, String key, DefaultState
target )
+ {
+ if( isTerminal() )
{
+ String line = "";
+ String targetLine = "";
+ if( null != key )
+ {
+ line = "\nKey: " + key;
+ }
+ if( null != target )
+ {
+ targetLine = "\nTarget: " + target.getName();
+ }
final String error =
"Cannot add " + role + " to a terminal state."
+ "\nState: " + getName()
- + "\nTarget: " + target.getName()
- + uriLine
+ + targetLine
+ line;
throw new IllegalStateException( error );
}
+ }
+
+ private void validateIsaMember( String role, String key, DefaultState
target )
+ {
+ String keyLine = "";
+ if( null != key )
+ {
+ keyLine = "\nKey: " + key;
+ }
if( false == isaMemberOfGraph( target ) )
{
final String error =
@@ -855,26 +891,48 @@
+ "the declared target state is not a member of the state
graph."
+ "\nState: " + getName()
+ "\nTarget: " + target.getName()
- + uriLine
- + line;
+ + keyLine ;
throw new IllegalArgumentException( error );
}
- if( this == target )
+ }
+
+ private void validateNonNullTarget( String role, String key,
DefaultState target )
+ {
+ String keyLine = "";
+ if( null != key )
+ {
+ keyLine = "\nKey: " + key;
+ }
+ if( null == target )
{
final String error =
- "Cannot add " + role
- + " because "
- + "the containing state and target state are the same."
+ "Cannot add " + role + " due to undefined target."
+ "\nState: " + getName()
- + "\nTarget: " + target.getName()
- + uriLine
- + line;
- throw new IllegalArgumentException( error );
+ + keyLine;
+ throw new NullPointerException( error );
+ }
+ }
+
+ /**
+ * Utility operation to test if a supplied state instance is an
+ * instance from this state graph.
+ *
+ * @param state the instance to evalue
+ * @return TRUE if the instance is a member else FALSE
+ */
+ private boolean isaMemberOfGraph( DefaultState state )
+ {
+ DefaultState[] states = getAllStates();
+ for( int i=0; i<states.length; i++ )
+ {
+ DefaultState s = states[i];
+ if( s == state ) return true;
}
+ return false;
}

- private static final String TERMINATOR = "terminator";
- private static final String INITIALIZER = "initializer";
- private static final String TRANSITION = "transition";
+ public static final String TERMINATOR = "terminator";
+ public static final String INITIALIZER = "initializer";
+ public static final String TRANSITION = "transition";

}

Modified:
development/main/metro/composition/part/src/test/net/dpml/composition/state/DefaultStateTestCase.java
==============================================================================
---
development/main/metro/composition/part/src/test/net/dpml/composition/state/DefaultStateTestCase.java
(original)
+++
development/main/metro/composition/part/src/test/net/dpml/composition/state/DefaultStateTestCase.java
Tue Apr 26 06:01:25 2005
@@ -409,7 +409,7 @@
try
{
m_root.setInitialization( new URI( "system:null" ), null );
- fail( "do not throw NPE" );
+ fail( "No NPE." );
}
catch( NullPointerException e )
{
@@ -437,11 +437,11 @@
try
{
foo.setInitialization( new URI( "method:null" ), m_root );
- fail( "do not throw ISE" );
+ // success
}
catch( IllegalStateException e )
{
- // success
+ fail( "Initializations in terminals are allowed." );
}
}


Modified: development/main/metro/composition/testing/test/build.xml
==============================================================================
--- development/main/metro/composition/testing/test/build.xml (original)
+++ development/main/metro/composition/testing/test/build.xml Tue Apr 26
06:01:25 2005
@@ -218,7 +218,7 @@
name="container"
dest="target/test/managing-container.part">
<parts>
- <component key="test" type="net.dpml.test.state.ManagedComponent"/>
+ <component key="component"
type="net.dpml.test.state.ManagedComponent"/>
</parts>
</component>


Modified:
development/main/metro/composition/testing/test/src/main/net/dpml/test/config/ConfigurableContainer.java
==============================================================================
---
development/main/metro/composition/testing/test/src/main/net/dpml/test/config/ConfigurableContainer.java
(original)
+++
development/main/metro/composition/testing/test/src/main/net/dpml/test/config/ConfigurableContainer.java
Tue Apr 26 06:01:25 2005
@@ -90,16 +90,7 @@
((Configurable)model).configure( conf );
}
}
- Manager manager = model.getManager();
- try
- {
- manager.initialize();
- manager.execute( "execute" );
- }
- finally
- {
- manager.terminate();
- }
+ model.getController().resolve( model );
}

private Logger getLogger()

Modified:
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagedComponent.java
==============================================================================
---
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagedComponent.java
(original)
+++
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagedComponent.java
Tue Apr 26 06:01:25 2005
@@ -26,17 +26,20 @@

import javax.swing.event.ChangeListener;

-import net.dpml.parts.state.State;
import net.dpml.composition.state.DefaultState;
-import net.dpml.composition.management.DefaultManager;
+
+import net.dpml.parts.state.State;
+import net.dpml.parts.state.StateEvent;
+import net.dpml.parts.state.StateListener;

/**
* Experimental component dealing with state management.
*
* @author <a href="mailto:info AT dpml.net";>The Digital Product Meta
Library</a>
*/
-public class ManagedComponent implements Observer
+public class ManagedComponent implements StateListener
{
+
// ------------------------------------------------------------------
// static
// ------------------------------------------------------------------
@@ -61,40 +64,36 @@
public ManagedComponent( final Logger logger, Context context )
{
m_logger = logger;
- context.addObserver( this );
+ context.addStateListener( this );
}

- public void update( Observable observable, Object event )
+ /**
+ * Notify the listener of a state change. The supplied event
+ * contains the originating state and the state that is about to
+ * be committed.
+ *
+ * @param event the state change event
+ */
+ public void stateChanged( final StateEvent event )
{
- m_logger.info( "# event: " + event );
+ State source = event.getFromState();
+ State destination = event.getToState();
+ final String message =
+ "transitioning from '"
+ + source.getName()
+ + "' to '"
+ + destination.getName()
+ + "'";
+ m_logger.info( message );
}

// ------------------------------------------------------------------
// concerns
// ------------------------------------------------------------------

- public class Controller extends DefaultManager
- {
- public Controller( Logger logger, ManagedComponent instance )
- {
- super( COMPONENT_STATE_MODEL, logger, instance );
- }
-
- //
- // Override the default initialize method with an demo of the
- // optional registration of a generic handler.
- //
-
- public Object initialize() throws Exception
- {
- addHandler( "terminate", GENERIC_HANDLER );
- return super.initialize();
- }
- }
-
public interface Context
{
- void addObserver( Observer observer );
+ void addStateListener( StateListener listener );
}

// ------------------------------------------------------------------
@@ -147,7 +146,7 @@
buffer.append( "\nState Model:" );
buffer.append( "\nCurrent State: " + state.getName() );
buffer.append( "\n-------------------------------------------------"
);
- buffer.append( COMPONENT_STATE_MODEL.list() );
+ buffer.append( STATE_GRAPH.list() );
buffer.append( "\n-------------------------------------------------"
);
getLogger().info( buffer.toString() );
}
@@ -156,7 +155,7 @@
// static utilities
// ------------------------------------------------------------------

- private static final DefaultState COMPONENT_STATE_MODEL = new
DefaultState();
+ public static final DefaultState STATE_GRAPH = new DefaultState();

static
{
@@ -164,7 +163,7 @@
// construct a state graph
//

- DefaultState root = COMPONENT_STATE_MODEL;
+ DefaultState root = STATE_GRAPH;
DefaultState initialized = root.addState( "initialized" );
DefaultState available = root.addState( "available" );
DefaultState started = available.addState( "started" );
@@ -172,7 +171,7 @@
DefaultState terminated = root.addTerminalState( "terminated" );

//
- // create the handler declarations and add then under transitions
+ // create the handler declarations
//

try
@@ -185,7 +184,7 @@
//

root.setInitialization( initialized );
- root.setTerminator( new URI( "handler:terminate" ), terminated );
+ root.setTerminator( new URI( "method:null" ), terminated );
started.setTerminator( new URI( "method:stop" ), stopped );

//
@@ -206,7 +205,7 @@
}
catch( URISyntaxException e )
{
- e.printStackTrace(); // will not happen
+ // will not happen
}
}


Modified:
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagingContainer.java
==============================================================================
---
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagingContainer.java
(original)
+++
development/main/metro/composition/testing/test/src/main/net/dpml/test/state/ManagingContainer.java
Tue Apr 26 06:01:25 2005
@@ -30,14 +30,14 @@

import net.dpml.composition.state.DefaultState;

-import net.dpml.composition.management.DefaultManager;
+import net.dpml.activity.Executable;

/**
* Demonstration of a component that manages the state of a contained part.
*
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
*/
-public class ManagingContainer
+public class ManagingContainer implements Executable
{
//------------------------------------------------------------------
// static
@@ -76,7 +76,7 @@
public void execute() throws Exception
{
Parts parts = getParts();
- Manager manager = parts.selectTestManager();
+ Manager manager = parts.selectComponentManager();
manager.initialize();
manager.apply( "start" );
manager.execute( "audit" );
@@ -99,32 +99,6 @@

public interface Parts
{
- Manager selectTestManager();
- }
-
- public class Controller extends DefaultManager
- {
- public Controller( Logger logger, ManagingContainer instance )
- {
- super( createStateModel(), logger, instance );
- }
- }
-
- private static DefaultState createStateModel()
- {
- DefaultState root = new DefaultState();
- DefaultState initialized = root.addState( "initialized" );
- try
- {
- root.setInitialization( new URI( "method:execute" ), initialized
);
- }
- catch( Throwable e )
- {
- e.printStackTrace(); // will not happen
- }
- finally
- {
- return root;
- }
+ Manager selectComponentManager();
}
}

Modified:
development/main/metro/composition/testing/test/src/test/net/dpml/composition/testing/CompositeTestCase.java
==============================================================================
---
development/main/metro/composition/testing/test/src/test/net/dpml/composition/testing/CompositeTestCase.java
(original)
+++
development/main/metro/composition/testing/test/src/test/net/dpml/composition/testing/CompositeTestCase.java
Tue Apr 26 06:01:25 2005
@@ -69,8 +69,8 @@
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( "acme-bad-widget.part" );
Model model = helper.getCompositionManager().addPart( uri, "acme" );
- Manager manager = model.getManager();
- AcmeContainer container = (AcmeContainer) manager.initialize();
+ Controller controller = model.getController();
+ AcmeContainer container = (AcmeContainer) controller.resolve( model,
null, false );
try
{
container.execute();
@@ -81,19 +81,18 @@
}
finally
{
- manager.terminate();
+ controller.release( container );
helper.dispose();
}
}

private void executeTestOnPart( String path ) throws Exception
{
- CompositionHelper helper = new CompositionHelper();
+ CompositionHelper helper = new CompositionHelper( false );
URI uri = helper.toURI( path );
Model model = helper.getCompositionManager().addPart( uri, "acme" );
-
- Manager manager = model.getManager();
- AcmeContainer container = (AcmeContainer) manager.initialize();
+ Controller controller = model.getController();
+ AcmeContainer container = (AcmeContainer) controller.resolve( model,
null, false );

try
{
@@ -101,8 +100,7 @@
}
finally
{
- manager.terminate();
- //controller.release( container );
+ controller.release( container );
helper.dispose();
}
}

Modified:
development/main/metro/composition/testing/test/src/test/net/dpml/test/config/ConfigurationTestCase.java
==============================================================================
---
development/main/metro/composition/testing/test/src/test/net/dpml/test/config/ConfigurationTestCase.java
(original)
+++
development/main/metro/composition/testing/test/src/test/net/dpml/test/config/ConfigurationTestCase.java
Tue Apr 26 06:01:25 2005
@@ -48,20 +48,9 @@
CompositionHelper helper = new CompositionHelper();
URI uri = helper.toURI( "configurable-container.part" );
Model model = helper.getCompositionManager().addPart( uri );
- Manager manager = model.getManager();
-
- //Controller controller = model.getController();
- //Entry entry = controller.create( model );
- //ConfigurableContainer container = (ConfigurableContainer)
entry.getValue();
- try
- {
- manager.initialize();
- manager.execute( "execute" );
- }
- finally
- {
- manager.terminate();
- helper.dispose();
- }
+ Controller controller = model.getController();
+ ConfigurableContainer container = (ConfigurableContainer)
controller.resolve( model, null, false );
+ controller.release( container );
+ helper.dispose();
}
}

Modified:
development/main/metro/composition/testing/test/src/test/net/dpml/test/state/ManagementTestCase.java
==============================================================================
---
development/main/metro/composition/testing/test/src/test/net/dpml/test/state/ManagementTestCase.java
(original)
+++
development/main/metro/composition/testing/test/src/test/net/dpml/test/state/ManagementTestCase.java
Tue Apr 26 06:01:25 2005
@@ -70,7 +70,7 @@
CompositionHelper helper = new CompositionHelper( false );
URI uri = helper.toURI( "managing-container.part" );
Model model = helper.getCompositionManager().getModel( uri );
- Manager manager = model.getManager();
+ Manager manager = model.getManager( this );
try
{
manager.initialize();
@@ -86,6 +86,6 @@
CompositionHelper helper = new CompositionHelper( false );
URI uri = helper.toURI( "managed-component.part" );
Model model = helper.getCompositionManager().getModel( uri );
- return model.getManager();
+ return model.getManager( this );
}
}

Modified:
development/main/metro/parts/src/main/net/dpml/parts/control/Monitor.java
==============================================================================
--- development/main/metro/parts/src/main/net/dpml/parts/control/Monitor.java
(original)
+++ development/main/metro/parts/src/main/net/dpml/parts/control/Monitor.java
Tue Apr 26 06:01:25 2005
@@ -73,6 +73,12 @@
void warn( String message );

/**
+ * Log the supplied info level message.
+ * @param message the message to log
+ */
+ void warn( String message, Throwable throwable );
+
+ /**
* Log the supplied error level message.
* @param message the message to log
* @param throwable the exception

Modified:
development/main/metro/parts/src/main/net/dpml/parts/model/Model.java
==============================================================================
--- development/main/metro/parts/src/main/net/dpml/parts/model/Model.java
(original)
+++ development/main/metro/parts/src/main/net/dpml/parts/model/Model.java
Tue Apr 26 06:01:25 2005
@@ -51,12 +51,12 @@
/**
* Return a Manager for the default instance.
*/
- Manager getManager() throws Exception;
+ Manager getManager( Object owner ) throws Exception;

/**
* Return a Manager for an identified instance.
* @param id the instance identity
*/
- Manager getManager( Object id ) throws Exception;
+ Manager getManager( Object owner, Object id ) throws Exception;

}

Modified:
development/main/metro/parts/src/main/net/dpml/parts/state/Manager.java
==============================================================================
--- development/main/metro/parts/src/main/net/dpml/parts/state/Manager.java
(original)
+++ development/main/metro/parts/src/main/net/dpml/parts/state/Manager.java
Tue Apr 26 06:01:25 2005
@@ -18,17 +18,26 @@

package net.dpml.parts.state;

+import net.dpml.parts.control.Control;
+
/**
* The Manager interface is an interface representing a component controller.
*
* @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
*/
-public interface Manager
+public interface Manager extends Control
{
/**
+ * Return the instance managed by this manager.
+ * @return the managed instance
+ * @exception ResourceUnavailableException if the object is not available
+ */
+ Object getInstance() throws ResourceUnavailableException;
+
+ /**
* Initialize the component.
*/
- Object initialize() throws Exception;
+ void initialize() throws Exception;

/**
* Return the current state of the component.

Added:
development/main/metro/parts/src/main/net/dpml/parts/state/ResourceUnavailableException.java
==============================================================================
--- (empty file)
+++
development/main/metro/parts/src/main/net/dpml/parts/state/ResourceUnavailableException.java
Tue Apr 26 06:01:25 2005
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2005 Stephen 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.parts.state;
+
+
+/**
+ * Exception thrown if a requested resource is unavailable.
+ *
+ */
+public class ResourceUnavailableException extends IllegalStateException
+{
+ /**
+ * Creation of a new unavailable resource exception.
+ * @param message the message
+ * @param cause the causal exception
+ */
+ public ResourceUnavailableException( String message )
+ {
+ super( message );
+ }
+}

Added:
development/main/metro/parts/src/main/net/dpml/parts/state/StateEvent.java
==============================================================================
--- (empty file)
+++
development/main/metro/parts/src/main/net/dpml/parts/state/StateEvent.java
Tue Apr 26 06:01:25 2005
@@ -0,0 +1,59 @@
+/*
+ * 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.parts.state;
+
+import java.util.EventObject;
+
+
+/**
+ * Exception thrown when a recursive termination sequence is encountered.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ */
+public class StateEvent extends EventObject
+{
+ private final State m_from;
+ private final State m_to;
+
+ /**
+ * Construct a new <code>StateEvent</code>.
+ *
+ * @param source the source object
+ * @param from the originating state
+ * @param to the new current state
+ */
+ public StateEvent( final Object source, State from, State to )
+ {
+ super( source );
+ m_from = from;
+ m_to = to;
+ }
+
+ public State getFromState()
+ {
+ return m_from;
+ }
+
+ public State getToState()
+ {
+ return m_to;
+ }
+
+}
+

Added:
development/main/metro/parts/src/main/net/dpml/parts/state/StateListener.java
==============================================================================
--- (empty file)
+++
development/main/metro/parts/src/main/net/dpml/parts/state/StateListener.java
Tue Apr 26 06:01:25 2005
@@ -0,0 +1,35 @@
+/*
+ * 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.parts.state;
+
+/**
+ * Exception thrown when a recursive termination sequence is encountered.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ */
+public interface StateListener
+{
+ /**
+ * Notify the listener of a state change.
+ *
+ * @param event the state change event
+ */
+ void stateChanged( final StateEvent event );
+}
+



  • svn commit: r2412 - 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/management composition/control/src/main/net/dpml/composition/models composition/control/src/test/net/dpml/composition/management composition/part/src/main/net/dpml/composition/state composition/part/src/test/net/dpml/composition/state composition/testing/test composition/testing/test/src/main/net/dpml/test/config composition/testing/test/src/main/net/dpml/test/state composition/testing/test/src/test/net/dpml/composition/testing composition/testing/test/src/test/net/dpml/test/config composition/testing/test/src/test/net/dpml/test/state parts/src/main/net/dpml/parts/control parts/src/main/net/dpml/parts/model parts/src/main/net/dpml/parts/state, mcconnell, 04/25/2005

Archive powered by MHonArc 2.6.24.

Top of Page