avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mcconn...@apache.org
Subject cvs commit: avalon-sandbox/merlin/src/test/org/apache/avalon/merlin/kernel KernelTestCase.java
Date Sat, 18 Jan 2003 16:23:55 GMT
mcconnell    2003/01/18 08:23:55

  Modified:    merlin   blocks.xml
               merlin/src/java/org/apache/avalon/merlin/block Block.java
                        package.html
               merlin/src/java/org/apache/avalon/merlin/container
                        DefaultContainer.java
               merlin/src/java/org/apache/avalon/merlin/kernel
                        DefaultKernel.java KernelLoader.java
               merlin/src/test/org/apache/avalon/merlin/kernel
                        KernelTestCase.java
  Added:       merlin/src/java/org/apache/avalon/merlin/block
                        BlockLoader.java
               merlin/src/java/org/apache/avalon/merlin/block/impl
                        DefaultBlock.java DefaultBlockLoader.java
                        package.html
  Removed:     merlin/src/java/org/apache/avalon/merlin/block
                        DefaultBlock.java
  Log:
  Refactoring the kernel to seperate block loading from container implementation.
  
  Revision  Changes    Path
  1.7       +6 -7      avalon-sandbox/merlin/blocks.xml
  
  Index: blocks.xml
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/blocks.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- blocks.xml	18 Jan 2003 02:11:43 -0000	1.6
  +++ blocks.xml	18 Jan 2003 16:23:54 -0000	1.7
  @@ -1,10 +1,9 @@
   
   <!--
  -The blocks.xml file contains the declaration of the blocks to be loaded
  -and assembled by the kernel.  Each block element declares a block name,
  -a path to a single jar file, an engine configuration (which may 
  -include declaration of additional extension directories a block 
  -classpath), and tagged configuration fragments.
  +The blocks.xml file contains the declaration of the top-level blocks to 
  +be loaded and assembled by the kernel.  Each block element declares a 
  +block name, a path to a single jar file or block.xml file, and tagged 
  +configuration fragments.
   -->
   
   <blocks>
  @@ -20,9 +19,9 @@
         </configuration>
      </block>
   
  -   <block name="playground" path="../assembly/build/lib/avalon-assembly-demo-1.0.jar" enabled="true"/>
  +   <block name="playground" path="../assembly/build/lib/avalon-assembly-demo-1.0.jar" enabled="true" />
   
  -   <block name="demo" src="src/test/config/demo.xml" enabled="true" >
  +   <block name="demo" src="src/test/config/demo.xml" enabled="true">
        <configuration target="test">
          <configuration target="standard">
            <message>Client supplied message.</message>
  
  
  
  1.9       +2 -24     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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Block.java	15 Jan 2003 09:14:51 -0000	1.8
  +++ Block.java	18 Jan 2003 16:23:54 -0000	1.9
  @@ -79,28 +79,6 @@
       *
       * @exception Exception if a deployment error occurs
       */
  -    void decommission() throws Exception;
  -
  -   /**
  -    * Startup the block and startup all subsidiary blocks.
  -    * @exception Exception if a startup error occurs
  -    */
  -    //void startup() throws Exception;
  -
  -   /**
  -    * Suspend the block and all subsidiary blocks.
  -    */
  -    //void suspend();
  -
  -   /**
  -    * Resume the block and all subsidiary blocks.
  -    */
  -    //void resume();
  -
  -   /**
  -    * Shutdown the block.
  -    * @exception Exception if a shutdown error occurs
  -    */
  -    //void shutdown() throws Exception;
  +    void decommission();
   
   }
  
  
  
  1.2       +1 -1      avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/package.html,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- package.html	27 Dec 2002 16:39:14 -0000	1.1
  +++ package.html	18 Jan 2003 16:23:54 -0000	1.2
  @@ -1,5 +1,5 @@
   
   <body>
  -<p>The block package provides support for packaged component heirachies and represents functional application building block.</p> 
  +<p>The block package defines the interfaces and client contract supporting the concept of a composite component block.</p>
   </body>
   
  
  
  
  1.9       +12 -274   avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/BlockLoader.java
  
  
  
  
  1.1                  avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/impl/DefaultBlock.java
  
  Index: DefaultBlock.java
  ===================================================================
  
  
  package org.apache.avalon.merlin.block.impl;
  
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.util.List;
  import java.util.Iterator;
  import java.util.ArrayList;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.util.jar.JarFile;
  import java.util.Map;
  import java.util.Hashtable;
  
  import org.apache.avalon.assembly.appliance.Appliance;
  import org.apache.avalon.assembly.appliance.DefaultAppliance;
  import org.apache.avalon.assembly.appliance.ApplianceContext;
  import org.apache.avalon.assembly.appliance.ApplianceException;
  import org.apache.avalon.assembly.appliance.DependencyGraph;
  import org.apache.avalon.assembly.engine.EngineClassLoader;
  import org.apache.avalon.assembly.locator.Locator;
  import org.apache.avalon.assembly.locator.Contextualizable;
  import org.apache.avalon.assembly.lifestyle.LifestyleException;
  import org.apache.avalon.assembly.lifestyle.LifestyleService;
  import org.apache.avalon.assembly.lifecycle.AssemblyService;
  import org.apache.avalon.assembly.lifecycle.AssemblyException;
  import org.apache.avalon.assembly.util.ExceptionHelper;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.ContextException;
  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.merlin.block.Block;
  import org.apache.avalon.merlin.block.BlockException;
  import org.apache.avalon.merlin.container.DefaultContainer;
  import org.apache.avalon.merlin.container.ContainerDescriptor;
  import org.apache.avalon.merlin.container.Container;
  import org.apache.avalon.merlin.container.StateListener;
  import org.apache.avalon.merlin.container.StateEvent;
  import org.apache.avalon.meta.info.Type;
  import org.apache.avalon.meta.info.builder.XMLTypeCreator;
  import org.apache.avalon.meta.info.StageDescriptor;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.meta.model.builder.XMLProfileCreator;
  import org.apache.avalon.meta.model.Profile;
  import org.apache.avalon.merlin.service.Registry;
  import org.apache.avalon.merlin.kernel.DefaultKernel;
  import org.apache.avalon.assembly.appliance.DefaultApplianceContext;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  
  /**
   * The default implementation of a Block.  The implementation provides 
   * support for convinence operations related to its role as a container
   * by delegating to the container it is managing. As an appliance it is 
   * responsible for the establishment of a containment heirachy that 
   * represents the implemetation model for the block.
   */
  public class DefaultBlock extends DefaultAppliance implements Block, Runnable, StateListener
  {
      //-------------------------------------------------------------------------------
      // static
      //-------------------------------------------------------------------------------
  
      public static final Attributes.Name BLOCK_PACKAGE = new Attributes.Name( "Block-Package" );
      public static final Attributes.Name OLD_BLOCK_NAME = new Attributes.Name( "Block-Name" );
  
      private static final int DISASSEMBLED = 1000;
      private static final int TERMINATED = 2000;
      private static final int DISPOSED = 3000;
  
      public static String getPackageName( Manifest manifest )
      {
          Attributes attributes = manifest.getAttributes( Block.AVALON_BLOCK_KEY );
          if( attributes == null )
          {
              return null;
          }
          if( attributes.containsKey( BLOCK_PACKAGE ) )
          {
              return (String) attributes.get( BLOCK_PACKAGE );
          }
          if( attributes.containsKey( OLD_BLOCK_NAME ) )
          {
              return (String) attributes.get( OLD_BLOCK_NAME );
          }
          return null;
      }
  
      public static boolean isBlock( Manifest manifest )
      {
          if( manifest == null )
          {
              return false;
          }
          return ( manifest.getAttributes( Block.AVALON_BLOCK_KEY ) != null );
      }
  
  
      //-------------------------------------------------------------------------------
      // state
      //-------------------------------------------------------------------------------
  
     /**
      * The engine classloader.
      */
      EngineClassLoader m_engine;
  
     /**
      * The root container instance that this block is managing.
      */
      private Container m_container;
  
     /**
      * Flag holding the assembled state of the block.
      */
      private boolean m_assembled = false;
  
      /**
       * The thread in which we will run the container.
       */
      private Thread m_thread;
  
     /**
      * Flag holding the running state of the block.
      */
      private boolean m_running = false;
  
      /**
       * The container is managed as a thread under which the current state
       * is recorded in the m_state state member.
       */
      private int m_state = StateEvent.UNKNOWN;
  
      /**
       * The thread periodically checks for state change requests enter in
       * the m_action state member and attempts to bring the m_state value to
       * be equal to the m_action value and once achieved goes off for a
       * sleep.
       */
      private Integer m_action = new Integer( StateEvent.UNKNOWN );
  
      /**
       * An error raised by the managed container.
       */
      private BlockException m_error;
  
      /**
       * The apliance context.
       */
      private ApplianceContext m_applianceContext;
  
     /**
      * The container meta info descriptor.
      */
      private ContainerDescriptor m_descriptor;
  
     /**
      * The block configuration.
      */
      private Configuration m_config;
  
     /**
      * The service registry assigned to the block.
      */
      private Registry m_registry;
  
     /**
      * List of the appliance instances that the block is 
      * managing.
      */
      private List m_appliances = new ArrayList();
  
     /**
      * List of the subsidiary blocks.
      */
      private List m_blocks = new ArrayList();
  
     /**
      * Map of container objects keyed by block.
      */
      private Map m_containers = new Hashtable();
  
     /**
      * Reference to the set of appliances to be terminated.  The set 
      * appliances is based on the shutdown graph resolved during the 
      * disassembly phase.
      */
      private Appliance[] m_shutdown;
  
     /**
      * List of the commonents that have been established explicity by the 
      * block during deployment.
      */
      private Map m_components = new Hashtable();
  
     /**
      * Flag holding the deoplyed state of the block.
      */ 
      private boolean m_deployed = false;
  
     /**
      * Flag holding the decommissioned state of the block.
      */ 
      private boolean m_decommissioned = false;
  
     /**
      * Flag holding the disassembled state of the block.
      */ 
      private boolean m_disassembled = false;
  
     /**
      * Flag holding the terminated state of the block.
      */ 
      private boolean m_terminated = false;
  
      //=====================================================================
      // Contextualizable
      //=====================================================================
  
     /**
      * Supply a object locator to the instance.
      * @param locator the object locator
      * @exception LocatorException if a object location error occurs
      */
      public void contextualize( Locator context ) throws ContextException
      {
          super.contextualize( context );
          m_engine = (EngineClassLoader) context.get( "urn:assembly:engine" );
          m_applianceContext = (ApplianceContext) context.get( "urn:assembly:appliance.context" );
          m_descriptor = (ContainerDescriptor) context.get( "urn:merlin:container.descriptor" );
          m_registry = (Registry) context.get( "urn:merlin:container.registry" );
          m_config = (Configuration) context.get( "urn:merlin:container.configuration" );
          m_blocks = (List) context.get( "urn:merlin:container.containers" );
      }
  
      //=====================================================================
      // Initializable
      //=====================================================================
  
     /**
      * Initialization of the blocks during which appliance instances managed by the blocks
      * will be established.
      *
      * @exception Exception if a block initialization error occurs
      */
      public void initialize() throws Exception
      {
          super.initialize();
          if( m_engine == null )
          {
              throw new IllegalStateException( "context" );
          }
   
          //
          // construct the appliance instances managed by this block
          //
  
          Profile[] profiles = m_descriptor.getComponents();
          for( int i=0; i<profiles.length; i++ )
          {
              Profile profile = profiles[i];
              if( getLogger().isDebugEnabled() )
              {
                  final String message = "profile: " + profile; 
                  getLogger().debug( message );
              }
  
              Configuration config = 
                 DefaultKernel.getNamedConfiguration( m_config, profile.getName() );
  
              DefaultApplianceContext context = 
                 new DefaultApplianceContext( profile );
              context.setPartitionName( getPath() );
              context.setConfiguration( config );
              context.setStartupPolicy( false );
              context.makeReadOnly();
  
              Appliance appliance = m_engine.createAppliance( context, true );
              m_appliances.add( appliance );
              m_registry.bind( appliance );
          }
     }
  
      //-------------------------------------------------------------------------------
      // Appliance
      //-------------------------------------------------------------------------------
  
     /**
      * Assemble the appliance.  The implementation extends the default 
      * appliance behavior by instantiating the container it is managing, 
      * and applying assembly to the container instance. This results in 
      * container creating appliance instances for the component is is 
      * managing together with assembly of its sub-containers.
      *
      * @exception AssemblyException if an error occurs during appliance assembly
      */
      public void assemble( DependencyGraph graph ) throws AssemblyException
      {
          if( m_assembled )
          {
              return;
          }
  
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug("block assembly: " + System.identityHashCode( graph ) );
          }
  
          //
          // add the dependecy graph to the context that will be used to establish
          // the container so that the container can handle orderly startup and 
          // shutdown of compoents
          //
   
          Map context = m_applianceContext.getDeploymentContext();
          context.put( "urn:merlin:container.dependency-graph", graph );
          context.put( "urn:merlin:container.listener", this );
  
          //
          // assemble the components handled by the block
          //
  
          try
          {
              assembleComponents( graph );
          }
          catch( AssemblyException e )
          {
              final String error = 
                "Assembly failure attributable to embedded appliance.";
              throw new AssemblyException( error, e );
          }
  
          //
          // assemble the subsidiary blocks
          //
  
          Iterator iterator = m_blocks.iterator();
          while( iterator.hasNext() )
          {
              Block block = (Block) iterator.next();
  
              if( getLogger().isDebugEnabled() )
              {
                  final String message =
                    "activating block: " + block; 
                  getLogger().debug( message );
              }
  
              try
              {
                  block.assemble( new DependencyGraph( graph ) );
                  Container container = (Container) block.resolve( this );
                  m_containers.put( block, container );
              }
              catch( Throwable e )
              {
                  final String error =
                    "Could not establish a sub-container: " 
                    + block
                    + " in block: " + this;
                  throw new AssemblyException( error, e );
              }
          }
  
          super.assemble( graph );
  
          if( getLogger().isDebugEnabled() )
          {
              Appliance[] startup = graph.getStartupGraph( );
              StringBuffer buffer = new StringBuffer( "startup sequence: " );
              for( int p=0; p<startup.length; p++ )
              {
                 buffer.append( ", " + startup[p] );
              }
              getLogger().debug( buffer.toString() );
          }
      }
  
     /**
      * Startup the components in this container.
      * @exception Exception if a startup error occurs
      */
      private void assembleComponents( DependencyGraph graph ) throws AssemblyException
      {
          Iterator iterator = m_appliances.iterator();
          while( iterator.hasNext() )
          {
              Appliance appliance = (Appliance) iterator.next();
              graph.add( appliance );
              appliance.assemble( graph );
          }
      }
  
     /**
      * Disassemble the block.
      */
      public void disassemble()
      {
          if( m_disassembled )
          {
              return;
          }
  
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "disassemble" );
          }
  
          if( !m_deployed )
          {
              throw new IllegalStateException( "deployment" );
          }
  
          synchronized( m_action )
          {
              m_action = new Integer( StateEvent.STOPPED );
              while( ( m_state < StateEvent.STOPPED  ) && ( m_error == null ) )
              {
                  sleep();
              }
  
              if( m_error != null )
              {
                  if( getLogger().isErrorEnabled() )
                  {
                      final String msg = "Unexpected error during disassembly.";
                      String error = ExceptionHelper.packException( msg, m_error );
                      getLogger().error( error );
                      m_error = null;
                  }
              }
          }
      }
  
     /**
      * Startup the components in this container.
      * @exception Exception if a startup error occurs
      */
      //private void disassembleComponents()
      //{
      //    Iterator iterator = m_appliances.iterator();
      //    while( iterator.hasNext() )
      //    {
      //        Appliance appliance = (Appliance) iterator.next();
      //        appliance.disassemble();
      //    }
      //}
  
     /**
      * Terminate the block.  If a container has been established, the implemetation
      * will relase the container and continue with appliance termination.
      */
      public void terminate()
      {
          if( m_terminated )
          {
              return;
          }
  
          if( !m_deployed )
          {
              handleTermination();
          }
  
          synchronized( m_action )
          {
              m_action = new Integer( TERMINATED );
              while( ( m_state < TERMINATED ) && ( m_error == null ) )
              {
                  sleep();
              }
  
              if( m_error != null )
              {
                  if( getLogger().isErrorEnabled() )
                  {
                      final String msg = "Unexpected error during termination.";
                      String error = ExceptionHelper.packException( msg, m_error );
                      getLogger().error( error );
                      m_error = null;
                  }
              }
          }
      }
  
      //-------------------------------------------------------------------------------
      // Block
      //-------------------------------------------------------------------------------
  
     /**
      * Deploy the block during which appliances managed by the block
      * will be established as executing components.
      *
      * @exception Exception if a deployment error occurs
      */
      public void deploy() throws Exception
      {
          if( getDependencyGraph() == null )
          {
              final String error =
                "Cannot deploy block " + this + " before assembly.";
              throw new IllegalStateException( error );
          }
  
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "deployment" );
          }
  
          //
          // construct and start a thread in which this block will execute
          //
  
          m_thread = new Thread( this, super.getPath() );
          m_thread.setContextClassLoader( m_engine );
          m_thread.start();
  
          synchronized( m_action )
          {
              m_action = new Integer( StateEvent.STARTED );
              while( ( m_state < StateEvent.STARTED ) && ( m_error == null ) )
              {
                  sleep();
              }
  
              if( m_error != null )
              {
                  m_state = StateEvent.STOPPED;
                  final String error = 
                    "Unexpected deployment error.";
                  Exception exception = new BlockException( error, m_error );
                  m_error = null;
                  throw exception;
              }
          }
  
          //
          // deploy the subsidiary blocks
          //
  
          Iterator iterator = m_blocks.iterator();
          while( iterator.hasNext() )
          {
              Block block = (Block) iterator.next();
  
              try
              {
                  block.deploy();
                  Container container = (Container) block.resolve( this );
                  m_containers.put( block, container );
              }
              catch( Throwable e )
              {
                  final String error =
                    "Subsidiary block deployment error in: " + block
                    + " in parent block: " + this;
                  m_error = new BlockException( error, e );
                  break;
              }
          }
          
          m_deployed = true;
      }
  
     /**
      * Decommission the block.
      *
      * @exception Exception if a deployment error occurs
      */
      public void decommission()
      {
          if( !m_deployed )
          {
              throw new IllegalStateException( "deployment" );
          }
  
          synchronized( m_action )
          {
  
              m_action = new Integer( StateEvent.STOPPED );
              while( ( m_state < StateEvent.STOPPED ) && ( m_error == null ) )
              {
                  sleep();
              }
  
              if( m_error != null )
              {
                  if( getLogger().isErrorEnabled() )
                  {
                      final String msg = "Unexpected error during decommissioning.";
                      String error = ExceptionHelper.packException( msg, m_error );
                      getLogger().error( error );
                  }
                  m_state = StateEvent.STOPPED;
              }
          }
      }
  
      //-------------------------------------------------------------------------------
      // Runnable
      //-------------------------------------------------------------------------------
  
      /**
       * Starts the thread of execution for the block.  This operation is
       * invoked by the container constructor.
       */
      public void run()
      {
          if( !m_running )
          {
              m_running = true;
          }
  
          try
          {
  
              m_container = (Container) resolve( this );
  
              //
              // while desired state of the hosted container is something
              // other than DISPOSED, check if the desired state is different
              // from the current state reported by the container, and if
              // so initiate a container state change
              //
  
              while( m_action.intValue() < DISPOSED )
              {
                  synchronized( m_action )
                  {
                      if( m_state != m_action.intValue() )
                      {
                          switch( m_action.intValue() )
                          {
                              case StateEvent.STARTED:
                                  if( m_state == StateEvent.INITIALIZED )
                                  {
                                      m_container.startup();
                                  }
                                  else if( m_state == StateEvent.SUSPENDED )
                                  {
                                      m_container.resume();
                                  }
                                  break;
                              case StateEvent.SUSPENDED:
                                  if( m_state == StateEvent.STARTED )
                                  {
                                      m_container.suspend();
                                  }
                                  break;
                              case StateEvent.STOPPED:
                                  handleDecommissioning();
                                  break;
                              case DISASSEMBLED:
                                  handleDisassembly();
                                  break;
                              case TERMINATED:
                                  handleTermination();
                                  break;
                          }
                      }
                  }
                  sleep();
              }
  
              getLogger().debug( "exit: " + m_state );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected runtime error in block:" + this;
              m_error = new BlockException( error, e );
          }
      }
  
      private void handleDecommissioning()
      {
          //
          // decommission the subsidiary blocks
          //
   
          Iterator iterator = m_blocks.iterator();
          while( iterator.hasNext() )
          {
              Block block = (Block) iterator.next();
              block.decommission();
          }
  
          if( m_container != null )
          {
              if( ( m_state == StateEvent.STARTED )
                || ( m_state == StateEvent.SUSPENDED ) )
              {
                  m_container.shutdown();
              }
          }
          else
          {
              m_state = StateEvent.STOPPED;
          }
  
          m_decommissioned = true;
      }
  
      private void handleDisassembly()
      {
          if( !m_decommissioned )
          {
              handleDecommissioning();
          }
  
          m_shutdown = getDependencyGraph().getShutdownGraph();
  
          if( getLogger().isDebugEnabled() )
          {
              StringBuffer buffer = new StringBuffer( "dissassemble: " );
              for( int p=0; p<m_shutdown.length; p++ )
              {
                 buffer.append( ", " + m_shutdown[p] );
              }
              getLogger().debug( buffer.toString() );
          }
  
          for( int i=0; i<m_shutdown.length; i++ )
          {
              Appliance appliance = m_shutdown[i];
              appliance.disassemble();
          }
  
          Iterator iterator = m_blocks.iterator();
          while( iterator.hasNext() )
          {
              Block block = (Block) iterator.next();
              block.disassemble();
          }
  
          super.disassemble();
          m_disassembled = true;
          m_state = DISASSEMBLED;
      }
  
      private void handleTermination()
      {
          if( m_terminated )
          {
              // already terminated
              return;
          }
  
          if( !m_disassembled )
          {
              handleDisassembly();
          }
  
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "termination" );
          }
  
          for( int i=0; i<m_shutdown.length; i++ )
          {
              Appliance appliance = m_shutdown[i];
              appliance.terminate();
          }
  
          m_appliances = null;
  
          Iterator iterator = m_blocks.iterator();
          while( iterator.hasNext() )
          {
              Block block = (Block) iterator.next();
              block.terminate();
          }
  
          m_terminated = true;
          m_state = TERMINATED;
          super.terminate();
  
          //
          // trigger termination of the thread
          //
  
          m_action = new Integer( DISPOSED );
      }
  
      //-------------------------------------------------------------------------------
      // internal
      //-------------------------------------------------------------------------------
  
      /**
       * Method invoked when a container state changes.
       * @param event the state event
       */
      public void stateChanged( StateEvent event )
      {
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug("state event: " + event );
          }
          m_state = event.getState();
      }
  
      /**
       * Internal utility to sleep a bit.
       */
      private void sleep()
      {
          try
          {
              Thread.currentThread().sleep( 100 );
          }
          catch( Throwable wakeup )
          {
              // return
          }
      }
  }
  
  
  
  1.1                  avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/impl/DefaultBlockLoader.java
  
  Index: DefaultBlockLoader.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 apache@apache.org.
  
   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.impl;
  
  import java.io.File;
  import java.io.IOException;
  import java.io.FileInputStream;
  import java.io.InputStream;
  import java.net.URL;
  import java.net.MalformedURLException;
  import java.util.List;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.ArrayList;
  import java.util.Hashtable;
  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.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.EngineException;
  import org.apache.avalon.assembly.engine.Engine;
  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.assembly.appliance.ApplianceContext;
  import org.apache.avalon.assembly.appliance.DefaultApplianceContext;
  import org.apache.avalon.assembly.appliance.DependencyGraph;
  import org.apache.avalon.assembly.engine.type.UnknownTypeException;
  import org.apache.avalon.assembly.locator.Contextualizable;
  import org.apache.avalon.assembly.locator.Locator;
  import org.apache.avalon.assembly.locator.LocatorException;
  import org.apache.avalon.assembly.locator.DefaultLocator;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  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.ContextException;
  import org.apache.avalon.framework.service.DefaultServiceManager;
  import org.apache.avalon.merlin.block.Block;
  import org.apache.avalon.merlin.block.BlockException;
  import org.apache.avalon.merlin.block.BlockLoader;
  import org.apache.avalon.merlin.container.builder.XMLContainerCreator;
  import org.apache.avalon.merlin.container.ContainerDescriptor;
  import org.apache.avalon.merlin.container.Container;
  import org.apache.avalon.merlin.container.ContainerException;
  import org.apache.avalon.merlin.container.DefaultContainer;
  import org.apache.avalon.merlin.service.DefaultRegistry;
  import org.apache.avalon.merlin.service.Registry;
  import org.apache.avalon.meta.model.builder.XMLProfileCreator;
  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;
  
  /**
   * Implementation of the block loader.
   *
   * <ul>
   * <li>loading kernel.xml configuration
   * <li>loading blocks.xml configuration
   * <li>establishment of the logging system
   * <li>loading internal jar-file dependencies
   * <li>establishment of a root component management engine
   * <li>block abstraction that encapsulates a heirachical container model
   * <li>block configuration repository
   * <li>block assembly, deployment and decommissioning
   * <li>management of interupt conditions and kernel disposal
   * <li>error management
   * </ul>
   *
   * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/01/18 16:23:54 $
   * @see DefaultBlock
   */
  
  public class DefaultBlockLoader extends AbstractLogEnabled implements Contextualizable, Initializable, Disposable, BlockLoader
  {
      //==============================================================
      // static
      //==============================================================
  
      /**
       * The logging manager that we use to construct logging catagories
       * and logging channels.
       */
      private static LoggingManager LOGGING;
  
      protected static final String BLOCK_XML_ENTRY = "BLOCK-INF/block.xml";
  
      protected static final XMLContainerCreator CREATOR = new XMLContainerCreator();
  
      private static final XMLProfileCreator BUILDER = new XMLProfileCreator();
  
     /**
      * 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( "configuration", BlockLoader.class.getName() );
          }
          return ConfigurationUtil.matchFirstOccurance( config, "configuration", "target", name );
      }
  
      //==============================================================
      // state
      //==============================================================
  
     /**
      * The root registry.
      */
      private Registry m_registry;
      
     /**
      * The application home directory.
      */
      private File m_home;
  
      /**
       * The assembly engine.
       */
      private EngineClassLoader m_engine;
  
      /**
       * The system context.
       */
      private Locator m_system;
  
      //==============================================================
      // Contextualizable
      //==============================================================
  
     /**
      * Contextualization of the block loader during which the root 
      * engine and registry along with the system context.
      */
      public void contextualize( Locator context ) throws ContextException
      {
          m_engine = (EngineClassLoader) context.get( "urn:assembly:engine" );
          m_registry = (Registry) context.get( "urn:assembly:registry" );
          m_system = (Locator) context.get( "urn:assembly:system-context" );
          m_home = (File) m_system.get( "urn:assembly:home" );
      }
  
      //==============================================================
      // Initializable
      //==============================================================
  
      public void initialize() throws Exception
      {
          if( m_engine == null )
          {
              throw new IllegalStateException( "contextualization" );
          }
      }
  
      //==============================================================
      // Disposable
      //==============================================================
  
     /**
      * Disposal of the loader and related resources.
      */
      public void dispose()
      {
          m_engine = null;
          m_registry = null;
          m_system = null;
          m_home = null;
      }
  
      //==============================================================
      // BlockLoader
      //==============================================================
  
     /**
      * Load all of the blocks declared in the supplied configuration.
      * The configuration contains an arbitary number of "block" elements
      * each containing the name and path of a jar file to be loaded together
      * with client supplied configuration data.
      *
      * @param conf the configuration loaded from the blocks.xml file
      * @param system the system context
      * @return the set of blocks
      */
      public Block[] createBlocks( Configuration conf )
        throws BlockException
      {
          Configuration[] configs = conf.getChildren("block");
          getLogger().info("block count = " + configs.length );
  
          ArrayList blocks = new ArrayList();
          for( int i=0; i<configs.length; i++ )
          {
              Configuration config = configs[i];
              String name = config.getAttribute( "name", null );
              boolean enabled = config.getAttributeAsBoolean( "enabled", true );
              if( enabled )
              {
                  try
                  {
                      Block block = loadPhysicalBlock( config, m_system );
                      blocks.add( block );
                  }
                  catch( Throwable e )
                  {
                      final String error = 
                        "Error during block deployment for block: " + (i+1) + " [" + name + "]";
                      throw new BlockException( error, e );
                  }
              }
          }
          return (Block[]) blocks.toArray( new Block[0] );
      }
  
      //==============================================================
      // internals
      //==============================================================
  
     /**
      * Load a single block defintion.  The defintion is a configuration
      * element named "block" that either:
      * <ul>
      * <li>a reference to a block configuration file</li>
      * <li>a reference to a package black in the form of a jar file</li>
      * </ul>
      * 
      * The block name is defined by the block name attribute declared under the 
      * block element in the blocks.xml configuration.  In the case of the 
      * configuration based block defintion, the configuration is derived from a 
      * and explicit file reference.  In the case of a packaged block, the 
      * configuration is resolved from a packaged xmml file name 
      * /BLOCK-INFO/block.xml with a jar file.
      * 
      *
      * @param config the block declaration
      * @param system the system context
      * @return the block
      * @exception Exception if a block loading error occurs
      */
      private Block loadPhysicalBlock( Configuration config, Context system )
        throws BlockException
      {
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug( "block configuration: \n" + ConfigurationUtil.list( config ) );
          }
  
          //
          // get the basic information for the block declaration
          // in the block.xml file
          //
  
          URL url = null;
          Configuration base;
          String name = null;
  
          try
          {
               name = config.getAttribute( "name" );
          }
          catch( ConfigurationException e )
          {
               final String error = 
                 "Block defintion is missing the required name attribute:"
                 + ConfigurationUtil.list( config );
               throw new BlockException( error, e );
          }
  
          Logger logger = getLogger().getChildLogger( name );
  
          try
          {
              String string = config.getAttribute( "url", null );
              if( string != null )
              {
                  if( string.indexOf(":") > -1 )
                  {
                      // its a URL
                      if( string.toLowerCase().startsWith("file:") )
                      {
                          // its a file
                          String filename = string.substring(7);
                          File file = new File( m_home, filename ).getCanonicalFile();
                          getLogger().info( "FILE: " + file );
                      }
                      else
                      {
                          URL myURL = new URL( string );
                          getLogger().info( "URL: " + myURL );
                          Object object = myURL.getContent();
                          getLogger().info( "OBJECT: " + object );
                      }
                  }
              }
              if( string != null )
              {
              }
          }
          catch( Throwable e )
          {
              getLogger().error( "URL ERROR: " + e.toString() );
          }
  
          if( config.getAttribute( "path", null ) != null )
          {
  
              //
              // It is a packaged block within a jar file.
              //
  
              String path = config.getAttribute("path", null );
              if( getLogger().isDebugEnabled() )
              {
                  logger.debug( "[" + path + "] as [" + name + "]");
              }
  
              //
              // load the jar file referenced by the block declaration and get its 
              // manifest
              //
  
              try
              {
                  url = new File( m_home, path ).getCanonicalFile().toURL();
                  JarFile jar = getJarFile( url );
  
                  //
                  // get the blocks packaged configuration and use that to establish 
                  // the engine to be supplied to the block
                  //
  
                  base = getBlockConfiguration( jar );
              }
              catch( Throwable e )
              {
                  final String error = 
                    "Unable to resolve package block description on path: " + path;
                  throw new BlockException( error, e );
              }
          }
          else
          {
              // 
              // The block configuration is declared in an external file.
              //
  
              String src = config.getAttribute( "src", null );
              if( src == null )
              {
                  final String error = 
                    "Block does not contain a 'src' or 'path' attribute: \n"
                    + ConfigurationUtil.list( config );
                  throw new BlockException( error );
              }
  
              File file = new File( m_home, src );
              DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
              InputStream is = null;
              try
              {
                  is = new FileInputStream( file );
              }
              catch( IOException ie )
              {
                  final String error = 
                    "Unable to load external block definition from the file: " + file;
                  throw new BlockException( error, ie );
              }
              if( is == null )
              {
                  throw new BlockException(
                     "Could not load the configuration resource \"" + file  + "\"" );
              }
  
              try
              {
                  base = builder.build( is );
              }
              catch( Throwable e )
              {
                  final String error = 
                    "Source related error while load external block definition from file: " + file;
                  throw new BlockException( error, e );
              }
          }
  
          Configuration implementation = base.getChild( "implementation" );
          Configuration engineConfig = implementation.getChild( "engine" );
          EngineClassLoader engine = null;
  
          try
          {
              engine = createChildEngine( m_engine, m_home, engineConfig, url, logger );
          }
          catch( Throwable ee )
          {
              final String error = 
                "Could not construct secondary engine for block: " + name;
              throw new BlockException( error, ee );
          }
  
          //
          // create an appliance context and add to it a registry derived from the 
          // parent registry
          //
  
          String partition = name + Container.PATH_SEPERATOR;
          ContainerDescriptor descriptor = createContainerDescriptor( name, engine, implementation );
          Registry registry = null;
  
          try
          {
              registry = m_registry.createChild( name );
          }
          catch( Throwable ee )
          {
              final String error = 
                "Could not construct secondary registry for block: " + name;
              throw new BlockException( error, ee );
          }
  
          List list = createChildBlocks( engine, registry, partition, implementation, config, logger );
          return createBlock( engine, list, descriptor, name, registry, Container.PATH_SEPERATOR, config ); 
      }
  
     /**
      * Create a descriptor of a container populated with the defintintion
      * of the components it is managing.
      * 
      * @param name the container name
      * @param engine the classloader to use
      * @param config the confuration describing the containment scenario
      * @return the container descriptor
      */
      private ContainerDescriptor createContainerDescriptor( 
        String name, EngineClassLoader engine, Configuration config )
        throws BlockException
      {
          String classname = config.getAttribute( "class", DefaultContainer.class.getName() );
          Type type = null;
          try
          {
              type = engine.getRepository().getTypeManager().getType( classname );
          }
          catch( UnknownTypeException ute )
          {
              final String error = 
                "Container definition references an unknown type: " + classname;
              throw new BlockException( error );
          }
          catch( Throwable e )
          {
              final String error = 
                "Internal error while resolving container: " + name
                + " using class: " + classname;
              throw new BlockException( error, e );
          }
  
          ContainerDescriptor descriptor = null;
          try
          {
              descriptor = CREATOR.createContainerDescriptor( type, config, name );
              Configuration[] children = config.getChildren( "appliance" );
              for( int i=0; i<children.length; i++ )
              {
                  Profile profile = createProfile( name, engine, children[i] );
                  engine.getRepository().getProfileManager().addProfile( profile );
                  descriptor.addComponent( profile );
              }
              return descriptor;
          }
          catch( Exception e )
          {
              final String error = 
                "Cannot build the container descriptor: " + name;
              throw new BlockException( error, e );
          }
      }
  
  
     /**
      * Creation of a set of child blocks relative to a set of parent parameters.
      * 
      * @param engine the parent classloader
      * @param registry the parent registry
      * @param partition the partition to be applied to the child containers
      * @param config a confiuration containing a set of subsidiary container elements
      * @param logger the logger from which child loggers shall be created
      * @return a list of appliance instances each representing a container container
      */
      private List createChildBlocks( 
        EngineClassLoader engine, Registry registry, String partition,
        Configuration config, Configuration custom, Logger logger )
        throws BlockException
      {
          List list = new ArrayList();
          Configuration[] children = config.getChildren( "container" );
  
          for( int i=0; i<children.length; i++ )
          {
              Configuration child = children[i];
  
              //
              // 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 name attribute:\n"
                    + ConfigurationUtil.list( child );
                  throw new BlockException( error );
              }
              Logger log = logger.getChildLogger( name );
  
              //
              // 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 configuration error.";
                  throw new BlockException( error, ce );
              }
              catch( EngineException ce )
              {
                  final String error = 
                    "Cannot create a subsidiary container due to a engine 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 block.
      *
      * @param engine the containers classloader
      * @param registry the component registry to apply to the container
      * @param partition the partition to assigne to the container
      * @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 block
      * @exception BlockException if an error occurs during creation of the block
      */
      private Block createContainmentBlock( 
        EngineClassLoader engine, Registry registry, String partition, String name, 
        Configuration config, Configuration custom, Logger logger )
        throws BlockException
      {
          String subPartition = partition + name + Container.PATH_SEPERATOR;
          List list = createChildBlocks( 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 - the map
          // contains the context entries that will be provided to the 
          // container (supplimented by entries added by the block 
          // implementation) and the context object is the context
          // to be applied to the block.
          //
  
          Map map = new Hashtable();
          map.put("urn:merlin:container.descriptor", descriptor ); 
  
          DefaultApplianceContext context = new DefaultApplianceContext( descriptor );
  
          context.setName( name );
          context.setDeploymentContext( map );
          context.setPartitionName( partition );
          context.setApplianceClassname( DefaultBlock.class.getName() );
          context.put("urn:merlin:container.descriptor", descriptor ); 
          context.put("urn:merlin:container.registry", registry );
          context.put("urn:merlin:container.configuration", target );
          context.put("urn:merlin:container.containers", containers );
          context.makeReadOnly();
  
          //
          // create the containement appliance
          //
  
          try
          {
              getLogger().debug( "creating block with context: " + context );
              return (Block) engine.createAppliance( context, false, false );
          }
          catch( Throwable e )
          {
              final String error = 
                "Unable to create block: " + partition + name;
              throw new BlockException( error, e );
          }
      }
  
      private JarFile getJarFile( URL url ) throws MalformedURLException
      {
          URL xurl;
  
          String protocol = url.getProtocol();
          if( protocol.equals("jar") )
          {
              xurl = url;
          }
          else
          {
              xurl = new URL( "jar:" + url.toString() + "!/" );
          }
  
          try
          {
              JarURLConnection connection = (JarURLConnection) xurl.openConnection();
              return connection.getJarFile();
          }
          catch( Throwable ioe )
          {
              final String error = 
                "Unexpected Exception while reading jar file from url: " + xurl + " cause: " + ioe;
              throw new RuntimeException( error );
          }
      }
  
      private Configuration getBlockConfiguration( JarFile jar ) throws Exception
      {
          if( jar == null )
          {
              throw new NullPointerException( "jar" );
          }
  
          ZipEntry entry = jar.getEntry( BLOCK_XML_ENTRY );
          if( entry == null )
          {
              if( getLogger().isDebugEnabled() )
              {
                  final String msg = "No block configuration - applying defaults.";
                  getLogger().debug( msg );
              }
              return new DefaultConfiguration( "block", jar.getName() );
          }
  
          try
          {
              DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
              InputStream is = jar.getInputStream( entry );
              if( is == null )
              {
                  throw new RuntimeException(
                      "Could not load the configuration resource \"" + jar.getName() + "\"" );
              }
              return builder.build( is );
          }
          catch( Throwable e )
          {
              final String error = "Unable to create configuration from jar file: " + jar.getName();
              throw new BlockException( error, e );
          }
      }
  
      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
          {
              Profile profile = BUILDER.createProfile( type, config );
              boolean policy = getActivationPolicy( config );
              profile.setActivationPolicy( policy );
              return profile;
          }
          catch( Throwable e )
          {
              final String error =
                "Root container in block: " + name 
                + " contains a problamatic profile: "
                + classname;
              throw new ContainerException( error, e );
          }
      }
  
      private boolean getActivationPolicy( Configuration config )
      {
          final String value = config.getAttribute( "activation", null );
          if( value == null )
          {
              return false;
          }
          final String string = value.toLowerCase().trim();
          if( string.equals( "startup" ) )
          {
              return true;
          }
          return string.equals( "true" );
      }
  
  
      protected EngineClassLoader createChildEngine( 
        EngineClassLoader parent, File home, Configuration config, Logger logger ) 
        throws EngineException, ConfigurationException
      {
          return createChildEngine( parent, home, config, null, logger );
      }
  
      protected EngineClassLoader createChildEngine( 
        EngineClassLoader parent, File home, Configuration config, URL url, Logger logger ) 
        throws EngineException, ConfigurationException
      {
          LibraryDescriptor extensions;
          try
          {
              extensions =
                CREATOR.createLibraryDescriptor( 
                  config.getChild( "library" ) );
          }
          catch( Throwable e )
          {
              final String error = "Bad library descriptor in configuration: \n" 
                + ConfigurationUtil.list( config );
              throw new EngineException( error, e );
          }
  
          ClasspathDescriptor classpath;
          try
          {
              classpath =
                CREATOR.createClasspathDescriptor( 
                  config.getChild( "classpath" ) );
          }
          catch( Throwable e )
          {
              final String error = "Bad classpath descriptor.";
              throw new EngineException( error, e );
          }
  
          try
          {
              EngineClassLoader engine;
              if( url != null )
              {
                  engine = new EngineClassLoader( new URL[]{ url }, parent );
              }
              else
              {
                  engine = new EngineClassLoader( parent );
              }
              engine.enableLogging( logger );
              DefaultLocator context = new DefaultLocator();
              context.put( "urn:assembly: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 EngineException( error, e );
          }
      }
  }
  
  
  
  1.1                  avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/block/impl/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>The impl package provides the implementation of the composite component block abstraction withing which 
  packaged component heirachies represent functional application building block.</p> 
  </body>
  
  
  
  
  1.15      +30 -9     avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/DefaultContainer.java
  
  Index: DefaultContainer.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/container/DefaultContainer.java,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- DefaultContainer.java	15 Jan 2003 09:14:51 -0000	1.14
  +++ DefaultContainer.java	18 Jan 2003 16:23:54 -0000	1.15
  @@ -393,6 +393,22 @@
                   {
                       Object object = appliance.resolve( this );
                       m_components.put( appliance, object );
  +                    if( !appliance.getStartupPolicy() )
  +                    {
  +                        if( object instanceof Startable )
  +                        {
  +                            try
  +                            {
  +                                ((Startable)object).start();
  +                            }
  +                            catch( Throwable e )
  +                            {
  +                                final String error =
  +                                  "Error during startup of a componet: " + appliance;
  +                                throw new ContainerException( error, e );
  +                            }
  +                        }
  +                    }
                   }
                   catch( Throwable e )
                   {
  @@ -441,18 +457,23 @@
           for( int i=0; i<appliances.length; i++ )
           {
               Appliance appliance = appliances[i];
  -            Object object = m_components.get( appliance );
  -            if( object != null )
  +            if( !appliance.getStartupPolicy() )
               {
  -                if( object instanceof Startable )
  +                // container is handling shutdown
  +
  +                Object object = m_components.get( appliance );
  +                if( object != null )
                   {
  -                    if( getLogger().isDebugEnabled() )
  +                    if( object instanceof Startable )
                       {
  -                        final String message =
  -                          "stopping: " + appliance;
  -                        getLogger().debug( message );
  +                        if( getLogger().isDebugEnabled() )
  +                        {
  +                           final String message =
  +                             "stopping: " + appliance;
  +                           getLogger().debug( message );
  +                        }
  +                        ((Startable)object).stop();
                       }
  -                    ((Startable)object).stop();
                   }
                   m_components.remove( appliance );
               }
  
  
  
  1.29      +36 -457   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.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- DefaultKernel.java	18 Jan 2003 02:11:43 -0000	1.28
  +++ DefaultKernel.java	18 Jan 2003 16:23:54 -0000	1.29
  @@ -98,11 +98,11 @@
   import org.apache.avalon.framework.context.ContextException;
   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.block.BlockLoader;
  +import org.apache.avalon.merlin.block.impl.DefaultBlockLoader;
   import org.apache.avalon.merlin.block.BlockException;
   import org.apache.avalon.merlin.container.builder.XMLContainerCreator;
   import org.apache.avalon.merlin.container.ContainerDescriptor;
  -import org.apache.avalon.merlin.container.ContainerLoader;
   import org.apache.avalon.merlin.container.Container;
   import org.apache.avalon.merlin.container.ContainerException;
   import org.apache.avalon.merlin.container.DefaultContainer;
  @@ -132,10 +132,10 @@
    *
    * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
    * @version $Revision$ $Date$
  - * @see DefaultBlock
  + * @see Block
    */
   
  -public class DefaultKernel extends ContainerLoader implements Kernel, Contextualizable, Initializable, Startable, Disposable
  +public class DefaultKernel extends AbstractLogEnabled implements Kernel, Contextualizable, Initializable, Startable, Disposable
   {
       //==============================================================
       // static
  @@ -149,6 +149,7 @@
   
       protected static final String BLOCK_XML_ENTRY = "BLOCK-INF/block.xml";
   
  +    protected static final XMLContainerCreator CREATOR = new XMLContainerCreator();
   
      /**
       * Return a configuration element relative to a target name.  The implementation 
  @@ -372,19 +373,36 @@
   
           if( getLogger().isInfoEnabled() )
           {
  -            getLogger().info( "commencing block construction phase" );
  +            getLogger().info( "\n\ncommencing block construction phase\n" );
           }
   
           Block[] blocks;
  +
           try
           {
  -            Context system = getSystemContext();
  -            blocks = loadPhysicalBlocks( m_configuration, system );
  +            DefaultBlockLoader loader = new DefaultBlockLoader();
  +            loader.enableLogging( getLogger().getChildLogger( "loader" ) );
  +            DefaultLocator context = new DefaultLocator();
  +            context.put( "urn:assembly:engine", m_engine );
  +            context.put( "urn:assembly:registry", m_registry );
  +            context.put( "urn:assembly:system-context", getSystemContext() );
  +            context.makeReadOnly();
  +            loader.contextualize( context );
  +            loader.initialize();
  +
  +            blocks = loader.createBlocks( m_configuration );
  +
               for( int i=0; i<blocks.length; i++ )
               {
                   Block block = blocks[i];
                   m_blocks.add( block );
  +                if( getLogger().isInfoEnabled() )
  +                {
  +                    getLogger().info( block.toString() );
  +                }
               }
  +
  +            loader.dispose();
           }
           catch( Throwable e )
           {
  @@ -403,7 +421,7 @@
   
           if( getLogger().isInfoEnabled() )
           {
  -            getLogger().info( "commencing structural assembly phase" );
  +            getLogger().info( "\n\ncommencing structural assembly phase\n" );
           }
   
           for( int i=0; i<blocks.length; i++ )
  @@ -455,12 +473,9 @@
       */
       public void start() throws Exception 
       {
  -        if( getLogger() != null ) 
  +        if( getLogger().isInfoEnabled() )
           {
  -            if( getLogger().isInfoEnabled() )
  -            {
  -                getLogger().info( "commencing startup phase" );
  -            }
  +            getLogger().info( "\n\ncommencing deployment phase\n" );
           }
   
           Iterator iterator = m_blocks.iterator();
  @@ -469,6 +484,11 @@
               Block block = (Block) iterator.next();
               block.deploy();
           }
  +
  +        if( getLogger().isInfoEnabled() )
  +        {
  +            getLogger().info( "\n\ndeployment complete\n" );
  +        }
       }
   
      /**
  @@ -482,7 +502,7 @@
           {
               if( getLogger().isInfoEnabled() )
               {
  -                getLogger().info( "decommissioning" );
  +                getLogger().info( "\n\ncommencing decommissioning phase\n" );
               }
           }
   
  @@ -507,7 +527,7 @@
           {
               if( getLogger().isInfoEnabled() )
               {
  -                getLogger().info( "termination" );
  +                getLogger().info( "\n\ncommencing termination phase\n" );
               }
           }
   
  @@ -528,387 +548,9 @@
       }
   
       //==============================================================
  -    // 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
       //==============================================================
   
  -   /**
  -    * Load all of the blocks declared in the block.xml configuration.
  -    * The configuration contains an arbitary number of "block" elements
  -    * each containing the name and path of a jar file to be loaded together
  -    * with client supplied configuration data.
  -    *
  -    * @param conf the configuration loaded from the blocks.xml file
  -    * @param system the system context
  -    * @return the set of blocks
  -    */
  -    private Block[] loadPhysicalBlocks( Configuration conf, Context system )
  -      throws Exception
  -    {
  -        Configuration[] configs = conf.getChildren("block");
  -        getLogger().info("block count = " + configs.length );
  -
  -        ArrayList blocks = new ArrayList();
  -        for( int i=0; i<configs.length; i++ )
  -        {
  -            Configuration config = configs[i];
  -            String name = config.getAttribute( "name", null );
  -            boolean enabled = config.getAttributeAsBoolean( "enabled", true );
  -            if( enabled )
  -            {
  -                try
  -                {
  -                    Block block = loadPhysicalBlock( config, system );
  -                    blocks.add( block );
  -                }
  -                catch( Throwable e )
  -                {
  -                    final String error = 
  -                      "Error during block deployment for block: " + (i+1) + " [" + name + "]";
  -                    throw new BlockException( error, e );
  -                }
  -            }
  -        }
  -        return (Block[]) blocks.toArray( new Block[0] );
  -    }
  -
  -   /**
  -    * Load a single block defintion.  The defintion is a configuration
  -    * element named "block" that either:
  -    * <ul>
  -    * <li>a reference to a block configuration file</li>
  -    * <li>a reference to a package black in the form of a jar file</li>
  -    * </ul>
  -    * 
  -    * The block name is defined by the block name attribute declared under the 
  -    * block element in the blocks.xml configuration.  In the case of the 
  -    * configuration based block defintion, the configuration is derived from a 
  -    * and explicit file reference.  In the case of a packaged block, the 
  -    * configuration is resolved from a packaged xmml file name 
  -    * /BLOCK-INFO/block.xml with a jar file.
  -    * 
  -    *
  -    * @param config the block declaration
  -    * @param system the system context
  -    * @return the block
  -    * @exception Exception if a block loading error occurs
  -    */
  -    private Block loadPhysicalBlock( Configuration config, Context system )
  -      throws Exception
  -    {
  -        if( getLogger().isDebugEnabled() )
  -        {
  -            getLogger().debug( "block configuration: \n" + ConfigurationUtil.list( config ) );
  -        }
  -
  -        //
  -        // get the basic information for the block declaration
  -        // in the block.xml file
  -        //
  -
  -        URL url = null;
  -        Configuration base;
  -        String name = config.getAttribute( "name" );
  -        Logger logger = getLogger().getChildLogger( name );
  -        if( config.getAttribute( "path", null ) != null )
  -        {
  -
  -            //
  -            // It is a packaged block within a jar file.
  -            //
  -
  -            String path = config.getAttribute("path");
  -            if( getLogger().isDebugEnabled() )
  -            {
  -                logger.debug( "[" + path + "] as [" + name + "]");
  -            }
  -
  -            //
  -            // load the jar file referenced by the block declaration and get its 
  -            // manifest
  -            //
  -
  -            url = new File( m_home, path ).getCanonicalFile().toURL();
  -            JarFile jar = getJarFile( url );
  -
  -            //
  -            // get the blocks packaged configuration and use that to establish 
  -            // the engine to be supplied to the block
  -            //
  -
  -            base = getBlockConfiguration( jar );
  -        }
  -        else
  -        {
  -            // 
  -            // The block configuration is declared in an external file.
  -            //
  -
  -            String src = config.getAttribute( "src", null );
  -            if( src == null )
  -            {
  -                final String error = 
  -                  "Block does not contain a 'src' or 'path' attribute: \n"
  -                  + ConfigurationUtil.list( config );
  -                throw new BlockException( error );
  -            }
  -
  -            File file = new File( m_home, src );
  -            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
  -            InputStream is = new FileInputStream( file );
  -            if( is == null )
  -            {
  -                throw new BlockException(
  -                    "Could not load the configuration resource \"" + file  + "\"" );
  -            }
  -            base = builder.build( is );
  -        }
  -
  -        Configuration implementation = base.getChild( "implementation" );
  -
  -        Configuration engineConfig = implementation.getChild( "engine" );
  -        EngineClassLoader engine = createChildEngine( m_engine, m_home, engineConfig, url, logger );
  -
  -        //
  -        // create an appliance context and add to it a registry derived from the 
  -        // parent registry
  -        //
  -
  -        String partition = name + Container.PATH_SEPERATOR;
  -        ContainerDescriptor descriptor = createContainerDescriptor( name, engine, implementation );
  -        Registry registry = m_registry.createChild( name );
  -
  -        List list = createChildBlocks( engine, registry, partition, implementation, config, logger );
  -
  -        //
  -        // create the appliance context for the container
  -        //
  -
  -        return createBlock( engine, list, descriptor, name, registry, Container.PATH_SEPERATOR, config ); 
  -    }
  -
  -   /**
  -    * Create a descriptor of a container populated with the defintintion
  -    * of the components it is managing.
  -    * 
  -    * @param name the container name
  -    * @param engine the classloader to use
  -    * @param config the confuration describing the containment scenario
  -    * @return the container descriptor
  -    */
  -    private ContainerDescriptor createContainerDescriptor( 
  -      String name, EngineClassLoader engine, Configuration config )
  -      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[] children = config.getChildren( "appliance" );
  -        for( int i=0; i<children.length; i++ )
  -        {
  -            Profile profile = createProfile( name, engine, children[i] );
  -            engine.getRepository().getProfileManager().addProfile( profile );
  -            descriptor.addComponent( profile );
  -        }
  -        return descriptor;
  -    }
  -
  -   /**
  -    * Creation of a set of child blocks relative to a set of parent parameters.
  -    * 
  -    * @param engine the parent classloader
  -    * @param registry the parent registry
  -    * @param partition the partition to be applied to the child containers
  -    * @param config a confiuration containing a set of subsidiary container elements
  -    * @param logger the logger from which child loggers shall be created
  -    * @return a list of appliance instances each representing a container container
  -    */
  -    private List createChildBlocks( 
  -      EngineClassLoader engine, Registry registry, String partition,
  -      Configuration config, Configuration custom, Logger logger )
  -      throws BlockException
  -    {
  -        List list = new ArrayList();
  -        Configuration[] children = config.getChildren( "container" );
  -
  -        for( int i=0; i<children.length; i++ )
  -        {
  -            Configuration child = children[i];
  -
  -            //
  -            // 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 name attribute:\n"
  -                  + ConfigurationUtil.list( child );
  -                throw new BlockException( error );
  -            }
  -            Logger log = logger.getChildLogger( name );
  -
  -            //
  -            // 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 block.
  -    *
  -    * @param engine the containers classloader
  -    * @param registry the component registry to apply to the container
  -    * @param partition the partition to assigne to the container
  -    * @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 block
  -    * @exception BlockException if an error occurs during creation of the block
  -    */
  -    private Block createContainmentBlock( 
  -      EngineClassLoader engine, Registry registry, String partition, String name, 
  -      Configuration config, Configuration custom, Logger logger )
  -      throws BlockException
  -    {
  -        String subPartition = partition + name + Container.PATH_SEPERATOR;
  -        List list = createChildBlocks( 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 - the map
  -        // contains the context entries that will be provided to the 
  -        // container (supplimented by entries added by the block 
  -        // implementation) and the context object is the context
  -        // to be applied to the block.
  -        //
  -
  -        Map map = new Hashtable();
  -        map.put("urn:merlin:container.descriptor", descriptor ); 
  -
  -        DefaultApplianceContext context = new DefaultApplianceContext( descriptor );
  -
  -        context.setName( name );
  -        context.setDeploymentContext( map );
  -        context.setPartitionName( partition );
  -        context.setApplianceClassname( DefaultBlock.class.getName() );
  -        context.put("urn:merlin:container.descriptor", descriptor ); 
  -        context.put("urn:merlin:container.registry", registry );
  -        context.put("urn:merlin:container.configuration", target );
  -        context.put("urn:merlin:container.containers", containers );
  -        context.makeReadOnly();
  -
  -        //
  -        // create the containement appliance
  -        //
  -
  -        try
  -        {
  -            getLogger().debug( "creating block with context: " + context );
  -            return (Block) engine.createAppliance( context, false, false );
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error = 
  -              "Unable to create block: " + partition + name;
  -            throw new BlockException( error, e );
  -        }
  -    }
  -
       private LoggingManager bootstrapLoggingManager( String root ) throws Exception
       {
           if( m_kernelConfig == null )
  @@ -1043,69 +685,6 @@
           {
               final String error = "Unable to create configuration from file: " + file;
               throw new ConfigurationException( error, e );
  -        }
  -    }
  -
  -    private JarFile getJarFile( URL url ) throws MalformedURLException
  -    {
  -        URL xurl;
  -
  -        String protocol = url.getProtocol();
  -        if( protocol.equals("jar") )
  -        {
  -            xurl = url;
  -        }
  -        else
  -        {
  -            xurl = new URL( "jar:" + url.toString() + "!/" );
  -        }
  -
  -        try
  -        {
  -            JarURLConnection connection = (JarURLConnection) xurl.openConnection();
  -            return connection.getJarFile();
  -        }
  -        catch( Throwable ioe )
  -        {
  -            final String error = 
  -              "Unexpected Exception while reading jar file from url: " + xurl + " cause: " + ioe;
  -            throw new RuntimeException( error );
  -        }
  -    }
  -
  -    private Configuration getBlockConfiguration( JarFile jar ) throws Exception
  -    {
  -        if( jar == null )
  -        {
  -            throw new NullPointerException( "jar" );
  -        }
  -
  -        ZipEntry entry = jar.getEntry( BLOCK_XML_ENTRY );
  -        if( entry == null )
  -        {
  -            if( getLogger().isDebugEnabled() )
  -            {
  -                final String msg = "No block configuration - applying defaults.";
  -                getLogger().debug( msg );
  -            }
  -            return new DefaultConfiguration( "block", jar.getName() );
  -        }
  -
  -        try
  -        {
  -            DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
  -            InputStream is = jar.getInputStream( entry );
  -            if( is == null )
  -            {
  -                throw new RuntimeException(
  -                    "Could not load the configuration resource \"" + jar.getName() + "\"" );
  -            }
  -            return builder.build( is );
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error = "Unable to create configuration from jar file: " + jar.getName();
  -            throw new BlockException( error, e );
           }
       }
   }
  
  
  
  1.4       +0 -1      avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/KernelLoader.java
  
  Index: KernelLoader.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/src/java/org/apache/avalon/merlin/kernel/KernelLoader.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- KernelLoader.java	15 Jan 2003 09:14:51 -0000	1.3
  +++ KernelLoader.java	18 Jan 2003 16:23:54 -0000	1.4
  @@ -30,7 +30,6 @@
   import org.apache.avalon.framework.context.DefaultContext;
   import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.merlin.block.Block;
  -import org.apache.avalon.merlin.block.DefaultBlock;
   import org.apache.avalon.merlin.block.BlockException;
   import org.apache.avalon.merlin.kernel.Kernel;
   import org.apache.avalon.merlin.kernel.DefaultKernel;
  
  
  
  1.6       +0 -1      avalon-sandbox/merlin/src/test/org/apache/avalon/merlin/kernel/KernelTestCase.java
  
  Index: KernelTestCase.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/src/test/org/apache/avalon/merlin/kernel/KernelTestCase.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- KernelTestCase.java	28 Dec 2002 08:06:44 -0000	1.5
  +++ KernelTestCase.java	18 Jan 2003 16:23:55 -0000	1.6
  @@ -31,7 +31,6 @@
   import org.apache.avalon.framework.context.Contextualizable;
   import org.apache.avalon.framework.context.ContextException;
   import org.apache.avalon.merlin.block.Block;
  -import org.apache.avalon.merlin.block.DefaultBlock;
   import org.apache.avalon.merlin.kernel.DefaultKernel;
   import org.apache.avalon.merlin.kernel.KernelException;
   import org.apache.avalon.assembly.util.ExceptionHelper;
  
  
  

--
To unsubscribe, e-mail:   <mailto:avalon-cvs-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-cvs-help@jakarta.apache.org>


Mime
View raw message