mcconnell 2003/07/05 20:00:26
Modified: merlin/composition/src/java/org/apache/avalon/composition/model/impl
DefaultClassLoaderModel.java
DefaultCompositionModel.java
DefaultCompositionModelFactory.java
DefaultContainmentModel.java
DefaultDeploymentModel.java DefaultModel.java
DefaultServiceRepository.java
DefaultSystemContext.java
DefaultTypeRepository.java Resources.properties
Scanner.java
merlin/composition/src/test/conf block.xml
Log:
Completing i18n in the composition model package, addition of support for
composition block management, and improvements to the type and service creation
patterns.
Revision Changes Path
1.5 +18 -48
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java
Index: DefaultClassLoaderModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultClassLoaderModel.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- DefaultClassLoaderModel.java 5 Jul 2003 09:33:42 -0000 1.4
+++ DefaultClassLoaderModel.java 6 Jul 2003 03:00:25 -0000 1.5
@@ -155,10 +155,9 @@
* repository, a base directory and a classloader directive
* enabling the creation of a fully populated classpath.
*
- * @param base the base directory from which relative references
- * shall be resolved
- * @param repository a local cache of jar files addressable
- * relative to group/name/version identifiers
+ * @param logger the assigned logging channel
+ * @param system the system context
+ * @param classloader the parent classloader
* @param directive the classloader directive containing the
* primative classpath entries and resource directives
*/
@@ -177,7 +176,6 @@
*
* @param logger the assigned logging channel
* @param system the system context
- * @param classloader the parent classloader
* @param parent the parent classloader model
* @param directive the classloader directive containing the
* primative classpath entries and resource directives
@@ -274,22 +272,22 @@
scanner.enableLogging( logger.getChildLogger( "scanner" ) );
scanner.scan( m_urls, types, services );
+ Logger typeLogger = logger.getChildLogger( "types" );
+ Logger serviceLogger = logger.getChildLogger( "services" );
if( parent != null )
{
m_types = new DefaultTypeRepository(
- m_classLoader, parent.getTypeRepository(), types );
+ typeLogger, m_classLoader, parent.getTypeRepository(), types );
m_services = new DefaultServiceRepository(
- m_classLoader, parent.getServiceRepository(), services );
+ serviceLogger, parent.getServiceRepository(), services );
}
else
{
- m_types = new DefaultTypeRepository( m_classLoader, types );
- m_services = new DefaultServiceRepository( m_classLoader, services );
+ m_types = new DefaultTypeRepository(
+ typeLogger, m_classLoader, types );
+ m_services = new DefaultServiceRepository(
+ serviceLogger, services );
}
-
- m_types.enableLogging( logger.getChildLogger( "types" ) );
- m_services.enableLogging( logger.getChildLogger( "services" ) );
- m_types.initialize();
}
//==============================================================
@@ -397,36 +395,7 @@
{
return m_logger;
}
-/*
- private static void setUpRepositories(
- ClassLoader classLoader, ClassLoaderModel parent, Logger logger, URL[] urls )
- throws Exception
- {
- ArrayList types = new ArrayList();
- ArrayList services = new ArrayList();
-
- Scanner scanner = new Scanner( classLoader );
- scanner.enableLogging( logger.getChildLogger( "scanner" ) );
- scanner.scan( urls, types, services );
-
- if( parent != null )
- {
- m_types = new DefaultTypeRepository(
- m_classLoader, parent.getTypeRepository(), types );
- m_services = new DefaultServiceRepository(
- m_classLoader, parent.getServiceRepository(), services );
- }
- else
- {
- m_types = new DefaultTypeRepository( m_classLoader, types );
- m_services = new DefaultServiceRepository( m_classLoader, services );
- }
-
- m_types.enableLogging( logger.getChildLogger( "types" ) );
- m_services.enableLogging( logger.getChildLogger( "services" ) );
- }
-*/
/**
* Build the fully qulalified classpath including extension jar files
* resolved relative to the classpath directives in the meta-data.
@@ -524,7 +493,9 @@
{
final int size = unsatisfied.size();
final String message =
- REZ.getString( "unsatisfied.extensions", new Integer( size ) );
+ REZ.getString(
+ "classloader.unsatisfied-extensions.error",
+ new Integer( size ) );
StringBuffer buffer = new StringBuffer( message );
for( int i = 0; i < size; i++ )
{
@@ -539,7 +510,7 @@
extension.getImplementationVersion(),
extension.getImplementationURL()
};
- final String entry = REZ.format( "missing.extension", params );
+ final String entry = REZ.format(
"classloader.missing.extension.error", params );
buffer.append( "\n" + entry );
}
throw new Exception( buffer.toString() );
@@ -621,9 +592,8 @@
catch( final IOException ioe )
{
final String message =
- REZ.getString( "bad-classpath-entry", element );
- throw new Exception(
- message + ": " + element, ioe );
+ REZ.getString( "classloader.bad-classpath-entry.error",
element );
+ throw new Exception( message, ioe );
}
}
}
1.3 +51 -44
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultCompositionModel.java
Index: DefaultCompositionModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultCompositionModel.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultCompositionModel.java 4 Jul 2003 15:24:55 -0000 1.2
+++ DefaultCompositionModel.java 6 Jul 2003 03:00:25 -0000 1.3
@@ -89,11 +89,11 @@
// state
//==============================================================
- private SystemContext m_system;
+ private final SystemContext m_system;
- private CompositionProfile m_profile;
+ private final CompositionProfile m_profile;
- private DefaultContainmentModel m_implementation;
+ private final DefaultContainmentModel m_implementation;
//==============================================================
// constructor
@@ -104,36 +104,17 @@
* repository, a base directory and a classloader directive
* enabling the creation of a fully populated classpath.
*
- * @param base the base directory from which relative references
- * shall be resolved
- * @param repository a local cache of jar files addressable
- * relative to group/name/version identifiers
- * @param directive the composition profile
+ * @param logger the logging channel
+ * @param system the system context
+ * @param classLoaderModel the classloader model
+ * @param profile the composition profile
*/
protected DefaultCompositionModel(
final Logger logger, SystemContext system, ClassLoaderModel classLoaderModel,
CompositionProfile profile )
throws Exception
{
- super( logger, "", ContainmentModel.SEPERATOR );
-
- m_system = system;
- m_profile = profile;
-
- try
- {
- m_implementation =
- new DefaultContainmentModel(
- logger, system, classLoaderModel, profile.getImplementation() );
- }
- catch( Throwable e )
- {
- final String error =
- REZ.getString(
- "error.composition.implementation.create",
- getPath() );
- throw new ModelException( error, e );
- }
+ this( logger, system, classLoaderModel, null, profile, "", "" );
}
/**
@@ -143,6 +124,7 @@
*
* @param logger the logging channel
* @param system the system context
+ * @param classLoaderModel the classloader model
* @param parent the containment context
* @param profile the composition profile
*/
@@ -151,35 +133,60 @@
ContainmentModel parent, CompositionProfile profile )
throws Exception
{
- super(
- logger,
- profile.getName(),
- parent.getPath() + profile.getName() + ContainmentModel.SEPERATOR );
+ this( logger, system, classLoaderModel, parent, profile, profile.getName(),
+ parent.getPartition() );
+ }
+
+ /**
+ * Creation of a new composition model. The model associated a
+ * repository, a base directory and a classloader directive
+ * enabling the creation of a fully populated classpath.
+ *
+ * @param logger the logging channel
+ * @param system the system context
+ * @param classLoaderModel the classloader model
+ * @param parent the containment context
+ * @param profile the composition profile
+ * @param name the name to assign to the model
+ * @param partition the partition name
+ */
+ private DefaultCompositionModel(
+ final Logger logger, SystemContext system, ClassLoaderModel classLoaderModel,
+ ContainmentModel parent, CompositionProfile profile, String name, String
partition )
+ throws Exception
+ {
+ super( logger, name, partition );
m_system = system;
m_profile = profile;
try
{
- m_implementation =
- new DefaultContainmentModel(
- logger,
- system,
- parent,
- classLoaderModel,
- profile.getImplementation() );
+ if( parent != null )
+ {
+ m_implementation =
+ new DefaultContainmentModel(
+ logger, system, parent, classLoaderModel,
+ profile.getImplementation() );
+ }
+ else
+ {
+ m_implementation =
+ new DefaultContainmentModel(
+ logger, system, classLoaderModel,
+ profile.getImplementation() );
+ }
}
catch( Throwable e )
{
final String error =
- REZ.getString( "error.composition.implementation.create", getPath() );
+ REZ.getString( "composition.implementation.create.error", getPath() );
throw new ModelException( error, e );
}
-
}
//==============================================================
- // public implementation
+ // CompositionModel
//==============================================================
/**
@@ -210,11 +217,11 @@
}
//==============================================================
- // protected implementation
+ // implementation
//==============================================================
public String toString()
{
- return "[composition: " + getPath() + "]";
+ return "[composition model: " + getPath() + getName() + "]";
}
}
1.3 +23 -2
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultCompositionModelFactory.java
Index: DefaultCompositionModelFactory.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultCompositionModelFactory.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- DefaultCompositionModelFactory.java 4 Jul 2003 15:24:55 -0000 1.2
+++ DefaultCompositionModelFactory.java 6 Jul 2003 03:00:25 -0000 1.3
@@ -58,6 +58,8 @@
import org.apache.avalon.composition.model.ModelException;
import org.apache.avalon.composition.model.SystemContext;
import org.apache.avalon.composition.repository.Repository;
+import org.apache.avalon.excalibur.i18n.ResourceManager;
+import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.meta.data.CompositionProfile;
@@ -71,6 +73,16 @@
public class DefaultCompositionModelFactory extends AbstractLogEnabled
implements CompositionModelFactory
{
+ //==============================================================
+ // static
+ //==============================================================
+
+ private static final Resources REZ =
+ ResourceManager.getPackageResources(
DefaultCompositionModelFactory.class );
+
+ //==============================================================
+ // constructor
+ //==============================================================
/**
* Creation of a new instance of a composition model using
@@ -87,6 +99,10 @@
return createCompositionModel( system, null, profile );
}
+ //==============================================================
+ // CompositionModelFactory
+ //==============================================================
+
/**
* Creation of a new instance of a composition model.
*
@@ -111,6 +127,7 @@
}
final Logger logger = getLogger();
+
try
{
ClassLoader loader = getClassLoader( classloader );
@@ -123,10 +140,14 @@
catch( Throwable e )
{
final String error =
- "Unable to construct a new composition model.";
+ REZ.getString( "factory.composition.create.error", profile.getName()
);
throw new ModelException( error, e );
}
}
+
+ //==============================================================
+ // implementation
+ //==============================================================
private ClassLoader getClassLoader( ClassLoader classloader )
{
1.4 +32 -18
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModel.java
Index: DefaultContainmentModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultContainmentModel.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DefaultContainmentModel.java 5 Jul 2003 09:33:42 -0000 1.3
+++ DefaultContainmentModel.java 6 Jul 2003 03:00:25 -0000 1.4
@@ -95,12 +95,15 @@
// state
//==============================================================
+ private String m_partition;
+
private final ContainmentProfile m_profile;
private final ClassLoaderModel m_classLoaderModel;
private List m_models = new ArrayList();
+
//==============================================================
// constructor
//==============================================================
@@ -118,10 +121,12 @@
* @param profile the composition profile
*/
public DefaultContainmentModel(
- final Logger logger, SystemContext system, ClassLoaderModel classLoaderModel,
ContainmentProfile profile )
+ final Logger logger, SystemContext system,
+ ClassLoaderModel classLoaderModel, ContainmentProfile profile )
throws Exception
{
super( logger, system, classLoaderModel, profile, SEPERATOR );
+ m_partition = SEPERATOR;
m_profile = profile;
m_classLoaderModel = classLoaderModel;
expandContainmentModel( system );
@@ -144,18 +149,17 @@
ClassLoaderModel classLoaderModel, ContainmentProfile profile )
throws Exception
{
- super( logger, system, classLoaderModel, profile,
- parent.getPath() + profile.getName() + SEPERATOR );
+ super( logger, system, classLoaderModel, profile, parent.getPartition() );
+
+ m_partition = getPath() + getName() + SEPERATOR;
m_profile = profile;
m_classLoaderModel = classLoaderModel;
expandContainmentModel( system );
}
- private void expandContainmentModel( SystemContext system ) throws
ModelException
+ private void expandContainmentModel( SystemContext system )
+ throws ModelException
{
-
- getLogger().debug( "expanding: " + this );
-
try
{
Profile[] profiles = m_profile.getProfiles();
@@ -183,14 +187,11 @@
{
final String error =
REZ.getString(
- "error.containment.composition.create",
+ "containment.composition.create.error",
getPath(),
profile.getName() );
throw new ModelException( error, e );
}
- final String error =
- "Unsupported profile class: " + profile.getClass().getName();
- throw new ModelException( error );
}
else if( profile instanceof ContainmentProfile )
{
@@ -213,7 +214,7 @@
{
final String error =
REZ.getString(
- "error.containment.container.create",
+ "containment.container.create.error",
getPath(),
profile.getName() );
throw new ModelException( error, e );
@@ -230,14 +231,14 @@
system,
m_classLoaderModel,
deployment,
- getPath() );
+ getPartition() );
m_models.add( model );
}
catch( Throwable e )
{
final String error =
REZ.getString(
- "error.containment.deployment.create",
+ "containment.deployment.create.error",
getPath(),
profile.getName() );
throw new ModelException( error, e );
@@ -246,7 +247,10 @@
else
{
final String error =
- "Unrecognized profile class: " + profile.getClass().getName();
+ REZ.getString(
+ "containment.unknown-profile-class.error",
+ getPath(),
+ profile.getClass().getName() );
throw new ModelException( error );
}
}
@@ -254,7 +258,7 @@
catch( Throwable e )
{
final String error =
- REZ.getString( "error.composition.classloader.create", getPath() );
+ REZ.getString( "containment.classloader.create.error", getPath() );
throw new ModelException( error, e );
}
}
@@ -262,6 +266,16 @@
//==============================================================
// public implementation
//==============================================================
+
+ /**
+ * Return the partition name established by this containment context.
+ * @return the partition name
+ */
+ public String getPartition()
+ {
+ return m_partition;
+ }
+
/**
* Return the classloader model.
@@ -287,6 +301,6 @@
public String toString()
{
- return "[containment: " + getPath() + "]";
+ return "[containment model: " + getPath() + getName() + "]";
}
}
1.4 +2 -19
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java
Index: DefaultDeploymentModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultDeploymentModel.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DefaultDeploymentModel.java 5 Jul 2003 09:33:42 -0000 1.3
+++ DefaultDeploymentModel.java 6 Jul 2003 03:00:25 -0000 1.4
@@ -86,22 +86,6 @@
new DefaultConfiguration(
"configuration", DeploymentModel.class.getName() );
- private static final Type NULL_TYPE;
- static
- {
- try
- {
- NULL_TYPE = new TypeBuilder().build( NullComponent.class );
- }
- catch( Throwable e )
- {
- throw new RuntimeException(
- "Internal error while creating NullComponent type defintion: "
- + e.toString() );
- }
- }
-
-
//==============================================================
// immutable state
//==============================================================
@@ -163,7 +147,6 @@
if( profile.getClassname() == null )
{
m_class = NullComponent.class;
- //m_type = NULL_TYPE;
}
else
{
@@ -282,6 +265,6 @@
public String toString()
{
- return "[deployment: " + getPath() + getName() + "]";
+ return "[deployment model : " + getPath() + getName() + "]";
}
}
1.2 +8 -4
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultModel.java
Index: DefaultModel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultModel.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultModel.java 4 Jul 2003 07:27:38 -0000 1.1
+++ DefaultModel.java 6 Jul 2003 03:00:25 -0000 1.2
@@ -72,7 +72,7 @@
//==============================================================
private static final Resources REZ =
- ResourceManager.getPackageResources( DefaultModel.class );
+ ResourceManager.getPackageResources( DefaultModel.class );
//==============================================================
// state
@@ -103,8 +103,12 @@
m_name = name;
m_path = path;
- getLogger().debug( "instantiating: " + this );
-
+ if( getLogger().isDebugEnabled() )
+ {
+ final String message =
+ REZ.getString( "created", this.toString() );
+ getLogger().debug( message );
+ }
}
//==============================================================
1.2 +26 -18
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultServiceRepository.java
Index: DefaultServiceRepository.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultServiceRepository.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultServiceRepository.java 5 Jul 2003 07:58:20 -0000 1.1
+++ DefaultServiceRepository.java 6 Jul 2003 03:00:25 -0000 1.2
@@ -59,7 +59,7 @@
import org.apache.avalon.composition.model.ServiceUnknownException;
import org.apache.avalon.composition.model.ServiceRepository;
import org.apache.avalon.framework.Version;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
+import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.meta.info.ReferenceDescriptor;
import org.apache.avalon.meta.info.Service;
import org.apache.avalon.meta.info.builder.ServiceBuilder;
@@ -71,26 +71,26 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision$ $Date$
*/
-public class DefaultServiceRepository extends AbstractLogEnabled implements
ServiceRepository
+public class DefaultServiceRepository implements ServiceRepository
{
//==============================================================
- // state
+ // immutable state
//==============================================================
/**
- * The classloader supplied to the manager.
+ * The logging channel.
*/
- private ClassLoader m_classloader;
+ private final Logger m_logger;
/**
* The parent service manager (may be null)
*/
- private ServiceRepository m_parent;
+ private final ServiceRepository m_parent;
/**
* List of service entries.
*/
- private List m_services;
+ private final List m_services;
//==============================================================
// constructor
@@ -98,22 +98,25 @@
/**
* Creation of a new root service manager.
+ * @param logger the logging channel
* @param services the list of available services
- * @exception NullPointerException if the classloader is null
+ * @exception NullPointerException if the services list is null
*/
- public DefaultServiceRepository( ClassLoader classloader, List services )
throws NullPointerException
+ DefaultServiceRepository(
+ final Logger logger, final List services ) throws NullPointerException
{
- this( classloader, null, services );
+ this( logger, null, services );
}
/**
* Creation of a new service manager.
+ * @param logger the logging channel
* @param parent the parent type manager
* @param services the list of available services
- * @exception NullPointerException if the classloader is null
+ * @exception NullPointerException if the services list is null
*/
- public DefaultServiceRepository(
- ClassLoader classloader, ServiceRepository parent, List services )
+ DefaultServiceRepository(
+ final Logger logger, final ServiceRepository parent, final List services )
throws NullPointerException
{
if( services == null )
@@ -122,7 +125,7 @@
}
m_parent = parent;
m_services = services;
- m_classloader = classloader; // not used
+ m_logger = logger;
}
//==============================================================
@@ -140,7 +143,7 @@
* @return the service matching the supplied classname and version.
* @exception UnknownServiceException if a matching service cannot be found
*/
- public Service getService( String classname, Version version )
+ public Service getService( final String classname, final Version version )
throws ServiceUnknownException
{
return getService( new ReferenceDescriptor( classname, version ) );
@@ -157,7 +160,7 @@
* @return the service matching the supplied descriptor.
* @exception UnknownServiceException if a matching service cannot be found
*/
- public Service getService( ReferenceDescriptor reference ) throws
ServiceUnknownException
+ public Service getService( final ReferenceDescriptor reference ) throws
ServiceUnknownException
{
Service service = getLocalService( reference );
if( service == null )
@@ -175,7 +178,7 @@
return service;
}
- private Service getLocalService( ReferenceDescriptor reference )
+ private Service getLocalService( final ReferenceDescriptor reference )
{
Iterator iterator = m_services.iterator();
while( iterator.hasNext() )
@@ -187,5 +190,10 @@
}
}
return null;
+ }
+
+ protected Logger getLogger()
+ {
+ return m_logger;
}
}
1.2 +28 -1
avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultSystemContext.java
Index: DefaultSystemContext.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/composition/src/java/org/apache/avalon/composition/model/impl/DefaultSystemContext.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- DefaultSystemContext.java 4 Jul 2003 07:27:38 -0000 1.1
+++ DefaultSystemContext.java 6 Jul 2003 03:00:25 -0000 1.2
@@ -56,6 +56,8 @@
import org.apache.avalon.composition.model.SystemContext;
import org.apache.avalon.composition.repository.Repository;
import org.apache.avalon.framework.context.DefaultContext;
+import org.apache.avalon.excalibur.i18n.ResourceManager;
+import org.apache.avalon.excalibur.i18n.Resources;
/**
@@ -66,10 +68,25 @@
*/
public class DefaultSystemContext extends DefaultContext implements SystemContext
{
+ //==============================================================
+ // static
+ //==============================================================
+
+ private static final Resources REZ =
+ ResourceManager.getPackageResources( DefaultSystemContext.class );
+
+ //==============================================================
+ // immutable state
+ //==============================================================
+
private final File m_base;
private final Repository m_repository;
+ //==============================================================
+ // constructor
+ //==============================================================
+
/**
* Creation of a new system context.
*
@@ -102,9 +119,19 @@
{
throw new NullPointerException( "repository" );
}
+ if( !base.isDirectory() )
+ {
+ final String error =
+ REZ.getString( "system.context.base.not-a-directory.error", base );
+ throw new IllegalArgumentException( error );
+ }
m_base = base;
m_repository = repository;
}
+
+ //==============================================================
+ // SystemContext
+ //==============================================================
/**
* Return the base directory from which relative references
1.4 +76 -124
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.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- DefaultTypeRepository.java 5 Jul 2003 09:33:42 -0000 1.3
+++ DefaultTypeRepository.java 6 Jul 2003 03:00:25 -0000 1.4
@@ -62,8 +62,9 @@
import org.apache.avalon.composition.model.TypeDuplicateException;
import org.apache.avalon.composition.model.TypeUnknownException;
import org.apache.avalon.composition.util.ExceptionHelper;
-import org.apache.avalon.framework.logger.AbstractLogEnabled;
-import org.apache.avalon.framework.activity.Initializable;
+import org.apache.avalon.excalibur.i18n.ResourceManager;
+import org.apache.avalon.excalibur.i18n.Resources;
+import org.apache.avalon.framework.logger.Logger;
import org.apache.avalon.meta.info.DependencyDescriptor;
import org.apache.avalon.meta.info.ReferenceDescriptor;
import org.apache.avalon.meta.info.ServiceDescriptor;
@@ -79,10 +80,17 @@
* @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision$ $Date$
*/
-class DefaultTypeRepository extends AbstractLogEnabled implements TypeRepository,
Initializable
+class DefaultTypeRepository implements TypeRepository
{
+ //==============================================================
+ // static
+ //==============================================================
+
+ private static final Resources REZ =
+ ResourceManager.getPackageResources( DefaultClassLoaderModel.class );
private static final Type NULL_TYPE;
+
static
{
try
@@ -92,25 +100,28 @@
catch( Throwable e )
{
throw new RuntimeException(
- "Internal error while creating NullComponent type defintion: "
- + e.toString() );
+ REZ.getString( "type.repository.null-create.error", e.toString() ) );
}
}
+ //==============================================================
+ // immutable state
+ //==============================================================
+
+ private final Logger m_logger;
+
private final ClassLoader m_classloader;
/**
* The parent type manager (may be null)
*/
- private TypeRepository m_parent;
+ private final TypeRepository m_parent;
/**
* Table of component types keyed by implementation classname.
*/
private final Hashtable m_types = new Hashtable();
- private final List m_typesList;
-
//==============================================================
// constructor
//==============================================================
@@ -120,9 +131,9 @@
* @param types the list of types local to the repository
* @exception NullPointerException if the type list is null
*/
- public DefaultTypeRepository( ClassLoader classloader, List types )
+ public DefaultTypeRepository( Logger logger, ClassLoader classloader, List
types )
{
- this( classloader, null, types );
+ this( logger, classloader, null, types );
}
/**
@@ -131,23 +142,19 @@
* @param types the list of types local to the repository
* @exception NullPointerException if the type list is null
*/
- public DefaultTypeRepository( ClassLoader classloader, TypeRepository parent,
List types )
+ public DefaultTypeRepository(
+ final Logger logger, final ClassLoader classloader, final TypeRepository
parent,
+ final List types )
{
if( types == null )
{
throw new NullPointerException( "types" );
}
+
m_parent = parent;
m_classloader = classloader;
- m_typesList = types;
- }
+ m_logger = logger;
- //==============================================================
- // lifecycle
- //==============================================================
-
- public void initialize() throws Exception
- {
//
// If the parent is null then we are root so we add the
// NullComponent type as the default component type.
@@ -159,40 +166,28 @@
m_types.put( classname , NULL_TYPE );
if( getLogger().isDebugEnabled() )
{
- getLogger().debug( "bootstrap: " + classname );
+ final String message =
+ REZ.getString( "type.repository.bootstrap.error", classname );
+ getLogger().debug( message );
}
}
//
- // Validate types before adding them to the repository.
- // If a validation error occurs then abort the process
- // which will result in classloader establishment failure.
+ // build up a map of types in the repository keyed by classname
//
if( getLogger().isDebugEnabled() )
{
- getLogger().debug( "validating: " + m_typesList.size() );
+ final String message =
+ REZ.getString( "type.repository.count", new Integer( types.size() ) );
+ getLogger().debug( message );
}
- Iterator iterator = m_typesList.iterator();
+ Iterator iterator = types.iterator();
while( iterator.hasNext() )
{
Type type = (Type) iterator.next();
final String classname = type.getInfo().getClassname();
- try
- {
- verify( type );
- }
- catch( Throwable e )
- {
- if( getLogger().isWarnEnabled() )
- {
- final String error =
- "Ignoring type due to verification error: " + classname;
- getLogger().warn( ExceptionHelper.packException(
- error, e, getLogger().isDebugEnabled() ) );
- }
- }
//
// we should add a test to make sure that the type is
@@ -201,6 +196,8 @@
if( getLogger().isDebugEnabled() )
{
+ final String message =
+ REZ.getString( "type.repository.addition", classname );
getLogger().debug( "add: " + classname );
}
@@ -211,9 +208,45 @@
//==============================================================
// DefaultTypeRepository
//==============================================================
+
+ /**
+ * Return all availble types.
+ * @return the array of types
+ */
+ public Type[] getTypes()
+ {
+ return getTypes( true );
+ }
+
+ /**
+ * Return all the types available within the repository.
+ *
+ * @param policy if TRUE, return all available types, if FALSE
+ * return only the locally established types.
+ * @return the array of types
+ */
+ public Type[] getTypes( boolean policy )
+ {
+ if( policy && ( m_parent != null ))
+ {
+ ArrayList list = new ArrayList( m_types.values() );
+ Type[] types = m_parent.getTypes();
+ for( int i = 0; i < types.length; i++ )
+ {
+ list.add( types[i] );
+ }
+ return (Type[]) list.toArray( new Type[0] );
+ }
+ else
+ {
+ return (Type[]) m_types.values().toArray( new Type[0] );
+ }
+ }
+
/**
* Locate a [EMAIL PROTECTED] Type} instances associated with the
* supplied implementation classname.
+ *
* @param clazz the component type implementation class.
* @return the type matching the supplied implementation classname.
* @exception TypeUnknownException if a matching type cannot be found
@@ -230,6 +263,7 @@
/**
* Locate a [EMAIL PROTECTED] Type} instances associated with the
* supplied implementation classname.
+ *
* @param classname the component type implementation class name.
* @return the type matching the supplied implementation classname.
* @exception TypeUnknownException if a matching type cannot be found
@@ -334,91 +368,9 @@
return (Type[]) list.toArray( new Type[0] );
}
- /**
- * Verify the intergrity of the supplied type.
- * @param type the type to verify
- * @exception Exception if an verification failure occurs
- */
- private void verify( Type type ) throws Exception
- {
- String name = type.getInfo().getName();
- Class clazz = getComponentClass( type );
- Class[] classes = getServiceClasses( type );
- ComponentVerifier verifier = new ComponentVerifier();
- verifier.verifyComponent( name, clazz, classes );
- }
-
- /**
- * Return the set of interface classes for a given type that are declared
- * or default to the "native" service access protocol and where the
- * service access model is undefined (i.e. native implementation).
- * access mode.
- *
- * @param type the component type
- * @return an array of classes represnting the type's service interfaces
- */
- private Class[] getServiceClasses( Type type )
- {
- ArrayList list = new ArrayList();
- ServiceDescriptor[] services = type.getServices();
- for( int i = 0; i < services.length; i++ )
- {
- ServiceDescriptor service = services[i];
- if( (service.getAttribute(
- "urn:avalon:service.protocol", "native" ).equals( "native" ))
- && (service.getAttribute( "urn:avalon:service.accessor", null )
== null) )
- {
- list.add( getServiceClass( services[i] ) );
- }
- }
- return (Class[]) list.toArray( new Class[0] );
- }
-
- /**
- * 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
- */
- private Class getComponentClass( Type type ) throws TypeException
+ protected Logger getLogger()
{
- if( null == type )
- {
- throw new NullPointerException( "type" );
- }
-
- final String classname = type.getInfo().getClassname();
-
- try
- {
- return m_classloader.loadClass( classname );
- } catch( Throwable e )
- {
- final String error =
- "Could not load implementation class for component type: "
- + classname;
- throw new TypeException( error, e );
- }
+ return m_logger;
}
- /**
- * 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
- */
- private Class getServiceClass( ServiceDescriptor service ) throws
TypeRuntimeException
- {
- final String classname = service.getReference().getClassname();
- try
- {
- return m_classloader.loadClass( classname );
- } catch( Throwable e )
- {
- final String error =
- "Could not load implementation class for service type: "
- + classname;
- throw new TypeRuntimeException( error, e );
- }
- }
}
1.3 +47 -45
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.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Resources.properties 4 Jul 2003 15:24:55 -0000 1.2
+++ Resources.properties 6 Jul 2003 03:00:25 -0000 1.3
@@ -1,48 +1,50 @@
-initialization=engine initialization
-kernel.extension=including kernel extension dir: {0}
-system.extension=including system extension dir: {0}
-relative.extension=including relative extension dir: {0}
-error.include=Invalid include directory: {0}
-extension.warning=The extension directory path: '{0}' does not refer to a
directory.;
-bootstrap.classpath=bootstraping from classpath
-bootstrap.path=path: {0}
-error.classpath=path: Classpath deployment failure.
-processing.url=processing: {0}
-ready=ready
-add.url=add: {0}
-add.classpath=adding classpath
-add.classpath.info=classpath contains {0} fileset entries
-classpath.dir.error=Classpath base directory does not exist: {0}
-classpath.base.error=Error processing classpath base directory: {0}
-classpath.include=fileset contains {0} include entries
-classpath.include.error=Error processing a classpath include: {0}
-classpath.ok=classpath ok
-classpath.expand.error=Unexpected exception while attempting to expand the supplied
classpath
-add.ext.error=Internal error while attempting to add optional package: {0}
-add.extension.error=Internal error while attempting to add extension url: {0}
-register.path=register: {0}
-resolve.fail=No profiles matching the requested dependency: {0}
-resolve=No profiles matching the requested dependency: {0}
-resolve.stage.notice=resolve: {0}
-resolve.stage.fail=No profiles matching the requested stage: {0}
-
-target.nocreate=Error creating LogTarget named "{0}" for file {0}. (Reason: {2}).
-unknown-priority=Unknown priority "{0}" for Logger named "{1}".
-category-create=Creating a log category named "{0}" that writes to "{1}" target at
priority "{2}".
-
-missing.extension=Unable to locate an extension that is required by application.\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}
-unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader
for application.
-bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it
impossible to load a manifest.
-available-extensions=Available extensions: {0}
-required-extensions=The list of required extensions for application includes: {0}
-optional-packages-added=The list of "Optional Packages" added to the application
include: {0}
-classpath-entries=The list of classpath entrys for the application include: {0}
-
-#
#
+# DefaultCompositionModelFactory
+factory.composition.create.error=Unable to construct a new composition 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}.
+
+# DefaultCompositionModel
+composition.implementation.create.error=Unable to create implementation model: {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.unknown-profile-class.error=Unknown profile class: {1} in {0}.
+
+# DefaultDeploymentModel
+
+# 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}
+
+#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}
+scanner.stream.unrecognized-content.warning=Unrecognized content: {0}
+scanner.stream.content.error=Content related error while scanning url: {0}
+scanner.jar.error=Unexpected error while scanning jar file: {0}
+scanner.type.addition=type: {0}
+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.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}
-error.composition.classloader.create=Unable to create a classloader for the
containment context: {0}
-error.composition.implementation.create=Unable to create implementation model: {0}
-error.containment.composition.create=Unable to create composition model: {0}
-error.containment.deployment.create=Unable to create deployment model: {0}
1.2 +192 -27
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.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Scanner.java 5 Jul 2003 07:57:50 -0000 1.1
+++ Scanner.java 6 Jul 2003 03:00:25 -0000 1.2
@@ -70,24 +70,31 @@
import org.apache.avalon.composition.model.ModelException;
import org.apache.avalon.composition.util.ExceptionHelper;
+import org.apache.avalon.excalibur.i18n.ResourceManager;
+import org.apache.avalon.excalibur.i18n.Resources;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.avalon.meta.data.Profile;
import org.apache.avalon.meta.info.Service;
+import org.apache.avalon.meta.info.ServiceDescriptor;
import org.apache.avalon.meta.info.Type;
import org.apache.avalon.meta.info.builder.TypeBuilder;
import org.apache.avalon.meta.info.builder.ServiceBuilder;
+import org.apache.avalon.meta.verifier.ComponentVerifier;
/**
* A repository for services, types and profiles.
*
- * @author <a href="mailto:[EMAIL PROTECTED]">Gary Shea</a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Avalon Development Team</a>
* @version $Revision$ $Date$
*/
-public class Scanner extends AbstractLogEnabled
+class Scanner extends AbstractLogEnabled
{
- //===================================================================
+ //==============================================================
// static
- //===================================================================
+ //==============================================================
+
+ private static final Resources REZ =
+ ResourceManager.getPackageResources( Scanner.class );
private static final String X_INFO = ".xinfo";
@@ -165,7 +172,9 @@
{
if( getLogger().isDebugEnabled() )
{
- getLogger().debug( "scanning: " + url );
+ final String message =
+ REZ.getString( "scanner.scanning", url.toString() );
+ getLogger().debug( message );
}
if( isDirectory( url ) )
@@ -194,8 +203,7 @@
catch( Throwable e )
{
final String error =
- "Unexpected Ierror while attempting to scan directory: "
- + url;
+ REZ.getString( "scanner.dir-scan.error", url.toString() );
throw new ModelException( error, e );
}
}
@@ -213,8 +221,8 @@
if( !uri.toString().endsWith( "!/" ) )
{
final String error =
- "Embeded jar file loading not supported: " + url;
- throw new IllegalArgumentException( error );
+ REZ.getString( "scanner.nested-jar-unsupported.error",
url.toString() );
+ throw new ModelException( error );
}
final JarURLConnection jar = (JarURLConnection) uri.openConnection();
@@ -223,9 +231,9 @@
}
catch( Throwable e )
{
- final String error =
- "Unexpected error while scanning jar file: " + url;
- throw new ModelException( error );
+ final String error =
+ REZ.getString( "scanner.jar.error", url.toString() );
+ throw new ModelException( error, e );
}
}
@@ -262,8 +270,11 @@
{
if( getLogger().isWarnEnabled() )
{
- getLogger().warn(
- "Unrecognized content from url " + url );
+ final String warning =
+ REZ.getString(
+ "scanner.stream.unrecognized-content.warning",
+ url.toString() );
+ getLogger().warn( warning );
}
}
}
@@ -271,10 +282,13 @@
{
if( getLogger().isWarnEnabled() )
{
- final String error =
- "Content related error while scanning url: " + url;
- getLogger().warn( ExceptionHelper.packException(
- error, e, getLogger().isDebugEnabled() ) );
+ final String error =
+ REZ.getString(
+ "scanner.stream.content.error",
+ url.toString() );
+ final String warning = ExceptionHelper.packException(
+ error, e, getLogger().isDebugEnabled() );
+ getLogger().warn( warning );
}
}
}
@@ -324,7 +338,6 @@
File file = files[i];
if( file.isDirectory() )
{
- getLogger().debug( "scanning dir: " + file );
scanDirectoryContent( base, file, types, services );
}
else
@@ -351,15 +364,166 @@
private void addType( List list, String name ) throws Exception
{
String classname = parseResourceName( name );
- list.add( TYPE_BUILDER.build( classname, m_classloader ) );
+ Type type = TYPE_BUILDER.build( classname, m_classloader );
+ try
+ {
+ verifyType( type );
+ if( getLogger().isDebugEnabled() )
+ {
+ final String message =
+ REZ.getString( "scanner.type.addition", classname );
+ getLogger().debug( message );
+ }
+ list.add( type );
+ }
+ catch( Throwable e )
+ {
+ if( getLogger().isWarnEnabled() )
+ {
+ final String error =
+ REZ.getString( "scanner.type.verification.failure", classname );
+ getLogger().warn( ExceptionHelper.packException(
+ error, e, getLogger().isDebugEnabled() ) );
+ }
+ }
}
private void addService( List list, String name ) throws Exception
{
String classname = parseResourceName( name );
- list.add( SERVICE_BUILDER.build( classname, m_classloader ) );
+ Service service = SERVICE_BUILDER.build( classname, m_classloader );
+ try
+ {
+ verifyService( service );
+ if( getLogger().isDebugEnabled() )
+ {
+ final String message =
+ REZ.getString( "scanner.service.addition", classname );
+ getLogger().debug( message );
+ }
+ list.add( service );
+ }
+ catch( Throwable e )
+ {
+ if( getLogger().isWarnEnabled() )
+ {
+ final String error =
+ REZ.getString( "scanner.service.verification.failure", classname
);
+ getLogger().warn( ExceptionHelper.packException(
+ error, e, getLogger().isDebugEnabled() ) );
+ }
+ }
+ }
+
+ /**
+ * Verify the intergrity of the supplied type.
+ * @param type the type to verify
+ * @exception Exception if an verification failure occurs
+ */
+ private void verifyType( Type type ) throws Exception
+ {
+ String name = type.getInfo().getName();
+ Class clazz = getComponentClass( type );
+ Class[] classes = getServiceClasses( type );
+ ComponentVerifier verifier = new ComponentVerifier();
+ verifier.verifyComponent( name, clazz, classes );
+ }
+
+ /**
+ * Verify the intergrity of the supplied type.
+ * @param type the type to verify
+ * @exception Exception if an verification failure occurs
+ */
+ private void verifyService( Service service ) throws Exception
+ {
+ String classname = service.getClassname();
+ try
+ {
+ m_classloader.loadClass( classname );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ REZ.getString( "scanner.service.missing-class.error", classname );
+ throw new ModelException( error, e );
+ }
+ }
+
+ /**
+ * Return the set of interface classes for a given type that are declared
+ * or default to the "native" service access protocol and where the
+ * service access model is undefined (i.e. native implementation).
+ * access mode.
+ *
+ * @param type the component type
+ * @return an array of classes represnting the type's service interfaces
+ */
+ private Class[] getServiceClasses( Type type ) throws ModelException
+ {
+ ArrayList list = new ArrayList();
+ ServiceDescriptor[] services = type.getServices();
+ for( int i = 0; i < services.length; i++ )
+ {
+ ServiceDescriptor service = services[i];
+ if( (service.getAttribute(
+ "urn:avalon:service.protocol", "native" ).equals( "native" ))
+ && (service.getAttribute( "urn:avalon:service.accessor", null ) ==
null) )
+ {
+ list.add( getServiceClass( services[i] ) );
+ }
+ }
+ return (Class[]) list.toArray( new Class[0] );
+ }
+
+ /**
+ * 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
+ */
+ private Class getComponentClass( Type type ) throws ModelException
+ {
+ if( null == type )
+ {
+ throw new NullPointerException( "type" );
+ }
+
+ final String classname = type.getInfo().getClassname();
+
+ try
+ {
+ return m_classloader.loadClass( classname );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ REZ.getString( "scanner.type.missing-class.error", classname );
+ throw new ModelException( error, e );
+ }
+ }
+
+ /**
+ * 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
+ */
+ private Class getServiceClass( ServiceDescriptor service ) throws ModelException
+ {
+ final String classname = service.getReference().getClassname();
+ try
+ {
+ return m_classloader.loadClass( classname );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ REZ.getString( "scanner.service.missing-class.error", classname );
+ throw new ModelException( error, e );
+ }
}
+
private boolean isDirectory( URL url )
{
if( url.getProtocol().equals( "file" ) )
@@ -376,8 +540,9 @@
{
return file;
}
- throw new IllegalArgumentException(
- "URL does not refer to a directory: " + url );
+ final String error =
+ REZ.getString( "scanner.url-not-a-directory.error", url.toString() );
+ throw new IllegalArgumentException( error );
}
private File getFile( URL url ) throws IllegalArgumentException
@@ -386,8 +551,9 @@
{
return new File( url.toString().substring( 5 ) );
}
- throw new IllegalArgumentException(
- "URL protocol does not match the required file: protocol: " + url );
+ final String error =
+ REZ.getString( "scanner.not-file-protocol.error", url.toString() );
+ throw new IllegalArgumentException( error );
}
private String parseResourceName( String resource )
@@ -415,5 +581,4 @@
return new URL( "jar:" + url.toString() + "!/" );
}
}
-
}
1.2 +5 -1 avalon-sandbox/merlin/composition/src/test/conf/block.xml
Index: block.xml
===================================================================
RCS file: /home/cvs/avalon-sandbox/merlin/composition/src/test/conf/block.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- block.xml 4 Jul 2003 07:27:42 -0000 1.1
+++ block.xml 6 Jul 2003 03:00:26 -0000 1.2
@@ -42,7 +42,11 @@
</repository>
</classpath>
</classloader>
- <component name="test"
class="org.apache.avalon.composition.model.teste.TestE"/>
+ <block name="block">
+ <implementation>
+ <component name="test"
class="org.apache.avalon.composition.model.teste.TestE"/>
+ </implementation>
+ </block>
</container>
</implementation>
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]