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]>