mcconnell 2003/07/14 15:03:44
Modified: merlin/composition/src/java/org/apache/avalon/composition/model/impl
DefaultConstructorModel.java
DefaultTypeRepository.java Resources.properties
Scanner.java
merlin/composition/src/test/conf context.xml
merlin/composition/src/test/org/apache/avalon/composition/model/test
ContextTestCase.java
merlin/composition/src/test/org/apache/avalon/composition/model/testa
TestA.xinfo
Log:
Add declared extension class checking, more i18n and some more ddetailed exception
handling to the scanner.
Revision Changes Path
1.3 +113 -10
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultConstructorModel.java
Index: DefaultConstructorModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultConstructorModel.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultConstructorModel.java 14 Jul 2003 04:46:24 -0000 1.2
+++ DefaultConstructorModel.java 14 Jul 2003 22:03:43 -0000 1.3
@@ -111,7 +111,7 @@
*/
public DefaultConstructorModel(
EntryDescriptor descriptor, ConstructorDirective directive,
- DeploymentContext context, Map map )
+ DeploymentContext context, Map map ) throws ModelException
{
super( descriptor );
@@ -127,8 +127,78 @@
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 );
+ Parameter[] params = m_directive.getParameters();
+
+ //
+ // TODO:
+ // wizz through and validate all of the parameter declarations
+ // and make sure that constructors exist that match the sub-parameter
+ // delcarations
+ //
}
+ private void validatePair( String descriptorClass, String directiveClass )
+ throws ModelException
+ {
+ 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
//==============================================================
@@ -150,7 +220,6 @@
try
{
ClassLoader loader = m_context.getClassLoader();
-
String classname = m_directive.getClassname();
String argument = m_directive.getArgument();
Parameter[] params = m_directive.getParameters();
@@ -171,7 +240,6 @@
}
return object;
-
}
/**
@@ -181,7 +249,6 @@
*/
public Object getValue( Parameter p ) throws ModelException
{
-
ClassLoader loader = m_context.getClassLoader();
String classname = p.getClassname();
String argument = p.getArgument();
@@ -201,20 +268,26 @@
ClassLoader loader, Class clazz, String argument,
Parameter[] 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( argument != null )
+ if( parameters.length == 0 )
{
- return getSingleArgumentConstructorValue( loader, clazz, argument );
+ if( argument == null )
+ {
+ return getNullArgumentConstructorValue( clazz );
+ }
+ else
+ {
+ return getSingleArgumentConstructorValue( loader, clazz, argument );
+ }
}
else
{
- return getMultiArgumentConstructorValue( loader, clazz, parameters );
+ return getMultiArgumentConstructorValue( loader, clazz, parameters );
}
}
@@ -327,6 +400,35 @@
}
}
+ 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
@@ -350,7 +452,8 @@
}
else
{
- final String error = "Unresolvable primative context value:
'" + key + "'.";
+ final String error =
+ "Unresolvable primative context value: '" + key + "'.";
throw new ModelException( error );
}
}
1.7 +2 -1
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultTypeRepository.java
Index: DefaultTypeRepository.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultTypeRepository.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- DefaultTypeRepository.java 12 Jul 2003 21:10:45 -0000 1.6
+++ DefaultTypeRepository.java 14 Jul 2003 22:03:43 -0000 1.7
@@ -72,6 +72,7 @@
import org.apache.avalon.meta.info.DependencyDescriptor;
import org.apache.avalon.meta.info.ReferenceDescriptor;
import org.apache.avalon.meta.info.ServiceDescriptor;
+import org.apache.avalon.meta.info.ExtensionDescriptor;
import org.apache.avalon.meta.info.StageDescriptor;
import org.apache.avalon.meta.info.Type;
import org.apache.avalon.meta.info.builder.TypeBuilder;
1.10 +34 -13
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties
Index: Resources.properties
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Resources.properties,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -r1.9 -r1.10
--- Resources.properties 14 Jul 2003 04:46:24 -0000 1.9
+++ Resources.properties 14 Jul 2003 22:03:43 -0000 1.10
@@ -1,25 +1,31 @@
#
# DefaultContainmentModelFactory
+# ==============================
factory.containment.create.error=Unable to construct a new containment model: {0}.
+
# DefaultClassLoaderModel
+# =======================
classloader.unsatisfied-extensions.error=Classpath contains {0} unsatisfied
extension dependencies.
classloader.missing.extension.error=Unable to locate a required extension.\n
Extension Name: {0}\n Specification Vendor: {1}\n Specification Version: {2}\n
Implementation Vendor: {3}\n Implementation Vendor-Id: {4}\n Implementation Version:
{5}\n Implementation URL: {6}
classloader.bad-classpath-entry.error=Cannot load manifest from classpath
reference: {0}.
classloader.child.creation.error=Internal error while attempt to construct a child
classloader model for containment profile: {0}.
+
# DefaultContainmentModel
+# =======================
containment.classloader.create.error=Unable to create a classloader for the
containment context: {0}.
-containment.composition.create.error=Unable to create composition model: {1} in {0}.
-containment.container.create.error=Unable to create containment model: {1} in {0}.
-containment.deployment.create.error=Unable to create deployment model: {1} in {0}.
+containment.container.create.error=Unable to create nested containment model: {1}
in the containment model {0}.
+containment.deployment.create.error=Unable to create a nested deployment model: {1}
in the containment model {0}.
containment.unknown-profile-class.error=Unknown profile class: {1} in {0}.
containment.context.home.not-a-directory.error=Supplied home dir is not a
directory: {0}
containment.context.temp.not-a-directory.error=Supplied temp dir is not a
directory: {0}
containment.add=added: {0}
+
# DefaultDeploymentModel
+# ======================
deployment.parameters.irrational=Illegal attempt to set a parameter value for a
component type '{0}' that is not parameterizable in the model: {1}.
deployment.configuration.irrational=Illegal attempt to set a configuration value
for a component type '{0}' that is not configurable in the model: {1}.
deployment.context.home.not-a-directory.error=Supplied home dir is not a directory:
{0}
@@ -31,19 +37,27 @@
deployment.context.internal.error=The context key [{0}] was recognized but could
not be fulfilled as no context entry model has be assigned to handle the request.
deployment.registration.override.error=Illegal attempt to override an existing
model entry [{0}].
+
# DefaultModel
+# ============
created=created: {0}
+
# DefaultSystemContext
+# ====================
system.context.base.not-a-directory.error="Base directory argument is not a
directory: {0}.
+
# DefaultTypeRepository
+# =====================
type.repository.null-create.error=Internal error while creating NullComponent type
defintion. {0}
type.repository.bootstrap.error=bootstrap: {0}
type.repository.count=type install count: {0}
type.repository.addition=add: {0}, ({1}).
+
#Scanner
+# ======
scanner.scanning=scanning: {0}
scanner.dir-scan.error=Unexpected error while attempting to scan directory: {0}
scanner.nested-jar-unsupported.error=Embeded jar file loading not supported: {0}
@@ -54,38 +68,45 @@
scanner.type.verification.failure=Ignoring type due to verification error: {0}
scanner.service.addition=type: {0}
scanner.service.verification.failure=Ignoring service due to verification error: {0}
-scanner.service.missing-class.error=Could not locate implementation class for
service: {0}
-scanner.type.missing-class.error=Could not locate implementation class for type: {0}
+scanner.service.missing-class.error=Cannot load service because the implementation
class for service [{0}] does not exist within the classloader.
+scanner.service.bad-class.error=Cannot load service [{0}] because the class
references the class [{1}] which does not exist in the classloader.
scanner.url-not-a-directory.error=URL does not refer to a directory: {0}
scanner.not-file-protocol.error=URL protocol does not match the required 'file'
protocol: {0}
+scanner.type.missing-class.error=Cannot load component type because the type class
{0} does not exist in the classloader.
+scanner.type.bad-class.error=Component type [{0}] contains a reference to the class
[{1}] which does not exist in the classloader.
+scanner.extension.bad-class.error=Cannot load component type [{0}] because the type
declares an extension class [{1}] which cannot be loaded to a missing class [{2}].
+scanner.extension.missing.error=Cannot load component type [{0}] contains because
the extension class it declares [{1}] does not exist in the classloader.
# DefaultImportModel
+# ==================
import.type-conflict.error=The object returned from the internal deployment context
matching the import directive key: {0} does not implement the context entry class: {1}
requested by the component under its local key: {2}.;
-
import.missing-entry.error=Cannot import context entry {0} requested for the
component context entry key {1} because the requested import key is unknown within the
scope of the supplied containment context.
-
import.load.error=Cannot load context entry for the component key: {0} because a
corresponding import directive could not load the class {1} declared as a constraint
by the component type entry declaration.
-
import.null-object.error=Resolution of the include directive for the containment
key {0} undeer the component context entry {1) return a null object reference.
#DefaultContextModel
+# ==================
context.strategy.custom=custom strategy: {0}
context.strategy.avalon=avalon strategy
context.non-standard-avalon-key.error=The component has requested a Avalon context
entry that is not know within the family of standard Avalon context keys. The
offending key is: {0}.
-
context.missing-directive.error=The component has requested a non-avalon context
entry. The container cannot resolve this request because no entry directive can be
found the matches the key: {0}.
-
context.unsupported-directive.error=The component has requested a context entry
under the key [{0}]. The container cannot resolve this request because the entry
directive type [{1}] is not supported at this time.
-
context.non-compliance-constructor.error="Custom context class [{0}] does not
implement a constructor pattern <init>( org.apache.avalon.framework.Context ).
-
context.custom-unexpected.error=Unexpected error occured while attempting to
construct a custom context using the class [{0}].
-
context.strategy.custom.missing.error=Custom stategy class [{0}] is not present in
the classpath.
context.strategy.custom.unexpected.error=Unable to load the custom stategy class
[{0}] due to an unexpected error.
context.strategy.avalon.missing.error=Classic Avalon context stategy class [{0}] is
not present in the classpath.
context.strategy.avalon.unexpected.error=Unable to load the classic Avalon stategy
class [{0}] due to an unexpected error.
# DefaultContext
+# ==============
context.entry.model.error=Cannot fulfill request due to an model-related error
while attempting to resolve a context entry for the key: {0}.
+
+# DefaultConstructorModel
+# =======================
+constructor.descriptor.unknown.error=The constructor entry descriptor declared
under the key [{0}] references a class [{1}] that does not exist within the associated
classloader.
+constructor.descriptor.load.error=The constructor entry descriptor declared under
the key [{0}] references a class [{1}] that that could not be loaded due to an runtime
error.
+constructor.directive.unknown.error=The constructor entry directive declared under
the key [{0}] references a class [{1}] that does not exist within the associated
classloader.
+constructor.directive.load.error=The constructor entry directive declared under the
key [{0}] references a class [{1}] that that could not be loaded due to an runtime
error.
+constructor.invalid-model.error=The component type declares a dependency under the
context entry [{0}] on a runtime entry of the type [{1}], however, the corresponding
directive declares a constructor that establishes an instance of the class [{2}] which
does not implement or extend the class declared by the directive.
1.8 +93 -42
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Scanner.java
Index: Scanner.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/Scanner.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- Scanner.java 12 Jul 2003 21:10:45 -0000 1.7
+++ Scanner.java 14 Jul 2003 22:03:43 -0000 1.8
@@ -79,6 +79,7 @@
import org.apache.avalon.meta.data.builder.ProfilePackageBuilder;
import org.apache.avalon.meta.info.Service;
import org.apache.avalon.meta.info.ServiceDescriptor;
+import org.apache.avalon.meta.info.ExtensionDescriptor;
import org.apache.avalon.meta.info.Type;
import org.apache.avalon.meta.info.builder.TypeBuilder;
import org.apache.avalon.meta.info.builder.ServiceBuilder;
@@ -371,33 +372,12 @@
private void addType( List types, String name ) throws Exception
{
String classname = parseResourceName( name );
- Class clazz = null;
- try
- {
- clazz = m_classloader.loadClass( classname );
- }
- catch( NoClassDefFoundError ncdf )
- {
- String ref = parseResourceName( ncdf.getMessage() );
- final String error =
- "Component type: " + classname
- + " references the class: " + ref
- + " which does not exist in the classloader.";
- throw new ModelException( error );
- }
- catch( ClassNotFoundException cnfe )
- {
- final String error =
- "Component type: " + classname
- + " does not exist in the classloader.";
- throw new ModelException( error, cnfe );
- }
-
+ Class clazz = getComponentClass( classname );
Type type = TYPE_BUILDER.buildType( clazz );
try
{
- verifyType( type );
+ verifyType( type, clazz );
if( getLogger().isDebugEnabled() )
{
final String message =
@@ -448,17 +428,65 @@
/**
* Verify the intergrity of the supplied type.
* @param type the type to verify
+ * @param clazz the implementation class
* @exception Exception if an verification failure occurs
*/
- private void verifyType( Type type ) throws Exception
+ private void verifyType( Type type, Class clazz ) throws Exception
{
- String name = type.getInfo().getName();
- Class clazz = getComponentClass( type );
- Class[] classes = getServiceClasses( type );
- ComponentVerifier verifier = new ComponentVerifier();
+ final String name = type.getInfo().getName();
+ final Class[] classes = getServiceClasses( type );
+ final Class[] extensions = getExtensionClasses( type );
+ final ComponentVerifier verifier = new ComponentVerifier();
verifier.verifyComponent( name, clazz, classes );
}
+ /**
+ * Return the set of lifecycle extension classes provided
+ * by the given type. This method is used as part of the
+ * process of verifying the integrity of a type.
+ *
+ * @param type the component type
+ * @return an array of classes represnting the lifecycle
+ * extension interfaces provided by the type
+ */
+ private Class[] getExtensionClasses( Type type )
+ throws ModelException
+ {
+ ArrayList list = new ArrayList();
+ ExtensionDescriptor[] extensions = type.getExtensions();
+ for( int i = 0; i < extensions.length; i++ )
+ {
+ ExtensionDescriptor extension = extensions[i];
+ list.add( getExtensionClass( type, extension ) );
+ }
+ return (Class[]) list.toArray( new Class[0] );
+ }
+
+ private Class getExtensionClass( Type type, ExtensionDescriptor extension )
+ throws ModelException
+ {
+ final String classname = extension.getReference().getClassname();
+ final String typeClass = type.getInfo().getClassname();
+ try
+ {
+ return m_classloader.loadClass( classname );
+ }
+ catch( NoClassDefFoundError ncdf )
+ {
+ String ref = parseResourceName( ncdf.getMessage() );
+ final String error =
+ REZ.getString( "scanner.extension.bad-class.error", typeClass,
classname, ref );
+ throw new ModelException( error );
+ }
+ catch( ClassNotFoundException cnfe )
+ {
+ final String error =
+ REZ.getString( "scanner.extension.missing-class.error", typeClass,
classname );
+ throw new ModelException( error );
+ }
+ }
+
+
/**
* Verify the intergrity of the supplied type.
* @param type the type to verify
@@ -471,11 +499,18 @@
{
m_classloader.loadClass( classname );
}
- catch( Throwable e )
+ catch( NoClassDefFoundError ncdf )
{
- final String error =
+ String ref = parseResourceName( ncdf.getMessage() );
+ final String error =
+ REZ.getString( "scanner.service.bad-class.error", classname, ref );
+ throw new ModelException( error );
+ }
+ catch( ClassNotFoundException cnfe )
+ {
+ final String error =
REZ.getString( "scanner.service.missing-class.error", classname );
- throw new ModelException( error, e );
+ throw new ModelException( error );
}
}
@@ -488,7 +523,8 @@
* @param type the component type
* @return an array of classes represnting the type's service interfaces
*/
- private Class[] getServiceClasses( Type type ) throws ModelException
+ private Class[] getServiceClasses( Type type )
+ throws ModelException
{
ArrayList list = new ArrayList();
ServiceDescriptor[] services = type.getServices();
@@ -509,26 +545,42 @@
* Returns the component type implementation class.
* @param type the component type descriptor
* @return the class implementing the component type
- * @exception TypeException if a classloader error occurs
+ * @exception ModelException if a classloader error occurs
*/
- private Class getComponentClass( Type type ) throws ModelException
+ private Class getComponentClass( Type type )
+ throws ModelException
{
if( null == type )
{
throw new NullPointerException( "type" );
}
+ return getComponentClass( type.getInfo().getClassname() );
+ }
- final String classname = type.getInfo().getClassname();
-
+ /**
+ * Returns the component type implementation class.
+ * @param classname the component type implementation classname
+ * @exception ModelException if a classloader error occurs
+ */
+ private Class getComponentClass( String classname )
+ throws ModelException
+ {
try
{
return m_classloader.loadClass( classname );
}
- catch( Throwable e )
+ catch( NoClassDefFoundError ncdf )
{
- final String error =
+ String ref = parseResourceName( ncdf.getMessage() );
+ final String error =
+ REZ.getString( "scanner.type.bad-class.error", classname, ref );
+ throw new ModelException( error );
+ }
+ catch( ClassNotFoundException cnfe )
+ {
+ final String error =
REZ.getString( "scanner.type.missing-class.error", classname );
- throw new ModelException( error, e );
+ throw new ModelException( error );
}
}
@@ -536,7 +588,7 @@
* Returns the service type implementation class.
* @param service the service type descriptor
* @return the class implementing the service type
- * @exception TypeRuntimeException if a classloader error occurs
+ * @exception ModelException if a classloader error occurs
*/
private Class getServiceClass( ServiceDescriptor service ) throws ModelException
{
@@ -552,7 +604,6 @@
throw new ModelException( error, e );
}
}
-
private boolean isDirectory( URL url )
{
1.2 +16 -1 avalon-sandbox/merlin/composition/src/test/conf/context.xml
Index: context.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/conf/context.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- context.xml 14 Jul 2003 04:49:36 -0000 1.1
+++ context.xml 14 Jul 2003 22:03:43 -0000 1.2
@@ -14,6 +14,21 @@
</classpath>
</classloader>
- <component name="test-a"
class="org.apache.avalon.composition.model.testa.TestA"/>
+ <component name="test-a" class="org.apache.avalon.composition.model.testa.TestA">
+ <context class="org.apache.avalon.composition.model.testa.DefaultFacade">
+ <entry key="home">
+ <constructor class="java.io.File">
+ <param class="java.io.File">${urn:avalon:home.dir}</param>
+ <param>xxx</param>
+ </constructor>
+ </entry>
+ <entry key="time">
+ <constructor class="java.util.Date"/>
+ </entry>
+ <entry key="path">
+ <import key="urn:avalon:partition.name"/>
+ </entry>
+ </context>
+ </component>
</container>
1.2 +59 -1
avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/ContextTestCase.java
Index: ContextTestCase.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/test/ContextTestCase.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ContextTestCase.java 14 Jul 2003 04:49:36 -0000 1.1
+++ ContextTestCase.java 14 Jul 2003 22:03:43 -0000 1.2
@@ -5,6 +5,7 @@
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.Date;
import org.apache.avalon.composition.model.Model;
import org.apache.avalon.composition.model.DeploymentModel;
@@ -15,10 +16,13 @@
import org.apache.avalon.framework.context.ContextException;
import org.apache.avalon.meta.info.DependencyDescriptor;
import org.apache.avalon.meta.info.ServiceDescriptor;
+import org.apache.avalon.composition.model.testa.Facade;
public class ContextTestCase extends AbstractTestCase
{
-
+ private static final String FACADE_CLASSNAME =
+ "org.apache.avalon.composition.model.testa.DefaultFacade";
+
//-------------------------------------------------------
// constructor
//-------------------------------------------------------
@@ -103,5 +107,59 @@
{
assertTrue( "name", false );
}
+
+ //
+ // validate volatile entries
+ //
+
+ Date date = null;
+ try
+ {
+ date = (Date) context.get( "time" );
+ try
+ {
+ Thread.currentThread().sleep( 1200 );
+ }
+ catch( Throwable e )
+ {
+ // continue
+ }
+ }
+ catch( ContextException e )
+ {
+ assertTrue( "date", false );
+ }
+
+ try
+ {
+ Date now = (Date) context.get( "time" );
+ assertTrue( "volatile", now.after( date ) );
+ }
+ catch( ContextException e )
+ {
+ assertTrue( "now", false );
+ }
+
+ //
+ // validate an imported context entry
+ //
+
+ try
+ {
+ String path = (String) context.get( "path" );
+ }
+ catch( ContextException e )
+ {
+ assertTrue( "path", false );
+ }
+
+ //
+ // validate context safe-casting
+ // (e.g. ((MyContext)m_context).myMethod() type of thing)
+ //
+
+ final String className = context.getClass().getName();
+ boolean classNameMatches = className.equals( FACADE_CLASSNAME );
+ assertTrue( "custom context", classNameMatches );
}
}
1.3 +4 -1
avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/testa/TestA.xinfo
Index: TestA.xinfo
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/test/org/apache/avalon/composition/model/testa/TestA.xinfo,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- TestA.xinfo 14 Jul 2003 04:49:36 -0000 1.2
+++ TestA.xinfo 14 Jul 2003 22:03:44 -0000 1.3
@@ -4,12 +4,15 @@
<name>component-a</name>
<lifestyle>singleton</lifestyle>
</info>
- <context>
+ <context type="org.apache.avalon.composition.model.testa.Facade">
<entry key="urn:avalon:partition.name"/>
<entry key="urn:avalon:classloader"/>
<entry key="urn:avalon:home.dir"/>
<entry key="urn:avalon:temp.dir"/>
<entry key="urn:avalon:name" alias="name"/>
+ <entry key="home" type="java.io.File"/>
+ <entry key="time" type="java.util.Date" volatile="true"/>
+ <entry key="path"/>
</context>
<services>
<service type="org.apache.avalon.composition.model.testa.A"/>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]