mcconnell    2002/12/15 06:13:03

  Modified:    merlin/src/java/org/apache/avalon/merlin/block Block.java
                        BlockLoader.java DefaultBlock.java
               merlin/src/java/org/apache/avalon/merlin/container/builder
                        XMLContainerCreator.java
               merlin/src/java/org/apache/avalon/merlin/kernel
                        DefaultKernel.java
               merlin/src/test/config block.xml
  Added:       merlin/src/java/org/apache/avalon/merlin/block
                        BlockContext.java
               merlin/src/java/org/apache/avalon/merlin/container
                        ContainerLoader.java
  Log:
  General progress of the Block/Container/Appliance management abstractions.
  
  Revision  Changes    Path
  1.3       +4 -2      
avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java
  
  Index: Block.java
  ===================================================================
  RCS file: 
/home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/Block.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Block.java        9 Dec 2002 12:16:25 -0000       1.2
  +++ Block.java        15 Dec 2002 14:13:02 -0000      1.3
  @@ -50,13 +50,15 @@
   
   package org.apache.avalon.merlin.block;
   
  +import org.apache.avalon.assembly.appliance.Appliance;
  +
   /**
    * A block is a deployment model supporting composite components.
    *
    * @author <a href="mailto:avalon-dev@jakarta.apache.org";>Avalon Development 
Team</a>
    * @version $Revision$ $Date$
    */
  -public interface Block 
  +public interface Block extends Appliance
   {
       static final String AVALON_BLOCK_KEY = "Avalon-Block";
   }
  
  
  
  1.3       +138 -37   
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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BlockLoader.java  11 Dec 2002 08:12:24 -0000      1.2
  +++ BlockLoader.java  15 Dec 2002 14:13:02 -0000      1.3
  @@ -55,6 +55,9 @@
   import java.io.FileInputStream;
   import java.io.InputStream;
   import java.net.URL;
  +import java.net.MalformedURLException;
  +import java.util.Map;
  +import java.util.Hashtable;
   import java.util.ArrayList;
   import java.util.Enumeration;
   import java.util.jar.JarFile;
  @@ -63,6 +66,14 @@
   import java.util.zip.ZipEntry;
   import java.net.JarURLConnection;
   
  +import org.apache.avalon.assembly.logging.LoggingManager;
  +import org.apache.avalon.assembly.logging.LoggingDescriptor;
  +import org.apache.avalon.assembly.logging.DefaultLoggingManager;
  +import org.apache.avalon.assembly.engine.EngineClassLoader;
  +import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
  +import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
  +import org.apache.avalon.assembly.appliance.Appliance;
  +import org.apache.avalon.assembly.util.ExceptionHelper;
   import org.apache.avalon.framework.CascadingException;
   import org.apache.avalon.framework.logger.Logger;
   import org.apache.avalon.framework.activity.Initializable;
  @@ -79,17 +90,14 @@
   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.model.LoggingDirective;
   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.builder.XMLContainerCreator;
  -import org.apache.avalon.assembly.logging.LoggingManager;
  -import org.apache.avalon.assembly.logging.LoggingDescriptor;
  -import org.apache.avalon.assembly.logging.DefaultLoggingManager;
  -import org.apache.avalon.assembly.engine.EngineClassLoader;
  -import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
  -import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
  -import org.apache.avalon.assembly.util.ExceptionHelper;
  +import org.apache.avalon.meta.info.Type;
  +import org.apache.avalon.meta.model.LoggingDirective;
  +import org.apache.avalon.meta.model.Profile;
   
   /**
    * Default kernel implementation.  The implementation provides support for
  @@ -124,15 +132,42 @@
       // BlockLoader
       //==============================================================
   
  -    protected Block[] install( EngineClassLoader parent, File home, URL[] 
urls ) throws Exception
  +   /**
  +    * 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 
  +    * declared by the block definition (as distinct from the appiance used
  +    * to establish the block instance.
  +    *
  +    * @param parent the parent classloader
  +    * @param home the base directory from which classpath expansion is 
resolved
  +    * @param urls the set of block url values to load
  +    * @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
       {
  +        int n = urls.length;
  +        if( n > 0 )
  +        {
  +            if( n > 1 )
  +            {
  +                getLogger().debug( "installing " + urls.length + " blocks." 
);
  +            }
  +            else
  +            {
  +                getLogger().debug( "installing one subsidiary block." );
  +            }
  +        }
  +
           ArrayList blocks = new ArrayList();
           for( int i=0; i<urls.length; i++ )
           {
               URL url = urls[i];
               try
               {
  -                Block block = installBlock( parent, home, url );
  +                Block block = installBlock( parent, home, url, system );
                   blocks.add( block );
               }
               catch( Throwable e )
  @@ -151,9 +186,7 @@
                 + " installed: " 
                 + blocks.size() );
           }
  -
  -        int n = blocks.size();
  -        if( n > 0 )
  +        else
           {
               if( n > 1 )
               {
  @@ -168,7 +201,9 @@
           return (Block[]) blocks.toArray( new Block[0] );
       }
   
  -    private Block installBlock( EngineClassLoader parent, File home, URL url 
) throws Exception
  +    private Block installBlock( 
  +      EngineClassLoader parent, File home, URL url, Context system ) 
  +      throws Exception
       {
           if( getLogger().isDebugEnabled() )
           {
  @@ -194,23 +229,80 @@
           Logger logger = getLogger().getChildLogger( name ) ;
           logger.debug( "[" + name + "]");
   
  -        Configuration blockConfig = getBlockConfiguration( jar );
  -        Configuration config = blockConfig.getChild( "engine" );
  -        EngineClassLoader engine = createChildEngine( parent, home, config, 
logger );
  -
  -
  -        DefaultContext context = new DefaultContext();
  -        context.put( "urn:assembly:classloader", engine );
  -        context.put( "urn:merlin:block.manifest", manifest );
  -        context.put( "urn:merlin:block.url", url );
  -        context.put( "urn:avalon:home", home );
  -        context.makeReadOnly();
  -
  -        DefaultBlock block = new DefaultBlock();
  -        block.enableLogging( logger );
  -        block.contextualize( context );
  -        block.initialize();
  -        return block;
  +        Configuration config = getBlockConfiguration( jar );
  +        Configuration engineConfig = config.getChild( "engine" );
  +        Configuration containerConfig = config.getChild( "container" );
  +
  +        // 
  +        // create a classloader that will be supplied to the 
  +        // block (including resolution of block level classes
  +        // and extension path additions)
  +        //
  +
  +        EngineClassLoader engine = createChildEngine( parent, home, 
engineConfig, url, logger );
  +
  +        //
  +        // create and return the block
  +        //
  +
  +        String classname = containerConfig.getAttribute( "class", 
DefaultContainer.class.getName() );
  +        Type type = engine.getRepository().getTypeManager().getType( 
classname );
  +        ContainerDescriptor descriptor = CREATOR.createContainerDescriptor( 
type, containerConfig );
  +        Configuration[] components = containerConfig.getChildren( 
"component" );
  +        for( int i=0; i<components.length; i++ )
  +        {
  +            Profile profile = createProfile( name, engine, components[i] );
  +            descriptor.addComponent( profile );
  +        }
  +
  +        BlockContext context = new BlockContext( url, manifest );
  +        context.setProfile( descriptor );
  +
  +        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 )
  @@ -222,11 +314,20 @@
           return ( manifest.getAttributes( Block.AVALON_BLOCK_KEY ) != null );
       }
   
  -    protected JarFile getJarFile( URL url )
  +    protected JarFile getJarFile( URL url ) throws MalformedURLException
       {
  +        URL xurl = url;
  +        if( url.getProtocol().equals("jar") )
  +        {
  +            xurl = url;
  +        }
  +        else
  +        {
  +            xurl = new URL( "jar:" + url.toString() + "!/" );
  +        }
           try
           {
  -            JarURLConnection connection = (JarURLConnection) 
url.openConnection();
  +            JarURLConnection connection = (JarURLConnection) 
xurl.openConnection();
               return connection.getJarFile();
           }
           catch( IOException ioe )
  @@ -252,7 +353,7 @@
                   final String msg = "No block configuration - applying 
defaults.";
                   getLogger().debug( msg );
               }
  -            return new DefaultConfiguration( "default", null );
  +            return new DefaultConfiguration( "block", jar.getName() );
           }
   
           try
  @@ -274,7 +375,7 @@
       }
   
       protected EngineClassLoader createChildEngine( 
  -      EngineClassLoader parent, File home, Configuration config, Logger 
logger ) 
  +      EngineClassLoader parent, File home, Configuration config, URL url, 
Logger logger ) 
         throws BlockException, ConfigurationException
       {
           LibraryDescriptor extensions;
  @@ -305,7 +406,7 @@
   
           try
           {
  -            EngineClassLoader engine = new EngineClassLoader( parent );
  +            EngineClassLoader engine = new EngineClassLoader( new URL[]{ url 
}, parent );
               engine.enableLogging( logger.getChildLogger( "engine" ) );
               engine.configure( config );
               DefaultContext context = new DefaultContext();
  
  
  
  1.7       +257 -40   
avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java
  
  Index: DefaultBlock.java
  ===================================================================
  RCS file: 
/home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/DefaultBlock.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- DefaultBlock.java 12 Dec 2002 00:34:07 -0000      1.6
  +++ DefaultBlock.java 15 Dec 2002 14:13:02 -0000      1.7
  @@ -12,6 +12,7 @@
   import java.util.Map;
   import java.util.Hashtable;
   
  +import org.apache.avalon.framework.logger.Logger;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.assembly.appliance.DefaultAppliance;
   import org.apache.avalon.assembly.engine.EngineClassLoader;
  @@ -24,11 +25,15 @@
   import org.apache.avalon.framework.configuration.ConfigurationException;
   import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
   import org.apache.avalon.assembly.appliance.Appliance;
  +import org.apache.avalon.assembly.lifestyle.LifestyleException;
   import org.apache.avalon.merlin.container.DefaultContainer;
  +import org.apache.avalon.merlin.container.ContainerDescriptor;
   import org.apache.avalon.meta.info.Type;
  +import org.apache.avalon.meta.info.StageDescriptor;
  +import org.apache.avalon.meta.info.DependencyDescriptor;
   import org.apache.avalon.meta.model.Profile;
   
  -public class DefaultBlock extends BlockLoader implements Block, 
Contextualizable, Initializable
  +public class DefaultBlock implements Block
   {
       //==============================================================
       // static
  @@ -54,6 +59,8 @@
       // state
       //==============================================================
   
  +    private Logger m_logger;
  +
       private String m_name;
   
       private EngineClassLoader m_engine;
  @@ -74,43 +81,88 @@
       */
       private Appliance m_appliance;
   
  -    //==============================================================
  -    // Contextualizable
  -    //==============================================================
  -
      /**
  -    * <p>Application of a runtime context to the lifestyle service.
  -    * The context value will be passed directly to lifestyle handlers 
  -    * established by this service.
  -    * @param context the runtime context
  +    * The set of subsidiary blocks.
       */
  -    public void contextualize( Context context ) throws ContextException
  -    {
  -        m_url = (URL) context.get( "urn:merlin:block.url" );
  -        m_engine = (EngineClassLoader) context.get( 
"urn:assembly:classloader" );
  -        m_manifest = (Manifest) context.get( "urn:merlin:block.manifest" );
  -        m_home = (File) context.get( "urn:avalon:home" );
  -    }
  +    private Appliance[] m_blocks;
   
  + 
       //==============================================================
  -    // Initializable
  +    // constructor
       //==============================================================
   
  -    public void initialize() throws Exception
  +    public DefaultBlock( 
  +      EngineClassLoader engine, BlockContext context, Context system, Logger 
logger )
  +      throws BlockException
       {
  -        getLogger().debug( "initialization" );
  -        m_config = getBlockConfiguration( getJarFile( m_url ) );
  +        if( engine == null )
  +        {
  +            throw new NullPointerException( "engine" );
  +        }
  +        if( context == null )
  +        {
  +            throw new NullPointerException( "context" );
  +        }
  +        if( system == null )
  +        {
  +            throw new NullPointerException( "system" );
  +        }
  +        if( logger == null )
  +        {
  +            throw new NullPointerException( "logger" );
  +        }
  +
  +        m_logger = logger;
  +
  +        m_url = context.getURL();
  +        if( m_url == null )
  +        {
  +            throw new NullPointerException( "url" );
  +        }
  +
  +        m_manifest = context.getManifest();
  +        if( m_manifest == null )
  +        {
  +            throw new NullPointerException( "manifest" );
  +        }
  +
  +        try
  +        {
  +            m_home = (File) system.get( "urn:avalon:home" );
  +        }
  +        catch( ContextException e )
  +        {
  +            final String error = 
  +              "System context does not declare the 'urn:avalon:home' entry.";
  +            throw new BlockException( error, e );
  +        }
   
           String name = getName();
  -        m_appliance = createContainmentAppliance( m_config );
  -        m_appliance.access();
  +        getLogger().debug( "block initialization: " + name );
  +
  +        ContainerDescriptor descriptor = (ContainerDescriptor) 
context.getProfile();
  +        getLogger().debug( "root container component count: " + 
descriptor.getComponents().length );
  +        
  +        //m_config = getBlockConfiguration( getJarFile( m_url ) );
  +
  +        //
  +        // create the root container for this block
  +        //
   
  +        //m_appliance = createContainmentAppliance( m_config );
  +        //m_appliance.access();
  +
  +        //
  +        // create any nested blocks contained within this block
  +        //
  +
  +        /*
           try
           {
               ClasspathDescriptor path = 
                 CREATOR.createClasspathDescriptor( m_config.getChild( "blocks" 
) );
               URL[] urls = ClasspathDescriptor.expand( m_home, path );
  -            Block[] blocks = install( m_engine, m_home, urls );
  +            m_blocks = install( m_engine, m_home, urls );
           }
           catch( Throwable e )
           {
  @@ -118,13 +170,41 @@
                 "Subsidiary block deployment failure in parent block: " + name;
               throw new BlockException( error, e );
           }
  +        */
  +    }
  +
  +   /**
  +    * Return the loging channel for the appliance.
  +    * @return the logging channel
  +    */
  +    protected Logger getLogger()
  +    {
  +        return m_logger;
  +    }
  +
  +    //==============================================================
  +    // Block
  +    //==============================================================
  +
  +    public void assemble() throws Exception
  +    {
  +        //getLogger().debug( "assemble" );
  +        //ClasspathDescriptor path = 
  +        //  CREATOR.createClasspathDescriptor( m_config.getChild( "blocks" ) 
);
  +        //URL[] urls = ClasspathDescriptor.expand( m_home, path );
  +        //Appliance[] blocks = install( m_engine, m_home, urls );
       }
   
  +    //==============================================================
  +    // Block
  +    //==============================================================
  +
  +   /*
       public Appliance createContainmentAppliance( Configuration config ) 
throws Exception
       {
           String name = getName();
           Configuration containment = m_config.getChild( "container" );
  -        String classname = containment.getAttribute( "type", 
DefaultContainer.class.getName() );
  +        String classname = containment.getAttribute( "class", 
DefaultContainer.class.getName() );
           Type type = m_engine.getRepository().getTypeManager().getType( 
classname );
           Profile profile = 
m_engine.getRepository().getProfileManager().getProfile( type );
   
  @@ -143,30 +223,167 @@
               throw new BlockException( error, e );
           }
       }
  +    */
  +
  +   /**
  +    * Return the name of the block.
  +    * @return the name
  +    */
  +    public String getName()
  +    {
  +        if( m_name == null )
  +        {
  +            m_name = getName( m_manifest );
  +        }
  +        return m_name;
  +    }
   
       //==============================================================
  -    // Block
  +    // Appliance
       //==============================================================
   
  -    public void assemble() throws Exception
  +   /**
  +    * Get the appliance path.
  +    */
  +    public String getPath()
       {
  -        getLogger().debug( "assemble" );
  -        ClasspathDescriptor path = 
  -          CREATOR.createClasspathDescriptor( m_config.getChild( "blocks" ) );
  -        URL[] urls = ClasspathDescriptor.expand( m_home, path );
  -        Block[] blocks = install( m_engine, m_home, urls );
  +        return m_appliance.getPath();
       }
   
  -    //==============================================================
  -    // Block
  -    //==============================================================
  +    /**
  +     * Return the profile backing the appliance.
  +     * @return the profile that this appliance is managing
  +     */
  +    public Profile getProfile()
  +    {
  +        return m_appliance.getProfile();
  +    }
   
  -    public String getName()
  +    /**
  +     * Return the activation policy for the component.  If TRUE, activation
  +     * will occur at startup.  If false, activation will be deferred to
  +     * the first lookup invocation if any (i.e. lazy activation).
  +     *
  +     * @return the activation policy
  +     */
  +    public boolean getActivationPolicy()
       {
  -        if( m_name == null )
  -        {
  -            m_name = getName( m_manifest );
  -        }
  -        return m_name;
  +        return m_appliance.getActivationPolicy();
  +    }
  +
  +    /**
  +     * Test is this profile is enabled.  A profile is enabled unless 
explicitly disabled by an
  +     * assembly directive, or implicity disabled as a result of an assembly 
failure.
  +     *
  +     * @return TRUE if the profile is enabled.
  +     * @see #setEnabled( boolean )
  +     */
  +    public boolean isEnabled()
  +    {
  +        return m_appliance.isEnabled();
  +    }
  +
  +    /**
  +     * Set the enabled status of the profile to the supplied value.
  +     * @param value the enabled status - TRUE or FALSE
  +     */
  +    public void setEnabled( boolean value )
  +    {
  +        m_appliance.setEnabled( value );
  +    }
  +
  +    /**
  +     * Return the assigned service providers.
  +     * @return the set of service provider appliances.
  +     */
  +    public Appliance[] getServiceProviders()
  +    {
  +        return m_appliance.getServiceProviders();
  +    }
  +
  +    /**
  +     * Return the dependency associations for component type with specified 
role.
  +     *
  +     * @param role the dependency role name
  +     * @return the dependency metadata for component with specified role.
  +     */
  +    public Appliance getServiceProvider( final String role )
  +    {
  +        return m_appliance.getServiceProvider( role );
  +    }
  +
  +    /**
  +     * Add the appliance that will acts as provider for a named dependency.
  +     * @param role the role against which the supplied appliance is to be 
associated
  +     * @param appliance the appliance that will fulfill the provider 
dependency
  +     */
  +    public void addServiceProvider( final String role, final Appliance 
appliance )
  +    {
  +        m_appliance.addServiceProvider( role, appliance );
  +    }
  +
  +    /**
  +     * Return the assigned extension providers.
  +     *
  +     * @return the set of extension provider appliances.
  +     */
  +    public Appliance[] getExtensionProviders()
  +    {
  +        return m_appliance.getExtensionProviders();
  +    }
  +
  +    /**
  +     * Returns the appliace assigned to handle the components lifecycle 
stage.
  +     * @param stage the lifecycle stage specification
  +     * @return a reference to the stage extension
  +     */
  +    public Appliance getExtensionProvider( final StageDescriptor stage )
  +    {
  +        return m_appliance.getExtensionProvider( stage );
  +    }
  +
  +    /**
  +     * Add a lifecycle stage extension.
  +     * @param stage the identifier of the stage to assign the manager to
  +     * @param appliance the appliance that will handle the stage
  +     */
  +    public void addExtensionProvider( final StageDescriptor stage, final 
Appliance appliance )
  +    {
  +        m_appliance.addExtensionProvider( stage, appliance );
  +    }
  +
  +   /**
  +    * Activate of the appliance.
  +    * @return the implementation object
  +    */
  +    public Object access() throws LifestyleException
  +    {
  +        return m_appliance.access();
  +    }
  +
  +   /**
  +    * Activate a service provided by the appliance.
  +    * @param dependency the service dependecy decsriptor
  +    */
  +    public Object access( final DependencyDescriptor dependency ) throws 
LifestyleException
  +    {
  +        return m_appliance.access( dependency );
  +    }
  +
  +   /**
  +    * Activate an extension handler provided by the appliance.
  +    * @param appliance the appliance to deploy
  +    */
  +    public Object access( final StageDescriptor stage ) throws 
LifestyleException
  +    {
  +        return m_appliance.access( stage );
  +    }
  +
  +   /**
  +    * Release a reference to a service provided by this appliance.
  +    */
  +    public void release( final Object object )
  +    {
  +        m_appliance.release( object );
       }
   }
  
  
  
  1.1                  
avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/BlockContext.java
  
  Index: BlockContext.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.merlin.block;
  
  import java.net.URL;
  import java.util.jar.Manifest;
  
  import org.apache.avalon.assembly.appliance.ApplianceContext;
  
  
  /**
   * An block context aggregates the set of arguments that are supplied to
   * and block instance.
   * 
   * @author <a href="mailto:avalon-dev@jakarta.apache.org";>Avalon Development 
Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/12/15 14:13:02 $
   */
  public class BlockContext extends ApplianceContext
  {
      //=====================================================================
      // state
      //=====================================================================
  
      /**
       * The URL to the block jar file.
       */
       private URL m_url;
  
      /**
       * The block manifest.
       */
      private Manifest m_manifest;
  
      //==============================================================
      // constructor
      //==============================================================
  
     /**
      * Creation of a new appliance context.
      * @param engine the service management engine
      * @param profile the profile
      * @param system the system context
      */
      public BlockContext( URL url, Manifest manifest )
      {
          if( url == null )
          {
              throw new NullPointerException( "url" );
          }
          if( manifest == null )
          {
              throw new NullPointerException( "manifest" );
          }
          m_url = url;
          m_manifest = manifest;
      }
  
      //==============================================================
      // parameters
      //==============================================================
  
     /**
      * Get the block jar URL.
      * @return the url
      */
      public URL getURL()
      {
          return m_url;
      }
  
     /**
      * Get the nlock manifest.
      * @return the manifest
      */
      public Manifest getManifest()
      {
          return m_manifest;
      }
  
  }
  
  
  
  1.1                  
avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/ContainerLoader.java
  
  Index: ContainerLoader.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact [EMAIL PROTECTED]
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.merlin.container;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.net.URL;
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.jar.JarFile;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.util.zip.ZipEntry;
  import java.net.JarURLConnection;
  
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Startable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.context.Contextualizable;
  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.model.LoggingDirective;
  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.logging.LoggingManager;
  import org.apache.avalon.assembly.logging.LoggingDescriptor;
  import org.apache.avalon.assembly.logging.DefaultLoggingManager;
  import org.apache.avalon.assembly.engine.EngineClassLoader;
  import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
  import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
  import org.apache.avalon.assembly.util.ExceptionHelper;
  
  /**
   * An abstract utility class that provides support for  
   * @author <a href="mailto:avalon-dev@jakarta.apache.org";>Avalon Development 
Team</a>
   * @version $Revision: 1.1 $ $Date: 2002/12/15 14:13:02 $
   */
  
  public class ContainerLoader extends AbstractLogEnabled 
  {
      //==============================================================
      // static
      //==============================================================
  
      protected static final XMLContainerCreator CREATOR = new 
XMLContainerCreator();
  
      //==============================================================
      // BlockLoader
      //==============================================================
  
  }
  
  
  
  1.5       +2 -2      
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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XMLContainerCreator.java  11 Dec 2002 08:12:24 -0000      1.4
  +++ XMLContainerCreator.java  15 Dec 2002 14:13:02 -0000      1.5
  @@ -225,7 +225,7 @@
           // create the logging categories for this profile
           //
   
  -        final String name = profile.getAttribute( "name" );
  +        final String name = profile.getAttribute( "name", "container" );
           LoggingDirective categories =
               createLoggingDirective( name, profile.getChild( "categories" ) );
   
  
  
  
  1.9       +31 -8     
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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- DefaultKernel.java        12 Dec 2002 00:36:08 -0000      1.8
  +++ DefaultKernel.java        15 Dec 2002 14:13:03 -0000      1.9
  @@ -89,6 +89,7 @@
   import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
   import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
   import org.apache.avalon.assembly.util.ExceptionHelper;
  +import org.apache.avalon.assembly.appliance.Appliance;
   import org.apache.avalon.merlin.block.Block;
   import org.apache.avalon.merlin.block.DefaultBlock;
   import org.apache.avalon.merlin.block.BlockLoader;
  @@ -153,6 +154,11 @@
        */
       private EngineClassLoader m_engine;
   
  +    /**
  +     * The system context.
  +     */
  +    private Context m_system;
  +
       //==============================================================
       // Contextualizable
       //==============================================================
  @@ -251,8 +257,7 @@
           }
   
           //
  -        // setup the bootstrap assembly engine that we will use to assembly
  -        // out root container
  +        // setup the bootstrap assembly engine
           //
   
           try
  @@ -274,7 +279,8 @@
           }
   
           //
  -        // we are now ready to assemble the root container
  +        // we are now ready to assemble the blocks declared under the 
  +        // kernel configuration
           //
   
           if( getLogger().isDebugEnabled() )
  @@ -293,11 +299,12 @@
                  getLogger().debug( "blocks: " + urls.length );
               }
   
  -            Block[] blocks = install( m_engine, m_home, urls );
  +            Context system = getSystemContext();
  +            Appliance[] blocks = install( m_engine, m_home, urls, system );
           }
           catch( Throwable e )
           {
  -            final String error = "Block deployment failure.";
  +            final String error = "Block installation phase failure.";
               String log = ExceptionHelper.packException( error, e );
               if( getLogger().isErrorEnabled() )
               {
  @@ -438,8 +445,8 @@
               EngineClassLoader engine = new EngineClassLoader();
               engine.enableLogging( getLogger().getChildLogger( "engine" ) );
               engine.configure( config );
  -            DefaultContext context = new DefaultContext();
  -            context.put( "urn:avalon:home", m_home );
  +            Context system = getSystemContext();
  +            DefaultContext context = new DefaultContext( system );
               context.put( "urn:assembly:engine.bootstrap", "true" );
               context.put( "urn:assembly:engine.extensions", extensions );
               context.put( "urn:assembly:engine.classpath", classpath );
  @@ -467,5 +474,21 @@
       {
           return "DefaultKernel"
             + ":" + System.identityHashCode( this );
  +    }
  +
  +   /**
  +    * Create the system context.
  +    * @return the system context
  +    */
  +    private Context getSystemContext()
  +    {
  +        if( m_system == null )
  +        {
  +            DefaultContext context = new DefaultContext();
  +            context.put( "urn:avalon:home", m_home );
  +            context.makeReadOnly();
  +            m_system = context;
  +        }
  +        return m_system;
       }
   }
  
  
  
  1.4       +15 -35    avalon-sandbox/merlin/src/test/config/block.xml
  
  Index: block.xml
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/src/test/config/block.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- block.xml 12 Dec 2002 00:36:40 -0000      1.3
  +++ block.xml 15 Dec 2002 14:13:03 -0000      1.4
  @@ -6,24 +6,22 @@
   <block>
   
      <!--
  -   Configuration of the service management engine that will be supplied 
  -   to the block during deployment.
  +   Block information.
      -->
   
  -   <engine>
  +   <info>
  +     <name>standard</name>
  +   </info>
   
  -     <!--
  -     Declaration of the location of additional supporting jar files 
  -     not accessible as extensions.
  -     -->
  -
  -     <classpath>
  -       <fileset dir="build/lib">
  -         <include name="avalon-merlin-demo-1.0.jar"/>
  -       </fileset>
  -     </classpath>
  +   <!--
  +   Declaration the services provided by this block.
  +   -->
   
  -   </engine>
  +   <services>
  +     <service>
  +       <reference type="org.apache.avalon.playground.StandardService"/>
  +     </service>
  +   </services>
   
      <!--
      Declaration the block implemetation.
  @@ -31,32 +29,14 @@
   
      <container>
   
  -     <import/>
  -
  -     <component name="basic" 
class="org.apache.excalibur.playground.BasicComponent" activation="startup">
  +     <component name="basic" 
class="org.apache.avalon.playground.StandardComponent" activation="startup">
          <categories priority="DEBUG"/>
  -       <context class="org.apache.excalibur.playground.BasicContext">
  +       <context class="org.apache.avalon.playground.StandardComponent">
            <entry key="location">My Place</entry>
  -         <import name="avalon:home" key="home" />
  +         <import name="urn:avalon:home" key="home" />
          </context>
        </component>
   
  -     <export>
  -       <reference type="org.apache.excalibur.playground.BasicService"/>
  -     </export>
  -
      </container>
  -
  -   <!--
  -   Declaration of any subsidiary blocks.
  -   -->
  -
  -   <blocks>
  -     <!--
  -     <fileset dir="build/lib">
  -       <include name="xxx.jar"/>
  -     </fileset>
  -     -->
  -   </blocks>
   
   </block>
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to