Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2983 - in development/main: metro metro/central/src/main/net/dpml/metro/central metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/builder/src/main/net/dpml/composition/builder/datatypes metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/runtime metro/part/src/main/net/dpml/part/control metro/part/src/main/net/dpml/part/manager transit/core/tools/src/main/net/dpml/transit/tools

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: r2983 - in development/main: metro metro/central/src/main/net/dpml/metro/central metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/builder/src/main/net/dpml/composition/builder/datatypes metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/runtime metro/part/src/main/net/dpml/part/control metro/part/src/main/net/dpml/part/manager transit/core/tools/src/main/net/dpml/transit/tools
  • Date: Wed, 06 Jul 2005 17:57:58 -0400

Author: mcconnell AT dpml.net
Date: Wed Jul 6 17:57:58 2005
New Revision: 2983

Added:

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/DependencyGraph.java
development/main/metro/part/src/main/net/dpml/part/manager/Consumer.java
Modified:

development/main/metro/central/src/main/net/dpml/metro/central/MetroHelper.java

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java

development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.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/CompositionControllerContext.java

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

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/AbstractHandler.java

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

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/CompositionHandler.java

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ContextMap.java

development/main/metro/composition/control/src/main/net/dpml/composition/runtime/PartsTable.java
development/main/metro/index.xml

development/main/metro/part/src/main/net/dpml/part/control/ControllerContext.java
development/main/metro/part/src/main/net/dpml/part/manager/Container.java

development/main/transit/core/tools/src/main/net/dpml/transit/tools/AntAdapter.java
Log:
o addition of container assembly capabilities including management of startup
and shutdown sequencing

Modified:
development/main/metro/central/src/main/net/dpml/metro/central/MetroHelper.java
==============================================================================
---
development/main/metro/central/src/main/net/dpml/metro/central/MetroHelper.java
(original)
+++
development/main/metro/central/src/main/net/dpml/metro/central/MetroHelper.java
Wed Jul 6 17:57:58 2005
@@ -73,6 +73,11 @@

public MetroHelper() throws Exception
{
+ this( new LoggingAdapter( "metro" ) );
+ }
+
+ public MetroHelper( Logger ) throws Exception
+ {
String title = "Metro Part Handler.";
String type = "part";
Properties properties = new Properties();
@@ -81,7 +86,6 @@
{
properties.put( "work.dir", dir );
}
- Logger logger = new LoggingAdapter( "metro" );
DefaultContentModel model = new DefaultContentModel( logger, null,
type, title, properties );
ControllerContext context = new CompositionControllerContext( model
);
m_controller = new CompositionController( context );

Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/ComponentBuilderTask.java
Wed Jul 6 17:57:58 2005
@@ -32,12 +32,17 @@
import net.dpml.part.part.Part;
import net.dpml.part.part.PartHolder;
import net.dpml.part.part.PartReference;
+import net.dpml.part.control.ControllerContext;
+import net.dpml.part.manager.Component;
+import net.dpml.part.manager.Container;

import net.dpml.composition.builder.datatypes.CategoriesDataType;
import net.dpml.composition.builder.datatypes.ConfigurationDataType;
import net.dpml.composition.builder.datatypes.ContextDataType;
import net.dpml.composition.builder.datatypes.ParametersDataType;
import net.dpml.composition.builder.datatypes.PartsDataType;
+import net.dpml.composition.control.CompositionController;
+import net.dpml.composition.control.CompositionControllerContext;
import net.dpml.composition.data.ClassLoaderDirective;
import net.dpml.composition.data.ClasspathDirective;
import net.dpml.composition.data.ComponentProfile;
@@ -60,6 +65,9 @@
import net.dpml.parameters.Parameters;
import net.dpml.parameters.impl.DefaultParameters;

+import net.dpml.transit.tools.AntAdapter;
+import net.dpml.transit.model.Logger;
+
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -235,7 +243,18 @@
ClassLoaderDirective cld = constructClassLoaderDirective();
ComponentProfile profile = buildComponentProfile( classloader,
cld );

- // ?? ASSEMBLY ??
+ Logger logger = new AntAdapter( this );
+ ControllerContext context =
CompositionControllerContext.newContext( logger );
+ CompositionController controller = new CompositionController(
context );
+ Container container = controller.newContainer( classloader,
profile );
+ Component[] startup = container.getStartupSequence();
+
+ log( "componet: " + profile.getName() );
+ log( "Startup sequence length: " + startup.length );
+ for( int i=0; i<startup.length; i++ )
+ {
+ log( "" + (i+1) + " " + startup[i] );
+ }

URI uri = getDefinition().getArtifactURI( Part.ARTIFACT_TYPE );
if( null == m_output )

Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/datatypes/PartDataType.java
Wed Jul 6 17:57:58 2005
@@ -24,6 +24,7 @@

import net.dpml.composition.builder.PartReferenceBuilder;
import net.dpml.composition.control.CompositionController;
+import net.dpml.composition.control.CompositionControllerContext;
import net.dpml.composition.info.Type;

import net.dpml.part.control.ControllerContext;
@@ -128,7 +129,8 @@
URI uri = getURI();
try
{
- CompositionController handler = new CompositionController();
+ ControllerContext context =
CompositionControllerContext.newContext();
+ CompositionController handler = new CompositionController(
context );
return handler.loadPart( uri );
}
catch( PartNotFoundException pnfe )

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
Wed Jul 6 17:57:58 2005
@@ -42,6 +42,7 @@
import net.dpml.composition.runtime.ValueController;
import net.dpml.composition.runtime.ComponentController;
import net.dpml.composition.runtime.CompositionHandler;
+import net.dpml.composition.runtime.DefaultLogger;

import net.dpml.part.control.ControllerContext;
import net.dpml.part.control.HandlerNotFoundException;
@@ -92,24 +93,25 @@
// constructor
//--------------------------------------------------------------------

- public CompositionController()
- throws ControlException
- {
- this( createDefaultContext() );
- }
-
public CompositionController( ControllerContext context )
throws ControlException
{
super( context );

m_context = context;
- m_logger = m_context.getLogger();
+
+ if( context instanceof CompositionControllerContext )
+ {
+ CompositionControllerContext c = (CompositionControllerContext)
context;
+ m_logger = c.getLogger();
+ }
+ else
+ {
+ m_logger = getLoggerForURI( m_context.getURI() );
+ }
m_valueController = new ValueController( this );
m_componentController = new ComponentController( m_logger, this );
-
- m_logger.info( "metro controller established" );
-
+ m_logger.debug( "metro controller established" );
//m_lifestyleHandler = new LifestyleHandler( m_logger,
m_componentController );
}

@@ -159,7 +161,7 @@
throws IOException, ComponentException, PartNotFoundException,
HandlerNotFoundException, DelegationException
{
- m_logger.debug( "loading component " + uri );
+ m_logger.debug( "loading part " + uri );
Part part = loadPart( uri );
return newComponent( null, part, null );
}
@@ -191,7 +193,9 @@
String defaultName = directive.getKey();
String theName = getName( defaultName, name );
URI id = createURI( partition, theName );
- return new ValueHandler( m_logger, this, classloader, id,
directive, parent );
+ Logger logger = getLoggerForURI( id );
+ logger.debug( "new value" );
+ return new ValueHandler( logger, this, classloader, id,
directive, parent );
}
else if( part instanceof ComponentProfile )
{
@@ -199,8 +203,10 @@
String defaultName = profile.getName();
String theName = getName( defaultName, name );
URI id = createURI( partition, theName );
+ Logger logger = getLoggerForURI( id );
+ logger.debug( "new component" );
ClassLoader loader = getClassLoader( classloader, id,
profile );
- return new CompositionHandler( m_logger, this, loader, id,
profile, parent );
+ return new CompositionHandler( logger, this, loader, id,
profile, parent );
}
else
{
@@ -220,6 +226,52 @@
}
}

+ /**
+ * Construct a new component using the supplied part as the defintion of
the
+ * component type and deployment criteria.
+ *
+ * @param classloader the root classloader
+ * @param part component definition including type and deployment data
+ * @return a new component
+ * @exception ComponentException is an error occurs during component
establishment
+ * @exception HandlerNotFoundException if the part references a handler
but the handler could not be found
+ * @exception DelegationException if an error occurs following handover
of control to a foreign controller
+ * @exception UnsupportedPartTypeException if the component type is
recognized but not supported
+ */
+ public Container newContainer( ClassLoader parent, Part part )
+ throws ComponentException, HandlerNotFoundException,
DelegationException
+ {
+ URI partition = getPartition();
+ if( isRecognizedPart( part ) )
+ {
+ if( part instanceof ComponentProfile )
+ {
+ ComponentProfile profile = (ComponentProfile) part;
+ String name = profile.getName();
+ URI id = createURI( partition, name );
+ return new CompositionHandler( m_logger, this, parent, id,
profile, null );
+ }
+ else
+ {
+ String classname = part.getClass().getName();
+ final String error =
+ "Unsupported part implementation class ["
+ + classname
+ + "] passed to newComponent/3.";
+ throw new UnsupportedPartTypeException( CONTROLLER_URI,
classname, error );
+ }
+ }
+ else
+ {
+ String classname = part.getClass().getName();
+ final String error =
+ "Unsupported part implementation class ["
+ + classname
+ + "] passed to newComponent/2.";
+ throw new UnsupportedPartTypeException( CONTROLLER_URI,
classname, error );
+ }
+ }
+
private ClassLoader getClassLoader( Component component )
{
if( component instanceof ClassLoadingContext )
@@ -450,6 +502,16 @@
}
}

+ private Logger getLoggerForURI( URI uri )
+ {
+ String path = uri.getSchemeSpecificPart();
+ if( path.endsWith( "/" ) )
+ {
+ path = path.substring( 0, path.length() - 1 );
+ }
+ path.replace( '/', '.' );
+ return new DefaultLogger( path );
+ }

static final URI CONTROLLER_URI = setupURI( "@PART-CONTROLLER-URI@" );

@@ -475,6 +537,7 @@
net.dpml.transit.model.Logger logger = new LoggingAdapter(
"metro" );
DefaultContentModel model =
new DefaultContentModel( logger, null, type, title, properties
);
+
return new CompositionControllerContext( model );
}
catch( Throwable e )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionControllerContext.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionControllerContext.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionControllerContext.java
Wed Jul 6 17:57:58 2005
@@ -53,6 +53,33 @@
public class CompositionControllerContext extends WeakEventProducer
implements ControllerContext
{

//----------------------------------------------------------------------------
+ // static
+
//----------------------------------------------------------------------------
+
+ public static ControllerContext newContext()
+ {
+ return newContext( new net.dpml.transit.adapter.LoggingAdapter(
"metro" ) );
+ }
+
+ public static ControllerContext newContext(
net.dpml.transit.model.Logger logger )
+ {
+ try
+ {
+ String title = "Default Composition Context.";
+ String type = "part";
+ Properties properties = new Properties();
+ DefaultContentModel model =
+ new DefaultContentModel( logger, null, type, title, properties
);
+ return new CompositionControllerContext( model );
+ }
+ catch( Throwable e )
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+
//----------------------------------------------------------------------------
// state

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

@@ -334,4 +361,5 @@
super( source, oldDir, newDir );
}
}
+
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionPartHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionPartHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionPartHandler.java
Wed Jul 6 17:57:58 2005
@@ -97,7 +97,8 @@
* implementation will attempt to locate and delegate part loading
requests
* to the foreign handler.
*
- * @return the part estracted from the part handler referenced by the uri
+ * @param the part uri
+ * @return the part estracted from the part referenced by the uri
*/
public Part loadPart( URI uri )
throws PartNotFoundException, IOException, DelegationException
@@ -160,7 +161,7 @@
{
try
{
- PartHandler handler = resolvePartHandler( uri );
+ PartHandler handler = resolvePartHandler( foreign );
return handler.loadPart( holder.getByteArray() );
}
catch( Throwable e )
@@ -262,5 +263,4 @@
return null;
}
}
-
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/AbstractHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/AbstractHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/AbstractHandler.java
Wed Jul 6 17:57:58 2005
@@ -58,6 +58,15 @@
}

/**
+ * Return an array of components providing services to this component.
+ * @return the provider component array
+ */
+ public Component[] getProviders()
+ {
+ return new Component[0];
+ }
+
+ /**
* Return the availability status of the model.
* @return the availability status
*/

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentController.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentController.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentController.java
Wed Jul 6 17:57:58 2005
@@ -47,6 +47,7 @@
import net.dpml.part.control.ControllerRuntimeException;
import net.dpml.part.control.Disposable;
import net.dpml.part.manager.Component;
+import net.dpml.part.manager.Container;
import net.dpml.part.manager.DuplicateKeyException;
import net.dpml.part.state.State;
import net.dpml.part.state.Transition;
@@ -206,6 +207,32 @@
return;
}

+ getLogger().debug( "initialization of " + component.getURI() );
+ if( component instanceof Container )
+ {
+ Container container = (Container) component;
+
+ Component[] parts = container.getStartupSequence();
+ for( int i=0; i<parts.length; i++ )
+ {
+ Component part = parts[i];
+ try
+ {
+ getLogger().debug( "initializing part" + part.getURI() );
+ part.initialize();
+ }
+ catch( Throwable e )
+ {
+ URI uri = getURI();
+ final String error =
+ "Failed to initialize component due to a part
initaliation failure."
+ + "\nContainer: " + component.getURI()
+ + "\nComponent: " + part.getURI();
+ throw new ControlException( uri, error, e );
+ }
+ }
+ }
+
Object instance = getInstance( component );
List visited = new LinkedList();
State graph = component.getStateGraph();
@@ -791,6 +818,30 @@
{
return;
}
+
+ if( component instanceof Container )
+ {
+ Container container = (Container) component;
+ Component[] parts = container.getShutdownSequence();
+ for( int i=0; i<parts.length; i++ )
+ {
+ Component part = parts[i];
+ try
+ {
+ part.terminate();
+ }
+ catch( Throwable e )
+ {
+ URI uri = getURI();
+ final String error =
+ "Failed to terminate a subsidiary part."
+ + "\nContainer: " + component.getURI()
+ + "\nComponent: " + part.getURI();
+ getLogger().warn( error, e );
+ }
+ }
+ }
+
List visited = new LinkedList();
boolean flag = true;
while( flag )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ComponentHandler.java
Wed Jul 6 17:57:58 2005
@@ -64,6 +64,7 @@
import net.dpml.part.state.StateListener;
import net.dpml.part.state.State;
import net.dpml.part.state.ResourceUnavailableException;
+import net.dpml.part.manager.Consumer;
import net.dpml.part.manager.Component;
import net.dpml.part.manager.ClassLoadingContext;
import net.dpml.part.manager.ComponentException;
@@ -81,9 +82,11 @@
* @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 ComponentHandler extends WeakEventProducer implements
Component, ClassLoadingContext, Configurable, Parameterizable
+public class ComponentHandler extends WeakEventProducer
+ implements Component, Consumer, ClassLoadingContext, Configurable,
Parameterizable
{
private final Map m_proxies = new WeakHashMap();
+ private final DependencyGraph m_dependencies = new DependencyGraph();

private final Logger m_logger;
private final ComponentProfile m_profile;
@@ -115,6 +118,11 @@
{
super();

+ if( null != parent )
+ {
+ addShutdownHook( this );
+ }
+
m_logger = logger;
m_controller = controller;
m_classloader = classloader;
@@ -144,7 +152,8 @@
PartReference reference = parts[i];
String key = reference.getKey();
Part part = reference.getPart();
- getPartsTable().addPart( key, part );
+ Component component = getPartsTable().addComponent( key, part );
+ m_dependencies.add( component );
}

//
@@ -183,6 +192,35 @@
}
}

+ /**
+ * Return the startup sequence for the set of components contained
+ * within the container.
+ * @return the startup sequence
+ */
+ public Component[] getStartupSequence()
+ {
+ return m_dependencies.getStartupGraph();
+ }
+
+ /**
+ * Return the shudown sequence for the set of components contained
+ * within the container.
+ * @return the shutdown sequence
+ */
+ public Component[] getShutdownSequence()
+ {
+ return m_dependencies.getShutdownGraph();
+ }
+
+ /**
+ * Return an array of components providing services to this component.
+ * @return the provider component array
+ */
+ public Component[] getProviders()
+ {
+ return m_context.getProviders();
+ }
+
public ClassLoader getClassLoader()
{
return m_classloader;
@@ -392,6 +430,7 @@
*/
public void terminate()
{
+ getLogger().debug( "terminating" );
m_manager.terminate( this );
}

@@ -757,4 +796,38 @@
throw new ServiceClassNotFoundException( type, classname );
}
}
+
+ /**
+ * Create a shutdown hook that will trigger shutdown of the supplied
plugin.
+ * @param thread the application thread
+ */
+ private static void addShutdownHook( final Component component )
+ {
+ //
+ // Create a shutdown hook to trigger clean disposal of the
+ // component.
+ //
+
+ Runtime.getRuntime().addShutdownHook(
+ new Thread()
+ {
+ public void run()
+ {
+ try
+ {
+ component.terminate();
+ }
+ catch( Throwable e )
+ {
+ // ignore it
+ }
+ finally
+ {
+ System.runFinalization();
+ }
+ }
+ }
+ );
+ }
+
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/CompositionHandler.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/CompositionHandler.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/CompositionHandler.java
Wed Jul 6 17:57:58 2005
@@ -100,4 +100,5 @@
return component;
}
}
+
}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ContextMap.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ContextMap.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/ContextMap.java
Wed Jul 6 17:57:58 2005
@@ -23,6 +23,7 @@
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.ArrayList;

import net.dpml.part.control.Controller;
import net.dpml.part.control.DelegationException;
@@ -211,4 +212,28 @@
return entry;
}
}
+
+ /**
+ * Return an array of components providing services to the component.
+ * @return the provider component array
+ */
+ public synchronized Component[] getProviders()
+ {
+ ArrayList list = new ArrayList();
+ Component[] components = getComponents();
+ for( int i=0; i<components.length; i++ )
+ {
+ Component component = components[i];
+ if( component instanceof ComponentHandler )
+ {
+ list.add( component );
+ }
+ }
+ return (Component[]) list.toArray( new Component[ list.size() ] );
+ }
+
+ private Component[] getComponents()
+ {
+ return (Component[]) values().toArray( new Component[0] );
+ }
}

Added:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/DependencyGraph.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/DependencyGraph.java
Wed Jul 6 17:57:58 2005
@@ -0,0 +1,370 @@
+/*
+ * Copyright 2004-2005 Stephen J. McConnell.
+ * Copyright 2004 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.composition.runtime;
+
+import java.util.ArrayList;
+
+import net.dpml.part.manager.Component;
+import net.dpml.part.manager.Consumer;
+
+/**
+ * <p>Utility class to aquire an ordered graph of
+ * consumers and providers components.</p>
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: DependencyGraph.java 259 2004-10-30 07:24:40Z mcconnell $
+ */
+public class DependencyGraph
+{
+ /**
+ * Parent Map. Components in the parent Map are potential Providers for
+ * services if no component in the current graph satisfies a dependency.
+ */
+ private final DependencyGraph m_parent;
+
+ /**
+ * The set of components declared by the container as available. Used
when
+ * searching for providers/consumers.
+ */
+ private final ArrayList m_components = new ArrayList();
+
+ /**
+ * The child {@link DependencyGraph}objects. Possible consumers of
services
+ * in this assembly.
+ */
+ private final ArrayList m_children = new ArrayList();
+
+ /**
+ * holds the components assembled in order to track circular deps etc.
+ */
+ private ArrayList m_inProgress = new ArrayList();
+
+ /**
+ * Creation of a new empty dependency graph.
+ */
+ public DependencyGraph()
+ {
+ this( null );
+ }
+
+ /**
+ * Creation of a new dependecy graph holding a reference to a parent
graph.
+ * Component instances in the parent graph are potential providers for
+ * services if no component in current assembly satisfies a dependency.
+ *
+ * @param parent the parent graph
+ */
+ public DependencyGraph( final DependencyGraph parent )
+ {
+ m_parent = parent;
+ }
+
+ /**
+ * Addition of a consumer dependency graph.
+ *
+ * @param child the child map
+ */
+ public void addChild( final DependencyGraph child )
+ {
+ m_children.add( child );
+ }
+
+ /**
+ * Removal of a consumer dependency graph.
+ *
+ * @param child the child map
+ */
+ public void removeChild( final DependencyGraph child )
+ {
+ m_children.remove( child );
+ }
+
+ /**
+ * Add a component to current dependency graph.
+ *
+ * @param component the component to add to the graph
+ */
+ public void add( final Component component )
+ {
+ if( !m_components.contains( component ) )
+ {
+ m_components.add( component );
+ }
+ }
+
+ /**
+ * Remove a component from the dependency graph.
+ *
+ * @param component the component to remove
+ */
+ public void remove( final Component component )
+ {
+ m_components.remove( component );
+ }
+
+ /**
+ * Get the serilized graph of objects required when
+ * starting up the target. This makes sure that all providers are
+ * established before their coresponding consumers in the graph.
+ *
+ * @return the ordered list of components
+ */
+ public Component[] getStartupGraph()
+ {
+ try
+ {
+ return walkGraph( true );
+ }
+ catch ( Throwable e )
+ {
+ final String error = "Unexpect error while resolving startup
graph.";
+ throw new RuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Get the serilized graph of instances required
+ * when shutting down all the components. This makes sure that all
consumer
+ * shutdown actions occur before their coresponding providers in graph.
+ *
+ * @return the ordered list of component instances
+ */
+ public Component[] getShutdownGraph()
+ {
+ try
+ {
+ return walkGraph( false );
+ }
+ catch ( Throwable e )
+ {
+ final String error = "Unexpect error while resolving shutdown
graph.";
+ throw new RuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Get the serilized graph of instances that use services of the
specified component.
+ *
+ * @param component the provider component
+ * @return the ordered list of consumer components
+ */
+ public Component[] getConsumerGraph( final Component provider )
+ {
+ if( m_parent != null )
+ {
+ return m_parent.getConsumerGraph( provider );
+ }
+ try
+ {
+ Component[] graph = getComponentGraph( provider, false );
+ return referencedComponents( provider, graph );
+ }
+ catch ( Throwable e )
+ {
+ final String error = "Unexpect error while resolving consumer
graph for compoent: "
+ + provider;
+ throw new RuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Get the serilized graph of istances that provide
+ * specified component with services.
+ *
+ * @param component the consumer
+ * @return the ordered list of providers
+ */
+ public Component[] getProviderGraph( final Component consumer )
+ {
+ try
+ {
+ return referencedComponents( consumer, getComponentGraph(
consumer, true ) );
+ }
+ catch ( Throwable e )
+ {
+ final String error = "Unexpect error while resolving provider
graph for: "
+ + consumer;
+ throw new RuntimeException( error, e );
+ }
+ }
+
+ /**
+ * Return an component array that does not include the provided
component.
+ */
+ private Component[] referencedComponents( final Component component,
Component[] components )
+ {
+ ArrayList list = new ArrayList();
+ for ( int i = 0; i < components.length; i++ )
+ {
+ if( !components[i].equals( component ) )
+ {
+ list.add( components[i] );
+ }
+ }
+ return (Component[]) list.toArray( new Component[0] );
+ }
+
+ /**
+ * Get the graph of a single component.
+ *
+ * @param component the target component
+ * @param providers true if traversing providers, false if consumers
+ * @return the list of components
+ */
+ private Component[] getComponentGraph( final Component component,
+ final boolean providers )
+ {
+ final ArrayList result = new ArrayList();
+ visitcomponent( component, providers, new ArrayList(), result );
+ final Component[] returnValue = new Component[result.size()];
+ return (Component[]) result.toArray( returnValue );
+ }
+
+ /**
+ * Method to generate an ordering of nodes to traverse. It is expected
that
+ * the specified components have passed verification tests and are well
+ * formed.
+ *
+ * @param direction true if forward dependencys traced, false if
+ * dependencies reversed
+ * @return the ordered component list
+ */
+ private Component[] walkGraph( final boolean direction )
+ {
+ final ArrayList result = new ArrayList();
+ final ArrayList done = new ArrayList();
+
+ final int size = m_components.size();
+ for ( int i = 0; i < size; i++ )
+ {
+ final Component component = (Component) m_components.get( i );
+
+ visitcomponent( component, direction, done, result );
+ }
+
+ final Component[] returnValue = new Component[result.size()];
+ if( m_inProgress.size() != 0 )
+ {
+ throw new RuntimeException( "there where non-assembled
components: "
+ + m_inProgress );
+ }
+ return (Component[]) result.toArray( returnValue );
+ }
+
+ /**
+ * Visit a component when traversing dependencies.
+ *
+ * @param component the component
+ * @param direction true if walking tree looking for providers, else
false
+ * @param done those nodes already traversed
+ * @param order the order in which nodes have already been traversed
+ */
+ private void visitcomponent( final Component component,
+ final boolean direction, final ArrayList done, final ArrayList
order )
+ {
+ //if circular dependency
+ if( m_inProgress.contains( component ) )
+ {
+ throw new RuntimeException(
+ "Cyclic dependency encoutered in:" + component
+ + "is already in progress stack: "
+ + m_inProgress );
+ }
+
+ //If already visited this component return
+
+ if( done.contains( component ) )
+ {
+ return;
+ }
+ done.add( component );
+ m_inProgress.add( component );
+ if( direction )
+ {
+ visitProviders( component, done, order );
+ }
+ else
+ {
+ visitConsumers( component, done, order );
+ }
+
+ m_inProgress.remove( component );
+ order.add( component );
+ }
+
+ /**
+ * Traverse graph of components that provide services to the specified
+ * component.
+ *
+ * @param component the component to be checked
+ * @param done the list of already checked component
+ * @param order the order
+ */
+ private void visitProviders( final Component component,
+ final ArrayList done, final ArrayList order )
+ {
+ if( component instanceof Consumer )
+ {
+ Consumer consumer = (Consumer) component;
+ Component[] providers = consumer.getProviders();
+ for ( int i = ( providers.length - 1 ); i > -1; i-- )
+ {
+ visitcomponent( providers[i], true, done, order );
+ }
+ }
+ }
+
+ /**
+ * Traverse all consumers of a component. I.e. all components that use
service
+ * provided by the supplied component.
+ *
+ * @param component the component to be checked
+ * @param done the list of already checked components
+ * @param order the order
+ */
+ private void visitConsumers( final Component component,
+ final ArrayList done, final ArrayList order )
+ {
+ final int size = m_components.size();
+ for ( int i = 0; i < size; i++ )
+ {
+ final Component other = (Component) m_components.get( i );
+ if( other instanceof Consumer )
+ {
+ Consumer consumer = (Consumer) other;
+ final Component[] providers = consumer.getProviders();
+ for ( int j = 0; j < providers.length; j++ )
+ {
+ Component provider = providers[j];
+ if( provider.equals( component ) )
+ {
+ visitcomponent( other, false, done, order );
+ }
+ }
+ }
+ }
+ final int childCount = m_children.size();
+ for ( int i = 0; i < childCount; i++ )
+ {
+ final DependencyGraph map = (DependencyGraph) m_children.get( i
);
+ map.visitConsumers( component, done, order );
+ }
+ }
+}

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/PartsTable.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/PartsTable.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/runtime/PartsTable.java
Wed Jul 6 17:57:58 2005
@@ -54,7 +54,7 @@
m_component = component;
}

- public void addPart( String key, Part part )
+ public Component addComponent( String key, Part part )
throws ComponentException, DelegationException,
HandlerNotFoundException
{
if( null == key )
@@ -77,11 +77,11 @@
{
CompositionController controller = m_component.getController();
Component component = controller.newComponent( m_component,
part, key );
- addComponent( key, component );
+ return addComponent( key, component );
}
}

- public void addComponent( String key, Component component ) throws
DuplicateKeyException
+ public Component addComponent( String key, Component component ) throws
DuplicateKeyException
{
synchronized( m_parts )
{
@@ -90,6 +90,7 @@
throw new DuplicateKeyException( key );
}
m_parts.put( key, component );
+ return component;
}
}

@@ -106,4 +107,9 @@
{
return (Component) m_parts.get( key );
}
+
+ Component[] getComponents()
+ {
+ return (Component[]) m_parts.values().toArray( new Component[0] );
+ }
}

Modified: development/main/metro/index.xml
==============================================================================
--- development/main/metro/index.xml (original)
+++ development/main/metro/index.xml Wed Jul 6 17:57:58 2005
@@ -43,9 +43,6 @@
<type>jar</type>
</types>
</info>
- <dependencies>
- <include key="dpml-logging-api"/>
- </dependencies>
</project>

<!-- Activity -->

Modified:
development/main/metro/part/src/main/net/dpml/part/control/ControllerContext.java
==============================================================================
---
development/main/metro/part/src/main/net/dpml/part/control/ControllerContext.java
(original)
+++
development/main/metro/part/src/main/net/dpml/part/control/ControllerContext.java
Wed Jul 6 17:57:58 2005
@@ -21,7 +21,7 @@
import java.net.URI;
import java.io.File;

-import net.dpml.logging.Logger;
+//import net.dpml.logging.Logger;


/**
@@ -42,7 +42,7 @@
* Return the root logging channel.
* @return the logging channel
*/
- Logger getLogger();
+ //Logger getLogger();

/**
* Return the root working directory path.

Added:
development/main/metro/part/src/main/net/dpml/part/manager/Consumer.java
==============================================================================
--- (empty file)
+++ development/main/metro/part/src/main/net/dpml/part/manager/Consumer.java
Wed Jul 6 17:57:58 2005
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 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.part.manager;
+
+/**
+ * The Consumer interface exposes an operation through which provider
+ * components are declared and through ordered assembly of components
+ * may be undetaken enabling formal startup and shutdown sequencing.
+ *
+ * @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 interface Consumer
+{
+ /**
+ * Return an array of components providing services to this component.
+ * @return the provider component array
+ */
+ Component[] getProviders();
+}

Modified:
development/main/metro/part/src/main/net/dpml/part/manager/Container.java
==============================================================================
--- development/main/metro/part/src/main/net/dpml/part/manager/Container.java
(original)
+++ development/main/metro/part/src/main/net/dpml/part/manager/Container.java
Wed Jul 6 17:57:58 2005
@@ -53,4 +53,18 @@
*/
Component getComponent( String key ) throws ComponentNotFoundException;

+ /**
+ * Return the startup sequence for the set of components contained
+ * within the container.
+ * @return the startup sequence
+ */
+ Component[] getStartupSequence();
+
+ /**
+ * Return the shudown sequence for the set of components contained
+ * within the container.
+ * @return the shutdown sequence
+ */
+ Component[] getShutdownSequence();
+
}

Modified:
development/main/transit/core/tools/src/main/net/dpml/transit/tools/AntAdapter.java
==============================================================================
---
development/main/transit/core/tools/src/main/net/dpml/transit/tools/AntAdapter.java
(original)
+++
development/main/transit/core/tools/src/main/net/dpml/transit/tools/AntAdapter.java
Wed Jul 6 17:57:58 2005
@@ -33,7 +33,7 @@
* @author <a href="http://www.dpml.net";>The Digital Product Meta Library</a>
* @version $Id: AntMonitor.java 183 2004-10-23 16:53:31Z niclas $
*/
-class AntAdapter implements Adapter
+public class AntAdapter implements Adapter
{
/**
* The ant task that this adapter is assigned to.



  • svn commit: r2983 - in development/main: metro metro/central/src/main/net/dpml/metro/central metro/composition/builder/src/main/net/dpml/composition/builder metro/composition/builder/src/main/net/dpml/composition/builder/datatypes metro/composition/control/src/main/net/dpml/composition/control metro/composition/control/src/main/net/dpml/composition/runtime metro/part/src/main/net/dpml/part/control metro/part/src/main/net/dpml/part/manager transit/core/tools/src/main/net/dpml/transit/tools, mcconnell, 07/06/2005

Archive powered by MHonArc 2.6.24.

Top of Page