Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2142 - in development/main/metro: . activation/providers/metro/src/main/net/dpml/activation/metro composition/api/src/main/net/dpml/composition/model composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src composition/testing/unit/src/test composition/testing/unit/src/test/net composition/testing/unit/src/test/net/dpml composition/testing/unit/src/test/net/dpml/composition composition/testing/unit/src/test/net/dpml/composition/test context/impl/src/main/net/dpml/context/impl service/api/src/main/net/dpml/service

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: r2142 - in development/main/metro: . activation/providers/metro/src/main/net/dpml/activation/metro composition/api/src/main/net/dpml/composition/model composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src composition/testing/unit/src/test composition/testing/unit/src/test/net composition/testing/unit/src/test/net/dpml composition/testing/unit/src/test/net/dpml/composition composition/testing/unit/src/test/net/dpml/composition/test context/impl/src/main/net/dpml/context/impl service/api/src/main/net/dpml/service
  • Date: Sat, 26 Mar 2005 00:57:13 -0500

Author: mcconnell AT dpml.net
Date: Sat Mar 26 00:57:13 2005
New Revision: 2142

Added:

development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/ContextInvocationHandler.java

development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DependencyInvocationHandler.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
development/main/metro/composition/testing/unit/
development/main/metro/composition/testing/unit/build.xml
development/main/metro/composition/testing/unit/src/
development/main/metro/composition/testing/unit/src/test/
development/main/metro/composition/testing/unit/src/test/net/
development/main/metro/composition/testing/unit/src/test/net/dpml/

development/main/metro/composition/testing/unit/src/test/net/dpml/composition/

development/main/metro/composition/testing/unit/src/test/net/dpml/composition/test/

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

development/main/metro/service/api/src/main/net/dpml/service/FulfillmentRuntimeException.java
Removed:

development/main/metro/context/impl/src/main/net/dpml/context/impl/ContextInvocationHandler.java
Modified:

development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultComponentFactory.java

development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultServiceManager.java

development/main/metro/composition/api/src/main/net/dpml/composition/model/ContainmentModel.java

development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java

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

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

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContainmentModel.java

development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
development/main/metro/composition/testing/acme/build.xml

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java

development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
development/main/metro/index.xml
Log:
Working implementation of a context and dependencies invocation handler
capable of supporting the inner interface delivery model.

Added:
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/ContextInvocationHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/ContextInvocationHandler.java
Sat Mar 26 00:57:13 2005
@@ -0,0 +1,221 @@
+/*
+ * Copyright 2004 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.activation.metro;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Map;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.EntryDescriptor;
+
+import net.dpml.composition.model.EntryModel;
+
+/**
+ * This makes a dynamic proxy for an object. The object can be represented
+ * by one, some or all of it's interfaces.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ApplianceInvocationHandler.java 2106 2005-03-21 18:46:10Z
mcconnell AT dpml.net $
+ */
+public final class ContextInvocationHandler
+ implements InvocationHandler
+{
+ //-------------------------------------------------------------------
+ // state
+ //-------------------------------------------------------------------
+
+ /**
+ * A map of context entry key name and context entry values.
+ */
+ private final Map m_map;
+
+ /**
+ * A map of the entry descriptors published by the component type
+ * and keyed by entry key.
+ */
+ private final Map m_entries = new Hashtable();
+
+ /**
+ * The component type.
+ */
+ private final Type m_type;
+
+ //-------------------------------------------------------------------
+ // constructor
+ //-------------------------------------------------------------------
+
+ /**
+ * Create a context invocation handler.
+ *
+ * @param type the component type
+ * @param map a map of context values keyed by entry key
+ */
+ public ContextInvocationHandler( Type type, Map map )
+ throws NullPointerException
+ {
+ assertNotNull( map, "map" );
+ assertNotNull( type, "type" );
+
+ m_map = map;
+ m_type = type;
+
+ EntryDescriptor[] entries = type.getContext().getEntries();
+ for( int i=0; i<entries.length; i++ )
+ {
+ EntryDescriptor p = entries[i];
+ String key = p.getKey();
+ boolean required = p.isRequired();
+ m_entries.put( key, p );
+ if( required && ( false == map.containsKey( key ) ) )
+ {
+ final String error =
+ "The component type ["
+ + type.getInfo().getClassname()
+ + "] declares a required context entry under the key ["
+ + key
+ + "] however, no corresponding value has been supplied
within the context map.";
+
+System.out.println( "## MAP: " + map );
+ throw new IllegalArgumentException( error );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ /**
+ * Invoke the specified method on underlying object.
+ * This is called by the proxy object.
+ *
+ * @param proxy the proxy object
+ * @param method the method invoked on proxy object
+ * @param args the arguments supplied to method
+ * @return the return value of method
+ * @throws Throwable if an error occurs
+ * @exception NullPointerException if any one of the proxy or method
arguments
+ * is null, or if the object instance has been destroyed
earlier.
+ */
+ public Object invoke( final Object proxy, final Method method, final
Object[] args )
+ throws Throwable, NullPointerException
+ {
+ if( proxy == null )
+ throw new NullPointerException( "proxy" );
+ if( method == null )
+ throw new NullPointerException( "method" );
+
+ Class source = method.getDeclaringClass();
+ if( Object.class == method.getDeclaringClass() )
+ {
+ return method.invoke( this, args );
+ }
+
+ String name = method.getName();
+ String key = getKeyFromMethod( method );
+ EntryDescriptor entry = (EntryDescriptor) m_entries.get( key );
+
+ if( null == entry )
+ {
+ final String error =
+ "Illegal request for an undeclared context entry ["
+ + key
+ + "] withing the component type ["
+ + m_type.getInfo().getClassname()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+
+ //
+ // we have a valid key
+ //
+
+ EntryModel model = (EntryModel) m_map.get( key );
+ if( null == model )
+ {
+ return returnClientSuppliedDefaultArgument( entry, args );
+ }
+ else
+ {
+ Object value = model.getValue();
+ return value;
+ }
+ }
+
+ private String getKeyFromMethod( Method method )
+ {
+ String name = method.getName();
+ if( name.startsWith( "get" ) )
+ {
+ return formatKey( name.substring( 3 ) );
+ }
+ else
+ {
+ final String error =
+ "Invalid method accessor ["
+ + name
+ + "]";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ private String formatKey( String key )
+ {
+ if( key.length() < 1 )
+ {
+ throw new IllegalArgumentException( "key" );
+ }
+ String first = key.substring( 0, 1 ).toLowerCase();
+ String remainder = key.substring( 1 );
+ return first + remainder;
+ }
+
+ private Object returnClientSuppliedDefaultArgument( EntryDescriptor
entry, Object[] args )
+ {
+ if( args.length < 1 )
+ {
+ final String error =
+ "Insuffient arguments to resolve a default value for the key ["
+ + entry.getKey()
+ + "] within the component type ["
+ + m_type.getInfo().getName()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+ Object arg = args[0];
+ return arg;
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ private void assertNotNull( Object object, String key )
+ throws NullPointerException
+ {
+ if( null == object )
+ {
+ throw new NullPointerException( key );
+ }
+ }
+}

Modified:
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultComponentFactory.java
==============================================================================
---
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultComponentFactory.java
(original)
+++
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultComponentFactory.java
Sat Mar 26 00:57:13 2005
@@ -19,6 +19,9 @@
package net.dpml.activation.metro;

import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.Hashtable;
import java.util.Map;

import net.dpml.activation.ComponentFactory;
@@ -38,6 +41,7 @@
import net.dpml.composition.model.ContextualizationHandler;
import net.dpml.composition.model.DeploymentModel;
import net.dpml.composition.model.ModelException;
+import net.dpml.composition.model.DependencyModel;

import net.dpml.configuration.Configurable;
import net.dpml.configuration.Configuration;
@@ -55,6 +59,8 @@
import net.dpml.logging.LogEnabled;
import net.dpml.logging.Logger;

+import net.dpml.meta.info.Type;
+
import net.dpml.parameters.Parameterizable;
import net.dpml.parameters.Parameters;

@@ -215,13 +221,14 @@
final Logger logger = m_model.getLogger();
final Configuration config = m_model.getConfiguration();
final Parameters params = m_model.getParameters();
- final ServiceManager manager = new DefaultServiceManager( m_model );
+ final Class managerInterfaceClass =
getTargetServiceManagerInterface();
+ final Object manager = getTargetServiceManager(
managerInterfaceClass );
final Object context = getTargetContext();
final Class contextClass = getContextCastingClass();

final Object instance =
instantiate(
- clazz, logger, config, params, context, contextClass, manager );
+ clazz, logger, config, params, context, contextClass,
managerInterfaceClass, manager );

try
{
@@ -240,7 +247,7 @@
if( instance instanceof Serviceable )
{
getLogger().debug( "applying service manager" );
- ContainerUtil.service( instance, manager );
+ ContainerUtil.service( instance, (ServiceManager) manager );
}

if( instance instanceof Configurable )
@@ -316,12 +323,105 @@
}
}

+ private Class getTargetServiceManagerInterface()
+ throws LifecycleException
+ {
+ Class subject = m_model.getDeploymentClass();
+ Class[] classes = subject.getClasses();
+ Class inner = locateClass( "$Dependencies", classes );
+ if( null != inner )
+ {
+ return inner;
+ }
+ else
+ {
+ return ServiceManager.class;
+ }
+ }
+
+ private Object getTargetServiceManager( Class clazz )
+ throws LifecycleException
+ {
+ DependencyModel[] dependencies = m_model.getDependencyModels();
+ if( clazz == ServiceManager.class )
+ {
+ Logger logger = m_model.getLogger();
+ return new DefaultServiceManager( logger, dependencies );
+ }
+ else
+ {
+ Hashtable map = new Hashtable();
+ for( int i=0; i<dependencies.length; i++ )
+ {
+ DependencyModel dep = dependencies[i];
+ String key = dep.getDependency().getKey();
+ map.put( key, dep );
+ }
+ Type type = m_model.getType();
+ InvocationHandler handler = new DependencyInvocationHandler(
type, map );
+
+ ClassLoader classloader =
m_model.getDeploymentClass().getClassLoader();
+ return Proxy.newProxyInstance( classloader, new Class[]{ clazz
}, handler );
+ }
+ }
+
private Object getTargetContext()
throws LifecycleException
{
ContextModel model = m_model.getContextModel();
- Class impl = getContextImplementationClass( model );
- return createComponentContext( impl, model.getContextMap() );
+ String casting = model.getCastingClassname();
+ if( ( null != casting ) && casting.endsWith( "$Context" ) )
+ {
+ //
+ // return a proxy
+ //
+
+ Map map = model.getEntryModelMap();
+ Type type = m_model.getType();
+ InvocationHandler handler = new ContextInvocationHandler( type,
map );
+
+ Class inner = getInnerClass( "$Context" );
+ ClassLoader classloader =
m_model.getDeploymentClass().getClassLoader();
+ return Proxy.newProxyInstance( classloader, new Class[]{ inner
}, handler );
+ }
+ else
+ {
+ Class impl = getContextImplementationClass( model );
+ return createComponentContext( impl, model.getContextMap() );
+ }
+ }
+
+ private Class getInnerClass( String postfix )
+ {
+ Class subject = m_model.getDeploymentClass();
+ Class[] classes = subject.getClasses();
+ Class inner = locateClass( postfix, classes );
+ if( null == inner )
+ {
+ final String error =
+ "Unable to locate the " + postfix + " inner class in component
type ["
+ + subject.getName()
+ + "].";
+ throw new IllegalStateException( error );
+ }
+ else
+ {
+ return inner;
+ }
+ }
+
+ private Class locateClass( String postfix, Class[] classes )
+ {
+ for( int i=0; i<classes.length; i++ )
+ {
+ Class inner = classes[i];
+ String name = inner.getName();
+ if( name.endsWith( postfix ) )
+ {
+ return inner;
+ }
+ }
+ return null;
}

private Class getContextImplementationClass( ContextModel model ) throws
LifecycleException
@@ -386,10 +486,9 @@
}
}

-
private Object instantiate(
Class clazz, Logger logger, Configuration config, Parameters
params,
- Object context, Class contextClass, ServiceManager manager )
+ Object context, Class contextClass, Class managerClass, Object
manager )
throws LifecycleException, NullArgumentException
{
Constructor constructor = getConstructor( clazz );
@@ -399,6 +498,7 @@
for( int i=0; i<classes.length; i++ )
{
Class c = classes[i];
+
if( Logger.class.isAssignableFrom( c ) )
{
if( null == logger )
@@ -431,6 +531,10 @@
}
args[i] = params;
}
+ else if( ( null != manager ) && managerClass.isAssignableFrom( c
) )
+ {
+ args[i] = manager;
+ }
else if( ServiceManager.class.isAssignableFrom( c ) )
{
if( null == manager )
@@ -499,6 +603,11 @@
final Constructor constructor, final Object[] args )
throws LifecycleException
{
+ for( int i=0; i<args.length; i++ )
+ {
+ Object arg = args[i];
+ }
+
try
{
if( args.length == 0 )

Modified:
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultServiceManager.java
==============================================================================
---
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultServiceManager.java
(original)
+++
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DefaultServiceManager.java
Sat Mar 26 00:57:13 2005
@@ -80,18 +80,11 @@
* @param model component model of the component that is
* to be serviced.
*/
- public DefaultServiceManager( ComponentModel model )
+ public DefaultServiceManager( Logger logger, DependencyModel[]
dependencies )
throws NullArgumentException
{
- if( model == null )
- {
- throw new NullArgumentException( "model" );
- }
-
- m_logger = model.getLogger();
-
+ m_logger = logger;
m_map = new Hashtable();
- DependencyModel[] dependencies = model.getDependencyModels();
for( int i=0; i < dependencies.length; i++ )
{
final DependencyModel dependency = dependencies[i];
@@ -105,6 +98,7 @@
}
}

+
//-------------------------------------------------------------------
// ServiceManager
//-------------------------------------------------------------------

Added:
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DependencyInvocationHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/activation/providers/metro/src/main/net/dpml/activation/metro/DependencyInvocationHandler.java
Sat Mar 26 00:57:13 2005
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2004 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.activation.metro;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Map;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.DependencyDescriptor;
+
+import net.dpml.composition.model.ComponentModel;
+import net.dpml.composition.model.DeploymentModel;
+import net.dpml.composition.model.DependencyModel;
+
+import net.dpml.composition.model.EntryModel;
+
+import net.dpml.service.FulfillmentRuntimeException;
+
+/**
+ * This makes a dynamic proxy for an object. The object can be represented
+ * by one, some or all of it's interfaces.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ApplianceInvocationHandler.java 2106 2005-03-21 18:46:10Z
mcconnell AT dpml.net $
+ */
+public final class DependencyInvocationHandler
+ implements InvocationHandler
+{
+ //-------------------------------------------------------------------
+ // state
+ //-------------------------------------------------------------------
+
+ /**
+ * A map of provider entry key name and dependency model entries.
+ */
+ private final Map m_map;
+
+ /**
+ * A map of the dependency descriptors published by the component type
+ * and keyed by entry key.
+ */
+ private final Map m_entries = new Hashtable();
+
+ /**
+ * The component type.
+ */
+ private final Type m_type;
+
+ //-------------------------------------------------------------------
+ // constructor
+ //-------------------------------------------------------------------
+
+ /**
+ * Create a dependency invocation handler.
+ *
+ * @param type the component type
+ * @param map a map of context values keyed by entry key
+ */
+ public DependencyInvocationHandler( Type type, Map map )
+ throws NullPointerException
+ {
+ assertNotNull( map, "map" );
+ assertNotNull( type, "type" );
+
+ m_map = map;
+ m_type = type;
+
+ DependencyDescriptor[] entries = type.getDependencies();
+ for( int i=0; i<entries.length; i++ )
+ {
+ DependencyDescriptor p = entries[i];
+ String key = p.getKey();
+ boolean required = p.isRequired();
+ m_entries.put( key, p );
+ if( required && ( false == map.containsKey( key ) ) )
+ {
+ final String error =
+ "The component type ["
+ + type.getInfo().getClassname()
+ + "] declares a required service dependency entry under
the key ["
+ + key
+ + "] however no corresponding provider is available.";
+ throw new IllegalArgumentException( error );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ /**
+ * Invoke the specified method on underlying object.
+ * This is called by the proxy object.
+ *
+ * @param proxy the proxy object
+ * @param method the method invoked on proxy object
+ * @param args the arguments supplied to method
+ * @return the return value of method
+ * @throws Throwable if an error occurs
+ * @exception NullPointerException if any one of the proxy or method
arguments
+ * is null, or if the object instance has been destroyed
earlier.
+ */
+ public Object invoke( final Object proxy, final Method method, final
Object[] args )
+ throws Throwable, NullPointerException
+ {
+ if( proxy == null )
+ throw new NullPointerException( "proxy" );
+ if( method == null )
+ throw new NullPointerException( "method" );
+
+ Class source = method.getDeclaringClass();
+ if( Object.class == method.getDeclaringClass() )
+ {
+ return method.invoke( this, args );
+ }
+
+ String name = method.getName();
+ String key = getKeyFromMethod( method );
+ DependencyDescriptor entry = (DependencyDescriptor) m_entries.get(
key );
+
+ if( null == entry )
+ {
+ final String error =
+ "Illegal request for an undeclared dependency ["
+ + key
+ + "] withing the component type ["
+ + m_type.getInfo().getClassname()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+
+ //
+ // we have a valid key
+ //
+
+ DependencyModel model = (DependencyModel) m_map.get( key );
+ final DeploymentModel provider = model.getProvider();
+ if( null == provider )
+ {
+ return returnClientSuppliedDefaultArgument( entry, args );
+ }
+ else
+ {
+ return getServiceInstance( key, provider );
+ }
+ }
+
+ private Object getServiceInstance( String key, DeploymentModel provider )
+ {
+ if( null == provider )
+ {
+ throw new NullPointerException( "provider" );
+ }
+
+ try
+ {
+ Object instance = provider.resolve();
+ if( Proxy.isProxyClass( instance.getClass() ) )
+ {
+ return instance;
+ }
+ else
+ {
+ return instance;
+ }
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected runtime error while attempting to resolve the
service for the key ["
+ + key
+ + "] using the provider ["
+ + provider
+ + "] within the component type ["
+ + m_type.getInfo().getClassname()
+ + "].";
+ throw new FulfillmentRuntimeException( key, error, e );
+ }
+ }
+
+ private String getKeyFromMethod( Method method )
+ {
+ String name = method.getName();
+ if( name.startsWith( "get" ) )
+ {
+ return formatKey( name.substring( 3 ) );
+ }
+ else
+ {
+ final String error =
+ "Invalid method accessor ["
+ + name
+ + "]";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ private String formatKey( String key )
+ {
+ if( key.length() < 1 )
+ {
+ throw new IllegalArgumentException( "key" );
+ }
+ String first = key.substring( 0, 1 ).toLowerCase();
+ String remainder = key.substring( 1 );
+ return first + remainder;
+ }
+
+ private Object returnClientSuppliedDefaultArgument( DependencyDescriptor
entry, Object[] args )
+ {
+ if( args.length < 1 )
+ {
+ final String error =
+ "Insuffient arguments to resolve a default value for the key ["
+ + entry.getKey()
+ + "] within the component type ["
+ + m_type.getInfo().getName()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+ Object arg = args[0];
+ return arg;
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ private void assertNotNull( Object object, String key )
+ throws NullPointerException
+ {
+ if( null == object )
+ {
+ throw new NullPointerException( key );
+ }
+ }
+}

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContainmentModel.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContainmentModel.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContainmentModel.java
Sat Mar 26 00:57:13 2005
@@ -19,6 +19,7 @@
package net.dpml.composition.model;

import java.net.URL;
+import java.net.URI;
import java.util.List;

import net.dpml.composition.data.DeploymentProfile;
@@ -129,6 +130,15 @@
throws AssemblyException;

/**
+ * Addition of a new subsidiary deployment model using a supplied part
uri.
+ *
+ * @param uri a part uri
+ * @return the model based on the derived profile
+ * @exception ModelException if an error occurs during model establishment
+ */
+ DeploymentModel addModel( String name, URI uri ) throws ModelException;
+
+ /**
* Addition of a new subsidiary containment model
* using a supplied profile url.
*

Modified:
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
==============================================================================
---
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
(original)
+++
development/main/metro/composition/api/src/main/net/dpml/composition/model/ContextModel.java
Sat Mar 26 00:57:13 2005
@@ -81,4 +81,11 @@
*/
Map getContextMap();

+ /**
+ * Return a map of EntryModel instances.
+ *
+ * @return the entry model map.
+ */
+ Map getEntryModelMap();
+
}

Modified:
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
==============================================================================
---
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
(original)
+++
development/main/metro/composition/builder/src/main/net/dpml/composition/builder/TypeBuilderTask.java
Sat Mar 26 00:57:13 2005
@@ -622,8 +622,18 @@

private ContextDescriptor createContextDescriptor( Class subject )
throws IntrospectionException
{
- EntryDescriptor[] entries = createEntryDescriptors( subject );
- return new ContextDescriptor( null, entries );
+ Class[] classes = subject.getClasses();
+ Class param = locateClass( "$Context", classes );
+ if( null == param )
+ {
+ return new ContextDescriptor( null, new EntryDescriptor[0] );
+ }
+ else
+ {
+ EntryDescriptor[] entries = createEntryDescriptors( subject );
+ String classname = param.getName();
+ return new ContextDescriptor( classname, entries );
+ }
}

private EntryDescriptor[] createEntryDescriptors( Class subject )

Modified:
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
==============================================================================
---
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
(original)
+++
development/main/metro/composition/control/src/main/net/dpml/composition/control/CompositionController.java
Sat Mar 26 00:57:13 2005
@@ -56,6 +56,11 @@
// constructor
//--------------------------------------------------------------------

+ public CompositionController()
+ {
+ this( new ConsoleMonitor( "metro", false ) );
+ }
+
public CompositionController( Monitor monitor )
{
super();

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContainmentModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContainmentModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContainmentModel.java
Sat Mar 26 00:57:13 2005
@@ -63,6 +63,10 @@
import net.dpml.composition.provider.ContainmentContext;
import net.dpml.composition.provider.ModelFactory;

+import net.dpml.composition.control.CompositionController;
+
+import net.dpml.part.Part;
+
import net.dpml.configuration.Configuration;
import net.dpml.configuration.impl.DefaultConfigurationBuilder;

@@ -562,6 +566,47 @@
}

/**
+ * Addition of a new subsidiary deployment model using a supplied part
uri.
+ *
+ * @param uri a part uri
+ * @return the model based on the derived profile
+ * @exception ModelException if an error occurs during model establishment
+ */
+ public DeploymentModel addModel( String name, URI uri ) throws
ModelException
+ {
+ try
+ {
+ CompositionController controller = new CompositionController();
+ Part part = controller.loadPart( uri );
+ if( part instanceof DeploymentProfile )
+ {
+ DeploymentProfile profile = (DeploymentProfile) part;
+ return createDeploymentModel( name, profile );
+ }
+ else
+ {
+ final String error =
+ "Unknown part type ["
+ + part.getClass().getName()
+ + "]";
+ throw new ModelException( error );
+ }
+ }
+ catch( ModelException e )
+ {
+ throw e;
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Unexpected error while attempting to add a model using the ["
+ + uri
+ + "]";
+ throw new ModelException( error, e );
+ }
+ }
+
+ /**
* Addition of a new subsidiary model within
* the containment context.
*
@@ -1112,10 +1157,6 @@
}
else
{
- //
- // TODO: try and load the artifact as a serialized
DeploymnetDirective
- //
-
final String error =
"Don't know what to do with artifact: " + uri;
throw new ModelException( error );

Modified:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
==============================================================================
---
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
(original)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultContextModel.java
Sat Mar 26 00:57:13 2005
@@ -22,6 +22,7 @@
import java.util.Map;

import net.dpml.composition.data.ConstructorDirective;
+import net.dpml.composition.data.ValueDirective;
import net.dpml.composition.data.ContextDirective;
import net.dpml.composition.data.EntryDirective;
import net.dpml.composition.data.ImportDirective;
@@ -163,12 +164,6 @@
}
else
{
- //
- // there are only two context entry models - import
- // and constructor - identify the model to use then add
- // the resolved model to the map
- //
-
if( entryDirective instanceof ImportDirective )
{
//
@@ -194,6 +189,18 @@
m_map );
setEntryModel( alias, model );
}
+ else if( entryDirective instanceof ValueDirective )
+ {
+ ValueDirective value =
+ (ValueDirective) entryDirective;
+ DefaultValueModel model =
+ new DefaultValueModel(
+ entry,
+ value,
+ context,
+ m_map );
+ setEntryModel( alias, model );
+ }
else
{
String modelClass =
@@ -302,4 +309,15 @@
{
return new DefaultContextMap( m_map );
}
+
+ /**
+ * Return the map of entry models.
+ *
+ * @return the entry model map
+ */
+ public Map getEntryModelMap()
+ {
+ return m_map;
+ }
+
}

Added:
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/impl/src/main/net/dpml/composition/model/impl/DefaultValueModel.java
Sat Mar 26 00:57:13 2005
@@ -0,0 +1,636 @@
+/*
+ * Copyright 2004 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.composition.model.impl;
+
+import java.lang.reflect.Constructor;
+
+import java.util.Map;
+
+import net.dpml.composition.data.ValueDirective;
+import net.dpml.composition.data.ValueDirective.Value;
+
+import net.dpml.composition.model.EntryModel;
+import net.dpml.composition.model.ModelException;
+
+import net.dpml.composition.provider.ComponentContext;
+
+import net.dpml.meta.info.EntryDescriptor;
+
+import net.dpml.i18n.ResourceManager;
+import net.dpml.i18n.Resources;
+
+import net.dpml.lang.NullArgumentException;
+
+
+/**
+ * Default implementation of a the context entry constructor model.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: DefaultConstructorModel.java 1518 2005-01-17 17:13:05Z
niclas $
+ */
+public class DefaultValueModel extends DefaultEntryModel
+{
+ //==============================================================
+ // static
+ //==============================================================
+
+ private static final Resources REZ =
+ ResourceManager.getPackageResources( DefaultValueModel.class );
+
+ //==============================================================
+ // immutable state
+ //==============================================================
+
+ private final ValueDirective m_directive;
+
+ private final EntryDescriptor m_descriptor;
+
+ private final ComponentContext m_context;
+
+ private final Map m_map;
+
+ //==============================================================
+ // mutable state
+ //==============================================================
+
+ private Object m_value;
+
+ //==============================================================
+ // constructor
+ //==============================================================
+
+ /**
+ * Creation of a new context entry import model.
+ *
+ * @param descriptor the context entry descriptor
+ * @param directive the context entry directive
+ * @param context the containment context
+ * @param map a map of available context entries
+ * @exception NullArgumentException if either the directive argument or
the
+ * context argument is null.
+ */
+ public DefaultValueModel(
+ EntryDescriptor descriptor, ValueDirective directive,
+ ComponentContext context, Map map )
+ throws ModelException, NullArgumentException
+ {
+ super( descriptor );
+
+ if( directive == null )
+ {
+ throw new NullArgumentException( "directive" );
+ }
+ if( context == null )
+ {
+ throw new NullArgumentException( "context" );
+ }
+ m_descriptor = descriptor;
+ m_directive = directive;
+ m_context = context;
+ m_map = map;
+
+ validate();
+ }
+
+ private void validate()
+ throws ModelException
+ {
+ final String descriptorClassName = m_descriptor.getClassname();
+ final String directiveClassName = m_directive.getClassname();
+ validatePair( descriptorClassName, directiveClassName );
+ Value[] params = m_directive.getValues();
+
+ //
+ // TODO:
+ // wizz through and validate all of the value declarations
+ // and make sure that constructors exist that match the sub-parameter
+ // delcarations
+ //
+ }
+
+ private void validatePair( String descriptorClass, String directiveClass
)
+ throws ModelException
+ {
+ System.out.println( "## DESCRIPTOR CLASS: " + descriptorClass );
+ System.out.println( "## DIRECTIVE CLASS: " + directiveClass );
+
+
+ if( "int".equals( descriptorClass ) )
+ {
+ if( ( null == directiveClass ) || "int".equals( directiveClass )
)
+ {
+ return;
+ }
+ else
+ {
+ final String error =
+ "Descriptor class ["
+ + descriptorClass
+ + "] does not match the supplied directive class ["
+ + directiveClass
+ + "].";
+ throw new ModelException( error );
+ }
+ }
+
+ if( null == directiveClass )
+ {
+ return;
+ }
+
+ final String key = m_descriptor.getKey();
+ ClassLoader loader = m_context.getClassLoader();
+
+ Class target = null;
+ try
+ {
+ target = loader.loadClass( descriptorClass );
+ }
+ catch( ClassNotFoundException e )
+ {
+ final String error =
+ REZ.getString( "constructor.descriptor.unknown.error", key,
descriptorClass );
+ throw new ModelException( error );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ REZ.getString( "constructor.descriptor.load.error", key,
descriptorClass );
+ throw new ModelException( error, e );
+ }
+
+ Class source = null;
+ try
+ {
+ source = loader.loadClass( directiveClass );
+ }
+ catch( ClassNotFoundException e )
+ {
+ final String error =
+ REZ.getString( "constructor.directive.unknown.error", key,
directiveClass );
+ throw new ModelException( error );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ REZ.getString( "constructor.directive.load.error", key,
directiveClass );
+ throw new ModelException( error, e );
+ }
+
+ if( !target.isAssignableFrom( source ) )
+ {
+ final String error =
+ REZ.getString(
+ "constructor.invalid-model.error",
+ key, descriptorClass, directiveClass );
+ throw new ModelException( error );
+ }
+ }
+
+ //==============================================================
+ // EntryModel
+ //==============================================================
+
+ /**
+ * Return the context entry value.
+ *
+ * @return the context entry value
+ */
+ public Object getValue()
+ throws ModelException
+ {
+ if( m_value != null )
+ {
+ return m_value;
+ }
+
+ String target = m_descriptor.getKey();
+ Object object = null;
+ try
+ {
+ ClassLoader loader = m_context.getClassLoader();
+ String classname = getReturnTypeClassname();
+ String argument = m_directive.getLocalValue();
+ Value[] params = m_directive.getValues();
+ Class clazz = getValueClass( classname, loader );
+ object = getValue( loader, clazz, argument, params );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Cannot establish a constructed context entry for the key " +
target
+ + " due to a runtime failure.";
+ throw new ModelException( error, e );
+ }
+
+ if( !m_descriptor.isVolatile() )
+ {
+ m_value = object;
+ }
+
+ return object;
+ }
+
+ private String getReturnTypeClassname()
+ {
+ String classname = m_directive.getClassname();
+ if( null == classname )
+ {
+ return m_descriptor.getClassname();
+ }
+ else
+ {
+ return classname;
+ }
+ }
+
+ /**
+ * Return the context entry value.
+ *
+ * @return the context entry value
+ */
+ public Object getValue( Value p )
+ throws ModelException
+ {
+ ClassLoader loader = m_context.getClassLoader();
+ String classname = p.getClassname();
+ String argument = p.getArgument();
+ Value[] params = p.getValueDirectives();
+ Class clazz = getValueClass( classname, loader );
+ return getValue( loader, clazz, argument, params );
+ }
+
+ /**
+ * Return the derived parameter value.
+ * @param loader the classloader to use
+ * @param clazz the constructor class
+ * @param argument a single string constructor argument
+ * @param parameters an alternative sequence of arguments
+ * @return the value
+ * @exception ModelException if the parameter value cannot be resolved
+ */
+ public Object getValue(
+ ClassLoader loader, Class clazz, String argument,
+ Value[] parameters )
+ throws ModelException
+ {
+ //
+ // if the parameter contains a text argument then check if its a
reference
+ // to a map entry (in the form"${<key>}" ), otherwise its a simple
constructor
+ // case with a single string paremeter
+ //
+
+ if( parameters.length == 0 )
+ {
+ if( argument == null )
+ {
+ return getNullArgumentConstructorValue( clazz );
+ }
+ else
+ {
+ return getSingleArgumentConstructorValue( loader, clazz,
argument );
+ }
+ }
+ else
+ {
+ return getMultiArgumentConstructorValue( loader, clazz,
parameters );
+ }
+ }
+
+ private Object getMultiArgumentConstructorValue(
+ ClassLoader classLoader, Class clazz, Value[] parameters )
+ throws ModelException
+ {
+ //
+ // getting here means we are dealing with 0..n types parameter
constructor where the
+ // parameters are defined by the nested parameter definitions
+ //
+
+ if ( parameters.length == 0 )
+ {
+ try
+ {
+ return clazz.newInstance();
+ }
+ catch ( InstantiationException e )
+ {
+ final String error =
+ "Unable to instantiate instance of class: " +
clazz.getName();
+ throw new ModelException( error, e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ final String error =
+ "Cannot access null constructor for the class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ }
+ else
+ {
+ Class[] params = new Class[ parameters.length ];
+ for ( int i = 0; i < parameters.length; i++ )
+ {
+ String classname = parameters[i].getClassname();
+ try
+ {
+ params[i] = classLoader.loadClass( classname );
+ }
+ catch ( Throwable e )
+ {
+ final String error =
+ "Unable to resolve sub-parameter class: "
+ + classname
+ + " for the parameter " + clazz.getName();
+ throw new ModelException( error, e );
+ }
+ }
+
+ Object[] values = new Object[ parameters.length ];
+ for ( int i = 0; i < parameters.length; i++ )
+ {
+ Value p = parameters[i];
+ String classname = p.getClassname();
+ try
+ {
+ values[i] = getValue( p );
+ }
+ catch ( Throwable e )
+ {
+ final String error =
+ "Unable to instantiate sub-parameter for value: "
+ + classname
+ + " inside the parameter " + clazz.getName();
+ throw new ModelException( error, e );
+ }
+ }
+ Constructor constructor = null;
+ try
+ {
+ constructor = clazz.getConstructor( params );
+ }
+ catch ( NoSuchMethodException e )
+ {
+ final String error =
+ "Supplied parameters for "
+ + clazz.getName()
+ + " do not match the available class constructors.";
+ throw new ModelException( error, e );
+ }
+
+ try
+ {
+ return constructor.newInstance( values );
+ }
+ catch ( InstantiationException e )
+ {
+ final String error =
+ "Unable to instantiate an instance of a multi-parameter
constructor for class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ final String error =
+ "Cannot access multi-parameter constructor for the class:
'"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ catch ( Throwable e )
+ {
+ final String error =
+ "Unexpected error while attmpting to instantiate a
multi-parameter constructor "
+ + "for the class: '" + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ }
+ }
+
+ private Object getNullArgumentConstructorValue( Class clazz )
+ throws ModelException
+ {
+ try
+ {
+ return clazz.newInstance();
+ }
+ catch ( InstantiationException e )
+ {
+ final String error =
+ "Unable to instantiate instance of class: " + clazz.getName();
+ throw new ModelException( error, e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ final String error =
+ "Cannot access null parameter constructor for the class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ catch ( Throwable e )
+ {
+ final String error =
+ "Unexpected exception while creating the class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ }
+
+ private Object getSingleArgumentConstructorValue(
+ ClassLoader classLoader, Class clazz, String argument )
+ throws ModelException
+ {
+ if ( argument.startsWith( "${" ) )
+ {
+ if ( argument.endsWith( "}" ) )
+ {
+ final String key = argument.substring( 2, argument.length()
- 1 );
+ Object value = m_map.get( key );
+ if ( value != null )
+ {
+ if( value instanceof EntryModel )
+ {
+ return ((EntryModel)value).getValue();
+ }
+ else
+ {
+ return value;
+ }
+ }
+ else
+ {
+ final String error =
+ "Unresolvable context value: '" + key + "'.";
+ throw new ModelException( error );
+ }
+ }
+ else
+ {
+ final String error =
+ "Illegal format for context reference: '" + argument +
"'.";
+ throw new ModelException( error );
+ }
+ }
+ else
+ {
+ //
+ // the argument is a simple type that takes a single String value
+ // as a constructor argument
+ //
+
+ if( clazz.isPrimitive() )
+ {
+ if( Integer.TYPE == clazz )
+ {
+ return Integer.valueOf( argument );
+ }
+ else if( Boolean.TYPE == clazz )
+ {
+ return Boolean.valueOf( argument );
+ }
+ else if( Byte.TYPE == clazz )
+ {
+ return Byte.valueOf( argument );
+ }
+ else if( Short.TYPE == clazz )
+ {
+ return Short.valueOf( argument );
+ }
+ else if( Long.TYPE == clazz )
+ {
+ return Long.valueOf( argument );
+ }
+ else if( Float.TYPE == clazz )
+ {
+ return Float.valueOf( argument );
+ }
+ else if( Double.TYPE == clazz )
+ {
+ return Double.valueOf( argument );
+ }
+ else
+ {
+ final String error =
+ "The primitive return type ["
+ + clazz.getName()
+ + "] is not supported.";
+ throw new ModelException( error );
+ }
+ }
+
+ try
+ {
+ final Class[] params = new Class[]{ String.class };
+ Constructor constructor = clazz.getConstructor( params );
+ final Object[] values = new Object[]{ argument };
+ return constructor.newInstance( values );
+ }
+ catch ( NoSuchMethodException e )
+ {
+ final String error =
+ "Class: '" + clazz.getName()
+ + "' does not implement a single string argument
constructor.";
+ throw new ModelException( error );
+ }
+ catch ( InstantiationException e )
+ {
+ final String error =
+ "Unable to instantiate instance of class: " +
clazz.getName()
+ + " with the single argument: '" + argument + "'";
+ throw new ModelException( error, e );
+ }
+ catch ( IllegalAccessException e )
+ {
+ final String error =
+ "Cannot access single string parameter constructor for the
class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ catch ( Throwable e )
+ {
+ final String error =
+ "Unexpected exception while creating a single string
parameter value for the class: '"
+ + clazz.getName() + "'.";
+ throw new ModelException( error, e );
+ }
+ }
+ }
+
+ /**
+ * Return the classname of the parameter implementation to use.
+ * @param loader the classloader to use
+ * @return the parameter class
+ * @exception ModelException if the parameter class cannot be resolved
+ */
+ Class getValueClass( String classname, ClassLoader classLoader ) throws
ModelException
+ {
+ try
+ {
+ return classLoader.loadClass( classname );
+ }
+ catch ( final ClassNotFoundException e )
+ {
+ if ( classname.equals( "int" ) )
+ {
+ return int.class;
+ }
+ else if ( classname.equals( "short" ) )
+ {
+ return short.class;
+ }
+ else if ( classname.equals( "long" ) )
+ {
+ return long.class;
+ }
+ else if ( classname.equals( "byte" ) )
+ {
+ return byte.class;
+ }
+ else if ( classname.equals( "double" ) )
+ {
+ return double.class;
+ }
+ else if ( classname.equals( "byte" ) )
+ {
+ return byte.class;
+ }
+ else if ( classname.equals( "float" ) )
+ {
+ return float.class;
+ }
+ else if ( classname.equals( "char" ) )
+ {
+ return char.class;
+ }
+ else if ( classname.equals( "char" ) )
+ {
+ return char.class;
+ }
+ else if ( classname.equals( "boolean" ) )
+ {
+ return boolean.class;
+ }
+ else
+ {
+ throw new ModelException(
+ "Could not locate the parameter implementation for class:
'"
+ + classname + "'.", e );
+ }
+ }
+ }
+}

Modified: development/main/metro/composition/testing/acme/build.xml
==============================================================================
--- development/main/metro/composition/testing/acme/build.xml (original)
+++ development/main/metro/composition/testing/acme/build.xml Sat Mar 26
00:57:13 2005
@@ -15,15 +15,19 @@

<!-- create a classic container model -->
<container xmlns="plugin:dpml/composition/dpml-composition-builder"
name="acme">
- <component name="widget"
class="net.dpml.composition.testing.DefaultWidget"/>
- <component name="gizmo"
class="net.dpml.composition.testing.DefaultGizmo">
+ <component name="widget"
class="net.dpml.composition.testing.DefaultWidget">
<context>
+ <entry key="foo" value="bar"/>
<entry key="width" value="12"/>
<entry key="height" value="100"/>
</context>
+ </component>
+ <component name="gizmo"
class="net.dpml.composition.testing.DefaultGizmo">
+ <!--
<dependencies>
<dependency key="widget" source="widget"/>
</dependencies>
+ -->
<parts>
<value key="foo" value="bar"/>
<value key="date" class="java.util.Date"/>

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultGizmo.java
Sat Mar 26 00:57:13 2005
@@ -28,13 +28,6 @@
public class DefaultGizmo implements Gizmo
{
//------------------------------------------------------------------
- // state
- //------------------------------------------------------------------
-
- private final Logger m_logger;
- private final Widget m_widget;
-
- //------------------------------------------------------------------
// constructor
//------------------------------------------------------------------

@@ -44,27 +37,20 @@
* @param logger the logging channel assigned by the container
* @param dependencies the requested dependencies
*/
- public DefaultGizmo( Logger logger, Dependencies dependencies, Parts
parts )
+ public DefaultGizmo( Logger logger, Dependencies dependencies )
{
- m_logger = logger;
- m_widget = dependencies.getTheAcmeWidget();
- m_logger.info( "up and running with: " + m_widget.toString() );
+ logger.info( "initializing" );
+ Widget widget = dependencies.getWidget();
+ logger.info( "widget established: " + widget );
}

//------------------------------------------------------------------
// facards
//------------------------------------------------------------------

- public interface Context
- {
- int getWidth();
-
- int getHeight( int defaultHeight );
- }
-
public interface Dependencies
{
- Widget getTheAcmeWidget();
+ Widget getWidget();
}

public interface Parts

Modified:
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
==============================================================================
---
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
(original)
+++
development/main/metro/composition/testing/acme/src/main/net/dpml/composition/testing/DefaultWidget.java
Sat Mar 26 00:57:13 2005
@@ -34,12 +34,6 @@
public static final boolean TYPE_THREADSAFE_CAPABLE = true;

//------------------------------------------------------------------
- // state
- //------------------------------------------------------------------
-
- private final Logger m_logger;
-
- //------------------------------------------------------------------
// constructor
//------------------------------------------------------------------

@@ -48,9 +42,28 @@
*
* @param logger the logging channel asign by the container
*/
- public DefaultWidget( Logger logger )
+ public DefaultWidget( Logger logger, Context context )
+ {
+ String foo = context.getFoo();
+ int width = context.getWidth();
+ int height = context.getHeight( 5024 );
+
+ logger.info(
+ foo
+ + " established with a width of "
+ + width
+ + " and a height of "
+ + height );
+ }
+
+ //------------------------------------------------------------------
+ // facards
+ //------------------------------------------------------------------
+
+ public interface Context
{
- m_logger = logger;
- m_logger.info( "up and running" );
+ String getFoo();
+ int getWidth();
+ int getHeight( int defaultHeight );
}
}

Added: development/main/metro/composition/testing/unit/build.xml
==============================================================================
--- (empty file)
+++ development/main/metro/composition/testing/unit/build.xml Sat Mar 26
00:57:13 2005
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<project name="dpml-composition-testing-unit" default="install" basedir="."
+ xmlns:transit="antlib:net.dpml.transit"
xmlns:x="plugin:dpml/magic/dpml-magic-core">
+
+ <transit:import uri="artifact:template:dpml/magic/standard"/>
+
+ <target name="init" depends="standard.init">
+ <x:property key="dpml-composition-testing-acme" feature="uri"
type="part" name="acme.part"/>
+ <filter token="ACME-PART-URI" value="${acme.part}"/>
+ </target>
+
+</project>

Added:
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/test/FreightTestCase.java
==============================================================================
--- (empty file)
+++
development/main/metro/composition/testing/unit/src/test/net/dpml/composition/test/FreightTestCase.java
Sat Mar 26 00:57:13 2005
@@ -0,0 +1,67 @@
+/*
+ * 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.test;
+
+import java.net.URI;
+
+import net.dpml.metro.unit.CompositionTestCase;
+
+import net.dpml.composition.model.DeploymentModel;
+import net.dpml.composition.model.ContainmentModel;
+
+import net.dpml.exception.ExceptionHelper;
+
+/**
+ * The hello component testcase validates that the
+ * hello example is deployable.
+ */
+public class FreightTestCase extends CompositionTestCase
+{
+ //----------------------------------------------------------
+ // testcase
+ //----------------------------------------------------------
+
+ public void setUp() throws Exception
+ {
+ super.setupCompositionRoot();
+ }
+
+ /**
+ * Validate that the hello component is deployable and resolvable.
+ * @exception if a deployment error occurs
+ */
+ public void testFreight() throws Throwable
+ {
+ try
+ {
+ URI uri = new URI( "@ACME-PART-URI@" );
+ DeploymentModel test = getRoot().addModel( "test", uri );
+ test.commission();
+ Object object = test.resolve( false );
+ test.release( object );
+ getRoot().decommission();
+ }
+ catch( Throwable e )
+ {
+ final String header = "Derailed!";
+ String stack = ExceptionHelper.packException( header, e, true );
+ System.out.println( stack );
+ throw e;
+ }
+ }
+}

Modified: development/main/metro/index.xml
==============================================================================
--- development/main/metro/index.xml (original)
+++ development/main/metro/index.xml Sat Mar 26 00:57:13 2005
@@ -318,6 +318,7 @@
</types>
</info>
<dependencies>
+ <include key="dpml-automation-part" tag="api"/>
<include key="dpml-composition-spi"/>
<include key="dpml-composition-impl" build="false"/>
<include key="dpml-configuration-api"/>
@@ -412,6 +413,7 @@
<include key="dpml-util-cli"/>
<include key="dpml-activation-impl" build="false"/>
<include key="dpml-test-playground" build="false"/>
+ <include key="dpml-composition-control"/>
</dependencies>
</project>

@@ -525,6 +527,22 @@
</plugins>
</project>

+ <project basedir="composition/testing/unit">
+ <info>
+ <group>dpml/test</group>
+ <name>dpml-composition-testing-unit</name>
+ <version>1.0.0</version>
+ <status>SNAPSHOT</status>
+ <types>
+ <type>jar</type>
+ </types>
+ </info>
+ <dependencies>
+ <include key="dpml-composition-testing-acme" build="false"/>
+ <include key="dpml-metro-unit"/>
+ </dependencies>
+ </project>
+
<!-- Utitlities -->

<project basedir="util/defaults">
@@ -849,7 +867,6 @@
</types>
</info>
<dependencies>
- <include key="dpml-activity-api" tag="api"/>
<include key="dpml-composition-api" tag="api"/>
<include key="avalon-framework-api" tag="api"/>
<include key="dpml-activation-api" tag="api"/>
@@ -878,6 +895,7 @@
<include key="dpml-transit-main" tag="api"/>
<include key="dpml-activation-api" tag="api"/>
<include key="dpml-composition-api" tag="api"/>
+ <include key="dpml-automation-part" tag="api"/>
<include key="dpml-activation-metro-provider" build="false"/>
<include key="dpml-activation-avalon-provider" build="false"/>
<include key="dpml-system-impl" build="false"/>

Added:
development/main/metro/service/api/src/main/net/dpml/service/FulfillmentRuntimeException.java
==============================================================================
--- (empty file)
+++
development/main/metro/service/api/src/main/net/dpml/service/FulfillmentRuntimeException.java
Sat Mar 26 00:57:13 2005
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2004 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.service;
+
+/**
+ * Exception to indicate that there was a fatal service error.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: FatalServiceException.java 259 2004-10-30 07:24:40Z
mcconnell $
+ */
+public class FulfillmentRuntimeException
+ extends RuntimeException
+{
+ final String m_key;
+
+ /**
+ * Construct a new <code>FulfillmentRuntimeException</code> instance.
+ *
+ * @param key the lookup key
+ * @param message The detail message for this exception.
+ * @param cause expected service availability delay in milliseconds
+ */
+ public FulfillmentRuntimeException(
+ final String key, final String message, Throwable cause )
+ {
+ super( message, cause );
+ m_key = key;
+ }
+
+ public String getKey()
+ {
+ return m_key;
+ }
+}
+



  • svn commit: r2142 - in development/main/metro: . activation/providers/metro/src/main/net/dpml/activation/metro composition/api/src/main/net/dpml/composition/model composition/builder/src/main/net/dpml/composition/builder composition/control/src/main/net/dpml/composition/control composition/impl/src/main/net/dpml/composition/model/impl composition/testing/acme composition/testing/acme/src/main/net/dpml/composition/testing composition/testing/unit composition/testing/unit/src composition/testing/unit/src/test composition/testing/unit/src/test/net composition/testing/unit/src/test/net/dpml composition/testing/unit/src/test/net/dpml/composition composition/testing/unit/src/test/net/dpml/composition/test context/impl/src/main/net/dpml/context/impl service/api/src/main/net/dpml/service, mcconnell, 03/25/2005

Archive powered by MHonArc 2.6.24.

Top of Page