mcconnell    2002/12/27 17:34:04

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

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

Reply via email to