mcconnell 2002/12/15 17:09:47 Modified: merlin/src/java/org/apache/avalon/merlin/block BlockLoader.java merlin/src/java/org/apache/avalon/merlin/container ContainerLoader.java merlin/src/java/org/apache/avalon/merlin/container/builder XMLContainerCreator.java merlin/src/java/org/apache/avalon/merlin/kernel DefaultKernel.java Log: Building in the container heirachy as a composite element of a block. Revision Changes Path 1.4 +17 -108 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/BlockLoader.java Index: BlockLoader.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/BlockLoader.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- BlockLoader.java 15 Dec 2002 14:13:02 -0000 1.3 +++ BlockLoader.java 16 Dec 2002 01:09:47 -0000 1.4 @@ -92,8 +92,10 @@ import org.apache.avalon.framework.service.DefaultServiceManager; import org.apache.avalon.merlin.block.Block; import org.apache.avalon.merlin.block.DefaultBlock; -import org.apache.avalon.merlin.container.DefaultContainer; import org.apache.avalon.merlin.container.ContainerDescriptor; +import org.apache.avalon.merlin.container.ContainerLoader; +import org.apache.avalon.merlin.container.ContainerException; +import org.apache.avalon.merlin.container.DefaultContainer; import org.apache.avalon.merlin.container.builder.XMLContainerCreator; import org.apache.avalon.meta.info.Type; import org.apache.avalon.meta.model.LoggingDirective; @@ -118,7 +120,7 @@ * @version $Revision$ $Date$ */ -public class BlockLoader extends AbstractLogEnabled +public class BlockLoader extends ContainerLoader { //============================================================== // static @@ -126,8 +128,6 @@ protected static final String BLOCK_XML_ENTRY = "BLOCK-INF/block.xml"; - protected static final XMLContainerCreator CREATOR = new XMLContainerCreator(); - //============================================================== // BlockLoader //============================================================== @@ -136,7 +136,7 @@ * Install a set of blocks using the supplied classloader as the * parent classloader and returns a set of corresponding appliance * instances. The appliance instances returned from this method - * correspond to appliance object reflecting the service and dependecies + * correspond to appliance object reflecting the service and dependencies * declared by the block definition (as distinct from the appiance used * to establish the block instance. * @@ -146,7 +146,7 @@ * @return the set of block appliance instances * @exception Exception if an installation failure occurs */ - protected Block[] install( EngineClassLoader parent, File home, URL[] urls, Context system ) throws Exception + protected Block[] loadBlocks( EngineClassLoader parent, File home, URL[] urls, Context system ) throws Exception { int n = urls.length; if( n > 0 ) @@ -167,7 +167,7 @@ URL url = urls[i]; try { - Block block = installBlock( parent, home, url, system ); + Block block = loadBlock( parent, home, url, system ); blocks.add( block ); } catch( Throwable e ) @@ -201,7 +201,7 @@ return (Block[]) blocks.toArray( new Block[0] ); } - private Block installBlock( + private Block loadBlock( EngineClassLoader parent, File home, URL url, Context system ) throws Exception { @@ -230,8 +230,6 @@ logger.debug( "[" + name + "]"); Configuration config = getBlockConfiguration( jar ); - Configuration engineConfig = config.getChild( "engine" ); - Configuration containerConfig = config.getChild( "container" ); // // create a classloader that will be supplied to the @@ -239,72 +237,34 @@ // and extension path additions) // + Configuration engineConfig = config.getChild( "engine" ); EngineClassLoader engine = createChildEngine( parent, home, engineConfig, url, logger ); // - // create and return the block + // create and root container // + /* + Configuration containerConfig = config.getChild( "container" ); String classname = containerConfig.getAttribute( "class", DefaultContainer.class.getName() ); Type type = engine.getRepository().getTypeManager().getType( classname ); - ContainerDescriptor descriptor = CREATOR.createContainerDescriptor( type, containerConfig ); + ContainerDescriptor descriptor = CREATOR.createContainerDescriptor( type, containerConfig, name ); Configuration[] components = containerConfig.getChildren( "component" ); for( int i=0; i<components.length; i++ ) { Profile profile = createProfile( name, engine, components[i] ); descriptor.addComponent( profile ); } + */ + Appliance container = createContainer( engine, name, home, config, logger, true ); BlockContext context = new BlockContext( url, manifest ); - context.setProfile( descriptor ); + context.setProfile( (ContainerDescriptor) container.getProfile() ); Logger child = getLogger().getChildLogger( name ); return new DefaultBlock( engine, context, system, child ); } - private Profile createProfile( String name, EngineClassLoader engine, Configuration config ) - throws BlockException - { - String classname; - try - { - classname = config.getAttribute( "class" ); - } - catch( Throwable e ) - { - final String error = - "Root container in block: " + name + " contains an unamed profile."; - throw new BlockException( error, e ); - } - - Type type; - try - { - type = engine.getRepository().getTypeManager().getType( classname ); - } - catch( Throwable e ) - { - final String error = - "Root container in block: " + name - + " contains an profile that references an unknown type: " - + classname; - throw new BlockException( error, e ); - } - - try - { - return CREATOR.createContainerDescriptor( type, config ); - } - catch( Throwable e ) - { - final String error = - "Root container in block: " + name - + " contains a problamatic profile: " - + classname; - throw new BlockException( error, e ); - } - } - protected boolean isBlock( Manifest manifest ) { if( manifest == null ) @@ -371,57 +331,6 @@ { final String error = "Unable to create configuration from jar file: " + jar.getName(); throw new BlockException( error, e ); - } - } - - protected EngineClassLoader createChildEngine( - EngineClassLoader parent, File home, Configuration config, URL url, Logger logger ) - throws BlockException, ConfigurationException - { - LibraryDescriptor extensions; - try - { - extensions = - CREATOR.createLibraryDescriptor( - config.getChild( "library" ) ); - } - catch( Throwable e ) - { - final String error = "Bad library descriptor."; - throw new BlockException( error, e ); - } - - ClasspathDescriptor classpath; - try - { - classpath = - CREATOR.createClasspathDescriptor( - config.getChild( "classpath" ) ); - } - catch( Throwable e ) - { - final String error = "Bad classpath descriptor."; - throw new BlockException( error, e ); - } - - try - { - EngineClassLoader engine = new EngineClassLoader( new URL[]{ url }, parent ); - engine.enableLogging( logger.getChildLogger( "engine" ) ); - engine.configure( config ); - DefaultContext context = new DefaultContext(); - context.put( "urn:avalon:home", home ); - context.put( "urn:assembly:engine.extensions", extensions ); - context.put( "urn:assembly:engine.classpath", classpath ); - context.makeReadOnly(); - engine.contextualize( context ); - engine.initialize(); - return engine; - } - catch( Throwable e ) - { - final String error = "Engine bootstrap failure."; - throw new BlockException( error, e ); } } } 1.2 +196 -2 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/ContainerLoader.java Index: ContainerLoader.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/ContainerLoader.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- ContainerLoader.java 15 Dec 2002 14:13:02 -0000 1.1 +++ ContainerLoader.java 16 Dec 2002 01:09:47 -0000 1.2 @@ -79,10 +79,15 @@ import org.apache.avalon.framework.context.ContextException; import org.apache.avalon.framework.logger.AbstractLogEnabled; import org.apache.avalon.framework.service.DefaultServiceManager; +import org.apache.avalon.meta.info.Type; import org.apache.avalon.meta.model.LoggingDirective; +import org.apache.avalon.meta.model.Profile; import org.apache.avalon.merlin.block.Block; import org.apache.avalon.merlin.block.DefaultBlock; import org.apache.avalon.merlin.container.builder.XMLContainerCreator; +import org.apache.avalon.assembly.appliance.Appliance; +import org.apache.avalon.assembly.appliance.ApplianceContext; +import org.apache.avalon.assembly.appliance.ApplianceManager; import org.apache.avalon.assembly.logging.LoggingManager; import org.apache.avalon.assembly.logging.LoggingDescriptor; import org.apache.avalon.assembly.logging.DefaultLoggingManager; @@ -106,7 +111,196 @@ protected static final XMLContainerCreator CREATOR = new XMLContainerCreator(); //============================================================== - // BlockLoader + // ContainerLoader //============================================================== + + /** + * Creation of a new appliance holding a container. + * @param engine the component classloader to assign to the container + * @param name the container name + * @param home the root directory against which the classpath and extensions + * will be resolved + * @param config the container configuration + * @param logger the logging channel to assign to the container + */ + protected Appliance createContainer( + EngineClassLoader engine, String name, File home, Configuration config, Logger logger ) + throws Exception + { + return createContainer( engine, name, home, config, logger, false ); + } + + /** + * Creation of a new appliance holding a container. + * @param engine the component classloader to assign to the container + * @param name the container name + * @param home the root directory against which the classpath and extensions + * will be resolved + * @param config the container configuration + * @param logger the logging channel to assign to the container + */ + protected Appliance createContainer( + EngineClassLoader engine, String name, File home, Configuration config, Logger logger, boolean flag ) + throws Exception + { + + String classname = config.getAttribute( "class", DefaultContainer.class.getName() ); + Type type = engine.getRepository().getTypeManager().getType( classname ); + ContainerDescriptor descriptor = CREATOR.createContainerDescriptor( type, config, name ); + + Configuration[] components = config.getChildren( "component" ); + for( int i=0; i<components.length; i++ ) + { + Profile profile = createProfile( name, engine, components[i] ); + descriptor.addComponent( profile ); + Appliance appliance = engine.createAppliance( + new ApplianceContext( profile ), true ); + } + + Configuration[] containers = config.getChildren( "container" ); + for( int i=0; i<containers.length; i++ ) + { + Configuration childConfig = containers[i]; + + // + // create a classloader that will be supplied to the + // container (including resolution of the container level classpath + // and extension path additions) + // + + Configuration engineConfig = childConfig.getChild( "engine" ); + String childName; + Logger childLogger; + EngineClassLoader childEngine; + if( flag ) + { + childName = name; + childLogger = logger; + childEngine = engine; + } + else + { + childName = childConfig.getAttribute( "name", "untitled" ); + childLogger = logger.getChildLogger( childName ); + childEngine = childEngine = createChildEngine( engine, home, childConfig, childLogger ); + } + + Appliance container = createContainer( childEngine, childName, home, childConfig, childLogger ); + ContainerDescriptor containerDescriptor = (ContainerDescriptor) container.getProfile(); + descriptor.addContainer( containerDescriptor ); + Appliance appliance = engine.createAppliance( + new ApplianceContext( containerDescriptor ), true ); + } + return engine.createAppliance( new ApplianceContext( descriptor ), false ); + } + + protected Profile createProfile( String name, EngineClassLoader engine, Configuration config ) + throws ContainerException + { + String classname; + try + { + classname = config.getAttribute( "class" ); + } + catch( Throwable e ) + { + final String error = + "Root container in block: " + name + " contains an unamed profile."; + throw new ContainerException( error, e ); + } + + Type type; + try + { + type = engine.getRepository().getTypeManager().getType( classname ); + } + catch( Throwable e ) + { + final String error = + "Root container in block: " + name + + " contains an profile that references an unknown type: " + + classname; + throw new ContainerException( error, e ); + } + + try + { + return CREATOR.createContainerDescriptor( type, config ); + } + catch( Throwable e ) + { + final String error = + "Root container in block: " + name + + " contains a problamatic profile: " + + classname; + throw new ContainerException( error, e ); + } + } + + protected EngineClassLoader createChildEngine( + EngineClassLoader parent, File home, Configuration config, Logger logger ) + throws ContainerException, ConfigurationException + { + return createChildEngine( parent, home, config, null, logger ); + } + + protected EngineClassLoader createChildEngine( + EngineClassLoader parent, File home, Configuration config, URL url, Logger logger ) + throws ContainerException, ConfigurationException + { + LibraryDescriptor extensions; + try + { + extensions = + CREATOR.createLibraryDescriptor( + config.getChild( "library" ) ); + } + catch( Throwable e ) + { + final String error = "Bad library descriptor."; + throw new ContainerException( error, e ); + } + + ClasspathDescriptor classpath; + try + { + classpath = + CREATOR.createClasspathDescriptor( + config.getChild( "classpath" ) ); + } + catch( Throwable e ) + { + final String error = "Bad classpath descriptor."; + throw new ContainerException( error, e ); + } + + try + { + EngineClassLoader engine; + if( url != null ) + { + engine = new EngineClassLoader( new URL[]{ url }, parent ); + } + else + { + engine = new EngineClassLoader( parent ); + } + engine.enableLogging( logger.getChildLogger( "engine" ) ); + engine.configure( config ); + DefaultContext context = new DefaultContext(); + context.put( "urn:avalon:home", home ); + context.put( "urn:assembly:engine.extensions", extensions ); + context.put( "urn:assembly:engine.classpath", classpath ); + context.makeReadOnly(); + engine.contextualize( context ); + engine.initialize(); + return engine; + } + catch( Throwable e ) + { + final String error = "Engine bootstrap failure."; + throw new ContainerException( error, e ); + } + } } 1.6 +48 -32 avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/builder/XMLContainerCreator.java Index: XMLContainerCreator.java =================================================================== RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/builder/XMLContainerCreator.java,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- XMLContainerCreator.java 15 Dec 2002 14:13:02 -0000 1.5 +++ XMLContainerCreator.java 16 Dec 2002 01:09:47 -0000 1.6 @@ -163,7 +163,52 @@ Type type, Configuration config ) throws Exception { - return buildContainerDescriptor( type, config, Mode.EXPLICIT ); + return createContainerDescriptor( type, config, "container" ); + } + + + /** + * Create an explicit [EMAIL PROTECTED] ContainerDescriptor} instance from a + * configuration. + * @param type the component type + * @param config the profile description + * @return the profile + * @exception Exception if an error occurs during profile creation + */ + public ContainerDescriptor createContainerDescriptor( + Type type, Configuration config, String name ) + throws Exception + { + return buildContainerDescriptor( type, config, Mode.EXPLICIT, name ); + } + + private ContainerDescriptor buildContainerDescriptor( + Type type, Configuration profile, Mode mode, String defaultName ) + throws Exception + { + // + // create the logging categories for this profile + // + + final String name = profile.getAttribute( "name", defaultName ); + LoggingDirective categories = + createLoggingDirective( name, profile.getChild( "categories" ) ); + + final Parameters params = + Parameters.fromConfiguration( profile.getChild( "parameters" ) ); + final ContextDirective context = + createContextDirective( profile.getChild( "context" ) ); + final Configuration config = + profile.getChild( "configuration" ); + + // + // create the profile instance + // + + return (ContainerDescriptor) getConstructor().newInstance( + new Object[]{ + name, params, config, context, categories, type, mode } ); + } /** @@ -192,7 +237,7 @@ { vector.add( buildContainerDescriptor( - type, profiles[ i ], Mode.PACKAGED ) ); + type, profiles[ i ], Mode.PACKAGED, "package-" + i ) ); } return (ContainerDescriptor[])vector.toArray( @@ -215,35 +260,6 @@ return (ContainerDescriptor) getConstructor().newInstance( new Object[]{ null, null, defaults, context, categories, type, Mode.IMPLICIT } ); - } - - private ContainerDescriptor buildContainerDescriptor( - Type type, Configuration profile, Mode mode ) - throws Exception - { - // - // create the logging categories for this profile - // - - final String name = profile.getAttribute( "name", "container" ); - LoggingDirective categories = - createLoggingDirective( name, profile.getChild( "categories" ) ); - - final Parameters params = - Parameters.fromConfiguration( profile.getChild( "parameters" ) ); - final ContextDirective context = - createContextDirective( profile.getChild( "context" ) ); - final Configuration config = - profile.getChild( "configuration" ); - - // - // create the profile instance - // - - return (ContainerDescriptor) getConstructor().newInstance( - new Object[]{ - name, params, config, context, categories, type, mode } ); - } /** 1.10 +2 -2 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.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- DefaultKernel.java 15 Dec 2002 14:13:03 -0000 1.9 +++ DefaultKernel.java 16 Dec 2002 01:09:47 -0000 1.10 @@ -300,7 +300,7 @@ } Context system = getSystemContext(); - Appliance[] blocks = install( m_engine, m_home, urls, system ); + Block[] blocks = loadBlocks( m_engine, m_home, urls, system ); } catch( Throwable e ) {
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>