mcconnell 2002/12/27 17:34:04
Modified: merlin/src/java/org/apache/avalon/merlin/kernel
DefaultKernel.java
Log:
added support for custom configuration integration into the block/container creation
process
Revision Changes Path
1.17 +150 -38
avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/DefaultKernel.java
Index: DefaultKernel.java
===================================================================
RCS file:
/home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/DefaultKernel.java,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- DefaultKernel.java 27 Dec 2002 16:44:02 -0000 1.16
+++ DefaultKernel.java 28 Dec 2002 01:34:04 -0000 1.17
@@ -109,6 +109,7 @@
import org.apache.avalon.meta.model.LoggingDirective;
import org.apache.avalon.meta.model.Profile;
import org.apache.avalon.meta.info.Type;
+import org.apache.excalibur.configuration.ConfigurationUtil;
/**
* Default kernel implementation. The implementation provides support for
@@ -146,6 +147,25 @@
protected static final String BLOCK_XML_ENTRY = "BLOCK-INF/block.xml";
+ /**
+ * Return a configuration element relative to a target name. The implementation
+ * will locate a configuration child in the supplied configuration with an
element name
+ * of "configuration" with a attribute named "target" with a value corresponding
to
+ * the supplied name.
+ * @param config the configuration holding a set of child "configuration"
elements
+ * @param name the name to match against child "target" attribute names
+ * @return the matching configuration or new empty configuration if no match
found
+ */
+ public static Configuration getNamedConfiguration( Configuration config, String
name )
+ {
+ int i = config.getChildren("configuration").length;
+ if( i < 1 )
+ {
+ return new DefaultConfiguration( "default",
DefaultKernel.class.getName() );
+ }
+ return ConfigurationUtil.matchFirstOccurance( config, "configuration",
"target", name );
+ }
+
//==============================================================
// state
//==============================================================
@@ -498,6 +518,20 @@
}
//==============================================================
+ // ConfigurationRepository
+ //==============================================================
+
+ /**
+ * Returns a configuration relative to a target path.
+ * @param path the appliance path
+ * @return the configuration for the appliance
+ */
+ public Configuration getConfiguration( String path )
+ {
+ return null;
+ }
+
+ //==============================================================
// internals
//==============================================================
@@ -554,6 +588,7 @@
private Block loadPhysicalBlock( Configuration config, Context system )
throws Exception
{
+ getLogger().info( "block configuration: \n" + ConfigurationUtil.list(
config ) );
//
// get the basic information for the block declaration
@@ -605,24 +640,13 @@
Configuration containment = base.getChild( "implementation" );
ContainerDescriptor descriptor = createContainerDescriptor( name, engine,
containment );
Registry registry = m_registry.createChild( name );
- List list = createChildContainers( engine, registry, partition,
containment, logger );
+ List list = createChildContainers( engine, registry, partition,
containment, config, logger );
//
// create the appliance context for the container
//
- Map map = new Hashtable();
- map.put("urn:assembly:engine.classloader", engine );
- map.put("urn:merlin:container.containers", list );
- map.put("urn:merlin:container.descriptor", descriptor );
- map.put("urn:merlin:container.registry", registry );
-
- DefaultApplianceContext context = new DefaultApplianceContext( descriptor );
- context.setName( name );
- context.setDeploymentContext( map );
- context.setApplianceClassname( DefaultBlock.class.getName() );
-
- return (Block) engine.createAppliance( context, false );
+ return createBlock( engine, list, descriptor, name, registry,
Container.PATH_SEPERATOR, config );
}
@@ -664,8 +688,8 @@
*/
private List createChildContainers(
EngineClassLoader engine, Registry registry, String partition,
- Configuration config, Logger logger )
- throws Exception
+ Configuration config, Configuration custom, Logger logger )
+ throws BlockException
{
List list = new ArrayList();
Configuration[] children = config.getChildren( "container" );
@@ -673,22 +697,70 @@
for( int i=0; i<children.length; i++ )
{
Configuration child = children[i];
- String name = child.getAttribute( "name" );
+
+ //
+ // get the block name
+ //
+
+ String name;
+ try
+ {
+ name = child.getAttribute( "name" );
+ }
+ catch( ConfigurationException ce )
+ {
+ final String error =
+ "Cannot create a subsidiary container due to missing container
name in configuration:\n"
+ + ConfigurationUtil.list( child );
+ throw new BlockException( error );
+ }
Logger log = logger.getChildLogger( name );
- EngineClassLoader loader = createChildEngine(
- engine, m_home, child.getChild("engine"), log );
- Registry reg = registry.createChild( name );
-
- Appliance appliance = createContainerAppliance(
- loader, reg, partition, name, child, log );
- list.add( appliance );
+
+ //
+ // create the block classloader
+ //
+
+ EngineClassLoader loader;
+ try
+ {
+ loader = createChildEngine(
+ engine, m_home, child.getChild("engine"), log );
+ }
+ catch( ConfigurationException ce )
+ {
+ final String error =
+ "Cannot create a subsidiary container due to a confiuration
error.";
+ throw new BlockException( error, ce );
+ }
+ catch( ContainerException ce )
+ {
+ final String error =
+ "Cannot create a subsidiary container due to a loader creation
error.";
+ throw new BlockException( error, ce );
+ }
+
+ Registry reg;
+ try
+ {
+ reg = registry.createChild( name );
+ }
+ catch( MalformedURLException e )
+ {
+ final String error =
+ "Cannot create a subsidiary container due to a url format error.";
+ throw new BlockException( error, e );
+ }
+
+ Block block = createContainmentBlock(
+ loader, reg, partition, name, child, custom, log );
+ list.add( block );
}
return list;
}
/**
- * Create a single containment appliance.
+ * Create a single containment block.
*
* @param engine the containers classloader
* @param registry the compoent registry to apply to the container
@@ -696,33 +768,74 @@
* @param name the appliance name
* @param config the configuration of the container
* @param logger the logging channel to apply to classloaders created for child
containers
- * @return the containment appliance
- * @exception if an error occurs during creation of the containment appliance
+ * @return the containment block
+ * @exception BlockException if an error occurs during creation of the block
*/
- private Appliance createContainerAppliance(
+ private Block createContainmentBlock(
EngineClassLoader engine, Registry registry, String partition, String name,
- Configuration config, Logger logger )
- throws Exception
+ Configuration config, Configuration custom, Logger logger )
+ throws BlockException
{
String subPartition = partition + name + Container.PATH_SEPERATOR;
- List list = createChildContainers( engine, registry, subPartition, config,
logger );
- ContainerDescriptor descriptor = createContainerDescriptor( name, engine,
config );
+ List list = createChildContainers( engine, registry, subPartition, config,
custom, logger );
+
+ ContainerDescriptor descriptor;
+ try
+ {
+ descriptor = createContainerDescriptor( name, engine, config );
+ }
+ catch( Throwable e )
+ {
+ final String error =
+ "Cannot create a block due to an error during meta info creation.";
+ throw new BlockException( error, e );
+ }
+
+ return createBlock( engine, list, descriptor, name, registry, partition,
custom );
+ }
+
+ /**
+ * Create a block.
+ *
+ * @param engine the containers classloader
+ * @param list the list of subsidiary container blocks
+ * @param descriptor the container descriptor
+ * @param name the block name
+ * @param registry the compoent registry to apply to the container
+ * @param partition the partition to assign to the container
+ * @param custom the custom configuration
+ * @return the block
+ * @exception BlockException if an error occurs during creation of the block
+ */
+ private Block createBlock(
+ EngineClassLoader engine, List containers, ContainerDescriptor descriptor,
+ String name, Registry registry, String partition, Configuration custom )
+ throws BlockException
+ {
+ if( getLogger().isDebugEnabled() )
+ {
+ getLogger().debug( "creating block: " + partition + name );
+ }
+
+ Configuration target = getNamedConfiguration( custom, name );
//
// create the appliance context for the container
//
Map map = new Hashtable();
+ map.put("urn:avalon:partition.name", partition );
map.put("urn:assembly:engine.classloader", engine );
- map.put("urn:merlin:container.containers", list );
+ map.put("urn:merlin:container.containers", containers );
map.put("urn:merlin:container.descriptor", descriptor );
map.put("urn:merlin:container.registry", registry );
- map.put("urn:avalon:partition.name", partition );
+ map.put("urn:merlin:container.configuration", target );
DefaultApplianceContext context = new DefaultApplianceContext( descriptor );
context.setName( name );
context.setDeploymentContext( map );
context.setPartitionName( partition );
+ context.setApplianceClassname( DefaultBlock.class.getName() );
//
// create the containement appliance
@@ -731,15 +844,14 @@
try
{
context.makeReadOnly();
- return engine.createAppliance( context, false );
+ return (Block) engine.createAppliance( context, false );
}
catch( Throwable e )
{
final String error =
- "Unable to create containment appliance: " + name;
- throw new ContainerException( error, e );
+ "Unable to create block: " + partition + name;
+ throw new BlockException( error, e );
}
-
}
private LoggingManager bootstrapLoggingManager( String root ) throws Exception
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>