You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by mc...@apache.org on 2002/07/01 06:27:16 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/doc-files registry.gif

mcconnell    2002/06/30 21:27:16

  Added:       assembly .cvsignore build.properties build.xml
               assembly/demo/src/etc demo.mf
               assembly/demo/src/java/org/apache/excalibur/playground
                        BasicComponent.java BasicComponent.xinfo
                        BasicService.java ComplexComponent.java
                        ComplexComponent.xinfo InvalidComponent.java
                        InvalidComponent.xinfo SimpleComponent.java
                        SimpleComponent.xinfo SimpleService.java
                        TerminalComponent.java TerminalComponent.xinfo
               assembly/lib avalon-framework.jar
                        excalibur-configuration-1.0.jar
                        excalibur-containerkit-1.0.jar
                        excalibur-extension-1.0a.jar excalibur-i18n-1.0.jar
                        excalibur-io-1.1.jar excalibur-util-1.0.jar
                        logkit.jar
               assembly/src .cvsignore
               assembly/src/etc profile.xml project.mf
               assembly/src/java/org/apache/excalibur/merlin/registry
                        AssemblyException.java
                        AssemblyRuntimeException.java
                        ComponentDefinition.java ComponentType.java
                        DefaultClassLoader.java DefaultProfile.java
                        DefaultRegistry.java DefaultRegistry.xinfo
                        Fileset.java Main.java Profile.java
                        ProfileException.java ProfileRuntimeException.java
                        Registry.java RegistryException.java
                        RegistryRuntimeException.java Resources.properties
                        Selector.java ServiceRegistry.java
                        UnresolvedProviderException.java package.html
               assembly/src/java/org/apache/excalibur/merlin/registry/doc-files
                        registry.gif
  Log:
  first commit of the Merlin Registry service
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/assembly/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  local.properties
  build
  dist
  checkstyle.cache
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/build.properties
  
  Index: build.properties
  ===================================================================
  
  #
  # This file is read in by the build.xml file.  
  #
  project.title=Merlin II
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/build.xml
  
  Index: build.xml
  ===================================================================
  
  <!-- 
  Copyright 2001-2002 OSM SARL, All Rights Reserved.
  -->
  
  <project name="assembly" default="help" basedir=".">
  
    <property file="local.properties"/>
    <property file="build.properties"/>
  
    <target name="help" >
      <echo>
  
        Description
        -----------
  
        ${project.title}
  
        General Targets:
        ----------------
  
        all              - clean, build and dist
        build            - invokes the general build target
        javadoc          - javadoc API generation
        dist             - executes build, javadoc and support file creation
        clean            - destroy the build directory
        test             - run the component
        
      </echo>
    </target>
  
    <property name="VERSION" value="${MAJOR}.${MINOR}.${MICRO}"/>
  
    <property name="apps.path" value="../../jakarta-avalon-apps" />
    <property name="excalibur.path" value="../../jakarta-avalon-excalibur" />
    <property name="containerkit.path" value="${excalibur.path}/containerkit" />
  
    <property name="lib" value="lib" />
    <property name="src" value="src" />
    <property name="etc" value="${src}/etc" />
    <property name="build"  value="build" />
    <property name="dist"  value="dist" />
  
    <property name="javadoc.root.path"  value="${dist}/javadoc" />
    <property name="avalon.href"  value="http://jakarta.apache.org/avalon/api/" />
    <property name="jdk.href"  value="http://java.sun.com/j2se/1.4/docs/api/" />
    <property name="containerkit.href"  value="${containerkit.path}/dist/docs/api" />
    <property name="overview.html" value="${etc}/overview.html" />
    <property name="project.manifest" value="project.mf" />
  
    <!-- classpath -->
  
    <path id="project.classpath">
        <fileset dir="${lib}">
          <include name="*.jar" />
        </fileset>
    </path>
  
    <!-- MAIN TARGETS -->
  
    <target name="all" depends="clean,dist,javadoc"/>
    <target name="dist" depends="build"/>
  
    <target name="clean">
       <delete dir="${build}"/>
       <delete dir="${dist}"/>
    </target>
  
    <!-- PREPARE -->
  
    <target name="prepare"  >
      <mkdir dir="${build}" />
      <mkdir dir="${build}" />
      <mkdir dir="${dist}" />
    </target>
  
    <!-- BLOCK -->
  
    <target name="context" depends="prepare">
      <mkdir dir="dist"/>
      <uptodate property="uptodate" targetfile="${dist}/${ant.project.name}.jar">
        <srcfiles dir="${src}/java">
           <include name="**/*.*"/>
        </srcfiles>
        <srcfiles dir="${etc}">
           <include name="${project.manifest}"/>
        </srcfiles>
      </uptodate>
    </target>
  
    <target name="build" depends="context,demo.build" unless="uptodate" >
        <echo message="Building Block"/>
        <mkdir dir="${build}/main"/>
        <javac debug="off" destdir="${build}/main" deprecation="true">
          <classpath>
  	    <path refid="project.classpath" />
  	  </classpath>
          <src path="${src}/java" />
        </javac>
        <copy todir="${build}/main">
          <fileset dir="${src}/java">
            <include name="**/*.xinfo"/>
            <include name="**/*.xml"/>
            <include name="**/*.properties"/>
          </fileset>
        </copy>
        <jar jarfile="${dist}/${ant.project.name}.jar" basedir="${build}/main" manifest="${etc}/${project.manifest}"/>
    </target>
  
    <target name="demo.context" depends="prepare">
      <mkdir dir="dist"/>
      <uptodate property="demo.uptodate" targetfile="${dist}/demo.jar">
        <srcfiles dir="demo/src/java">
           <include name="**/*.*"/>
        </srcfiles>
        <srcfiles dir="demo/src/etc">
           <include name="demo.mf"/>
        </srcfiles>
      </uptodate>
    </target>
  
    <target name="demo.build" depends="demo.context" unless="demo.uptodate" >
        <echo message="Building Demo"/>
        <mkdir dir="${build}/demo"/>
        <javac debug="off" destdir="${build}/demo" deprecation="true">
          <classpath>
  	    <path refid="project.classpath" />
  	  </classpath>
          <src path="demo/src/java" />
        </javac>
        <copy todir="${build}/demo">
          <fileset dir="demo/src/java">
            <include name="**/*.xinfo"/>
            <include name="**/*.xml"/>
            <include name="**/*.properties"/>
          </fileset>
        </copy>
        <jar jarfile="${dist}/demo.jar" basedir="${build}/demo" manifest="demo/src/etc/demo.mf"/>
    </target>
  
    <!-- UTILITY TARGETS -->
  
    <target name="support">
      <copy todir="${dist}">
         <fileset dir="${etc}">
           <include name="LICENSE.TXT"/>
           <include name="README.TXT"/>
         </fileset>
      </copy>
    </target>
  
    <target name="javadoc" depends="prepare" >
      <echo message="path: ${javadoc.root.path}/${ant.project.name}"/>
      <mkdir dir="${javadoc.root.path}/${ant.project.name}" />
      <javadoc destdir="${javadoc.root.path}/${ant.project.name}" 
  	doctitle="&lt;h1&gt;${project.title} ${VERSION}&lt;/h1&gt;" 
        noindex="false" author="false" 
        use="true"
  	windowtitle="Assembly" 
        additionalparam="-breakiterator -J-Xmx128m"
        packagenames="org.*,net.*" 
        >
          <sourcepath path="${src}/java"/>
          <classpath>
  	    <path refid="project.classpath" />
            <pathelement path="${dist}/${ant.project.name}.jar}" />
  	  </classpath>
  	  <link href="${jdk.href}" />
  	  <link href="${avalon.href}" />
  	  <link href="${containerkit.href}" />
      </javadoc>
    </target>
  
    <target name="deploy" depends="build">
       <mkdir dir="deploy"/>
       <copy todir="deploy">
         <fileset dir="${dist}">
           <include name="assembly.jar"/>
         </fileset>
         <fileset dir="${lib}">
           <include name="avalon-framework.jar"/>
           <include name="logkit.jar"/>
           <include name="excalibur-i18n-1.0.jar" />
           <include name="excalibur-containerkit-1.0.jar" />
           <include name="excalibur-extension-1.0a.jar" />
           <include name="excalibur-configuration-1.0.jar" />
           <include name="excalibur-io-1.1.jar" />
           <include name="excalibur-util-1.0.jar" />
         </fileset>
       </copy>
    </target>
  
    <target name="kernel" depends="deploy">
       <java jar="deploy/assembly.jar" fork="true">
         <arg value="${src}/etc/profile.xml"/>
       </java>
    </target>
  
  </project>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/etc/demo.mf
  
  Index: demo.mf
  ===================================================================
  Manifest-Version: 1.0
  Created-By: OSM SARL
  Extension-List: framework
  framework-Extension-Name: avalon-framework
  framework-Specification-Version: 1.0
  framework-Implementation-Version: 4.1.2
  
  Name: org/apache/excalibur/playground/SimpleComponent.class
  Avalon-Block: true
  
  Name: org/apache/excalibur/playground/TerminalComponent.class
  Avalon-Block: true
  
  Name: org/apache/excalibur/playground/BasicComponent.class
  Avalon-Block: true
  
  Name: org/apache/excalibur/playground/ComplexComponent.class
  Avalon-Block: true
  
  Name: org/apache/excalibur/playground/InvalidComponent.class
  Avalon-Block: true
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.java
  
  Index: BasicComponent.java
  ===================================================================
  
  
  package org.apache.excalibur.playground;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * This is a minimal demonstration component that implements the 
   * <code>BasicService</code> interface and has no dependencies.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  public class BasicComponent extends AbstractLogEnabled
  implements BasicService
  {
  
      //=======================================================================
      // BasicService
      //=======================================================================
  
      public void doPrimeObjective()
      {
          getLogger().info("hello from BasicComponent");
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicComponent.xinfo
  
  Index: BasicComponent.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <component-info>
  
    <component>
      <!-- the component name -->
      <name>basic-component</name>
    </component>
  
    <services>
      <!-- services that this component provides --> 
      <service> 
        <service-ref type="org.apache.excalibur.playground.BasicService"/>
      </service> 
    </services>
  
  </component-info>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/BasicService.java
  
  Index: BasicService.java
  ===================================================================
  /*
   */
  package org.apache.excalibur.playground;
  
  /**
   * The <code>BasicService</code> executes a prime objective.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  public interface BasicService
  {
  
     static final String KEY = "org.apache.excalibur.playground.BasicService";
  
     /**
      * Execute the prime objective of this services.
      */
      void doPrimeObjective();
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.java
  
  Index: ComplexComponent.java
  ===================================================================
  /*
   * ComplexComponent.java
   */
  
  package org.apache.excalibur.playground;
  
  import org.apache.avalon.framework.activity.Executable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  
  /**
   * This is a minimal demonstration component that declares no interface but
   * has dependecies on two services.  These include SimpleService and 
   * BasicService. 
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  
  public class ComplexComponent extends AbstractLogEnabled
  implements Serviceable, Initializable, Executable, Disposable
  {
  
      private ServiceManager m_manager;
      private SimpleService m_simple;
      private BasicService m_basic;
  
      //=================================================================
      // Serviceable
      //=================================================================
      
      /**
       * Pass the <code>ServiceManager</code> to the <code>Serviceable</code>.
       * The <code>Serviceable</code> implementation uses the specified
       * <code>ServiceManager</code> to acquire the services it needs for
       * execution.
       *
       * @param manager The <code>ServiceManager</code> which this
       *                <code>Serviceable</code> uses.
       */
      public void service( ServiceManager manager )
      throws ServiceException
      {
          if( getLogger().isDebugEnabled() )
            getLogger().debug("service");
  
  	  m_manager = manager;
      }
  
  
      //=======================================================================
      // Initializable
      //=======================================================================
  
      public void initialize()
      throws Exception
      {       
          if( getLogger().isDebugEnabled() )
            getLogger().debug("initialize");
  
          //
          // verify current state
          //
  
          if( getLogger() == null ) throw new IllegalStateException(
            "Logging channel has not been assigned.");
  
          if( m_manager == null ) throw new IllegalStateException(
            "Manager has not been declared.");
  
          //
          // lookup the primary service
          //
  
          m_simple = (SimpleService) m_manager.lookup( "simple" );
          m_basic = (BasicService) m_manager.lookup( "basic" );
  
      }
  
      //=======================================================================
      // Executable
      //=======================================================================
  
      public void execute()
      {
          getLogger().info("hello from ComplexComponent");
          m_simple.doObjective();
          m_basic.doPrimeObjective();
      }
  
      //=======================================================================
      // Disposable
      //=======================================================================
      
      public void dispose()
      {
          if( getLogger().isDebugEnabled() )
            getLogger().debug("dispose");
  
          m_simple = null;
          m_manager = null;
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/ComplexComponent.xinfo
  
  Index: ComplexComponent.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <component-info>
  
    <component>
      <name>complex</name>
    </component>
  
    <dependencies>
        <dependency>
            <role>basic</role>
            <service-ref type="org.apache.excalibur.playground.BasicService"/>
        </dependency>
        <dependency>
            <role>simple</role>
            <service-ref type="org.apache.excalibur.playground.SimpleService"/>
        </dependency>
    </dependencies>
  
  </component-info>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.java
  
  Index: InvalidComponent.java
  ===================================================================
  
  
  package org.apache.excalibur.playground;
  
  /**
   * This is a minimal demonstration component that is declared with an invalid service dependency.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  
  public class InvalidComponent
  {
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/InvalidComponent.xinfo
  
  Index: InvalidComponent.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <component-info>
  
    <component>
      <name>simple-component</name>
    </component>
  
    <dependencies>
        <dependency>
            <role>silly</role>
            <service-ref type="org.apache.excalibur.playground.InvalidService"/>
        </dependency>
    </dependencies>
  
  </component-info>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.java
  
  Index: SimpleComponent.java
  ===================================================================
  
  
  package org.apache.excalibur.playground;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * This is a minimal demonstration component that a dependency on 
   * BasicService and provides SimpleService.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  
  public class SimpleComponent extends AbstractLogEnabled
  implements SimpleService
  {
  
      //=======================================================================
      // PrimaryService
      //=======================================================================
  
      public void doObjective()
      {
          getLogger().info("hello from SimpleComponent");
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleComponent.xinfo
  
  Index: SimpleComponent.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <component-info>
  
    <component>
      <name>simple-component</name>
    </component>
  
    <services>
      <service> 
        <service-ref type="org.apache.excalibur.playground.SimpleService"/>
      </service> 
    </services>
  
    <dependencies>
        <dependency>
            <role>basic</role>
            <service-ref type="org.apache.excalibur.playground.BasicService"/>
        </dependency>
    </dependencies>
  
  </component-info>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/SimpleService.java
  
  Index: SimpleService.java
  ===================================================================
  /*
   */
  package org.apache.excalibur.playground;
  
  /**
   * The <code>SimpleService</code> executes an objective.
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  
  public interface SimpleService
  {
  
      static final String KEY = "org.apache.excalibur.playground.SimpleService";
  
     /**
      * Execute the prime objective of this services.
      */
      void doObjective();
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.java
  
  Index: TerminalComponent.java
  ===================================================================
  
  
  package org.apache.excalibur.playground;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  
  /**
   * This is a minimal demonstration component that provides BasicService 
   * and has no dependencies
   *
   * @author <a href="mailto:mcconnell@osm.net">Stephen McConnell</a>
   */
  
  public class TerminalComponent extends AbstractLogEnabled
  implements BasicService
  {
  
      //=======================================================================
      // BasicService
      //=======================================================================
  
      public void doPrimeObjective()
      {
          getLogger().info("hello from TerminalComponent");
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/demo/src/java/org/apache/excalibur/playground/TerminalComponent.xinfo
  
  Index: TerminalComponent.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <component-info>
  
    <component>
      <name>terminal-component</name>
    </component>
  
    <services>
        <service> 
            <service-ref type="org.apache.excalibur.playground.BasicService"/>
        </service> 
    </services>
  
  </component-info>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/avalon-framework.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-configuration-1.0.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-containerkit-1.0.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-extension-1.0a.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-i18n-1.0.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-io-1.1.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/excalibur-util-1.0.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/lib/logkit.jar
  
  	<<Binary file>>
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/.cvsignore
  
  Index: .cvsignore
  ===================================================================
  doc
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/etc/profile.xml
  
  Index: profile.xml
  ===================================================================
  
  <!--
  Assemble a component instance.
  -->
  
  <kernel>
  
     <!--
     Declaration of the logging hierachy and constraints.
     -->
     
     <logger priority="DEBUG"/>
  
     <!--
     Location of installed extension directories.
     -->
  
     <extensions>
       <dirset dir=".">
         <include name="lib"/>
       </dirset>
     </extensions>
  
     <!--
     Definition of the registry of component types from which profiles can be applied.
     -->
  
     <registry name="root">
  
       <!--
       The classpath available to all components in the registry and from which
       component type descriptions will be created.
       -->
  
       <classpath>
         <fileset dir="dist">
           <include name="demo.jar"/>
         </fileset>
       </classpath>
  
       <!--
       The following is only used for testing - it is the classname of a component
       type to validate.
       -->
  
       <test class="org.apache.excalibur.playground.ComplexComponent"/>
  
       <!--
       The set of components declared within the scope of this application.
       -->
  
       <factories>
  
         <component name="complex" class="org.apache.excalibur.playground.ComplexComponent">
  
           <!--
           Include the following context value in the context supplied a component using this 
           profile.  Context entries are normally only required in the case where the component
           type declares a required context type and entry values. Generally speaking, a component
           will normally qualify it's instantiation criteria through a configuration declaration.
           Any context values defined at this level will override context values supplied by the
           container.
           -->
  
           <context>
             <entry name="location" value="Paris"/>
           </context>
  
           <!--
           Apply the following configuration when instantiating the component.  This configuration
           will be applied as the primary configuration in a cascading configuration chain.  A 
           type may declare a default configuration under a "classname".xconfig file that will be 
           used to dereference any configuration requests not resolvable by the configuration 
           supplied here.
           -->
  
           <configuration>
             <message value="Hello"/>
           </configuration>
  
           <!--
           The parameterization criteria from this instance of the component type.
           -->
  
           <parameters/>
  
         </component>
  
       </factories>
  
     </registry>
  
  
  </kernel>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/etc/project.mf
  
  Index: project.mf
  ===================================================================
  Manifest-Version: 1.0
  Created-By: OSM SARL
  Extension-Name: Assembler
  Specification-Vendor: Apache Software Foundation
  Specification-Version: 1.0
  Implementation-Vendor: Apache Software Foundation
  Implementation-Version: 0.1
  Class-Path: avalon-framework.jar logkit.jar excalibur-i18n-1.0.jar excalibur-configuration-1.0.jar excalibur-extension-1.0a.jar excalibur-containerkit-1.0.jar
  Main-Class: org.apache.excalibur.merlin.registry.Main
  
  Name: org/apache/excalibur/merlin/registry/DefaultRegistry.class
  Avalon-Block: true
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/AssemblyException.java
  
  Index: AssemblyException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.util.Enumeration;
  import java.util.Dictionary;
  import java.util.Hashtable;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate that there was an error Assembling a component model.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class AssemblyException
      extends CascadingException
  {
  
      private static final Hashtable EMPTY_TABLE = new Hashtable();
  
      private Dictionary m_errors;
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public AssemblyException( final String message )
      {
          this( null, message, null );
      }
  
      /**
       * Construct a new <code>AssemblyRuntimeException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       */
      public AssemblyException( final Dictionary errors, final String message )
      {
          this( errors, message, null );
      }
  
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public AssemblyException( final String message, final Throwable throwable )
      {
          this( null, message, throwable );
      }
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public AssemblyException( final Dictionary errors, final String message, 
        final Throwable throwable )
      {
          super( message, throwable );
          if( errors != null )
          {
              m_errors = errors;
          }
          else
          {
              m_errors = EMPTY_TABLE;
          }
      }
  
     /**
      * Return the table of supplimentary messages.
      * @return the messages table
      */
      public Dictionary getDictionary()
      {
         return m_errors;
      }
  
     /**
      * Returns a stringified representation of the exception.
      * @return the exception as a string.
      */
      public String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append( super.toString() );
          buffer.append( " Errors: " + m_errors.size() );
          Enumeration keys = m_errors.keys();
          while( keys.hasMoreElements() )
          {
               Object key = keys.nextElement();
               buffer.append( "\n  source: " + key.toString() + " cause: " + m_errors.get( key ) );
          }
          return buffer.toString();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/AssemblyRuntimeException.java
  
  Index: AssemblyRuntimeException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.util.Enumeration;
  import java.util.Dictionary;
  import java.util.Hashtable;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  /**
   * Exception to indicate that there was an error during assembly.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class AssemblyRuntimeException
      extends CascadingRuntimeException
  {
  
      private static final Hashtable EMPTY_TABLE = new Hashtable();
  
      private Dictionary m_errors;
  
      /**
       * Construct a new <code>AssemblyRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public AssemblyRuntimeException( final String message )
      {
          this( null, message, null );
      }
  
      /**
       * Construct a new <code>AssemblyRuntimeException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       */
      public AssemblyRuntimeException( final Dictionary errors, final String message )
      {
          this( errors, message, null );
      }
  
  
      /**
       * Construct a new <code>AssemblyRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public AssemblyRuntimeException( final String message, final Throwable throwable )
      {
          this( null, message, throwable );
      }
  
      /**
       * Construct a new <code>AssemblyRuntimeException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public AssemblyRuntimeException( final Dictionary errors, final String message, 
        final Throwable throwable )
      {
          super( message, throwable );
          if( errors != null )
          {
              m_errors = errors;
          }
          else
          {
              m_errors = EMPTY_TABLE;
          }
      }
  
     /**
      * Return the table of supplimentary messages.
      * @return the messages table
      */
      public Dictionary getDictionary()
      {
         return m_errors;
      }
  
     /**
      * Returns a stringified representation of the exception.
      * @return the exception as a string.
      */
      public String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append( super.toString() );
          buffer.append( " Errors: " + m_errors.size() );
          Enumeration keys = m_errors.keys();
          while( keys.hasMoreElements() )
          {
               Object key = keys.nextElement();
               buffer.append( "\n  source: " + key.toString() + " cause: " + m_errors.get( key ) );
          }
          return buffer.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ComponentDefinition.java
  
  Index: ComponentDefinition.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import java.net.URL;
  import java.io.InputStream;
  import java.util.Enumeration;
  import java.util.Properties;
  import java.util.Vector;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Hashtable;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.Version;
  import org.apache.excalibur.containerkit.metainfo.ContextDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.verifier.ComponentVerifier;
  import org.apache.excalibur.containerkit.verifier.VerifyException;
  import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
  import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
  
  import org.apache.excalibur.merlin.registry.Registry;
  import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
  
  /**
   * <p>Provides support for the navigation across <code>ComponentDefinition</code> instances 
   * implied by service and dependency relationships.  
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  class ComponentDefinition extends AbstractLogEnabled implements ComponentType
  {
      //=======================================================================
      // static
      //=======================================================================
  
      private static final Resources REZ =
          ResourceManager.getPackageResources( ComponentDefinition.class );
  
      private static final Profile[] EMPTY_PROFILES = new Profile[0];
  
      //=======================================================================
      // state
      //=======================================================================
  
     /**
      * The registry against which dependecies can be resolved.
      */
      private DefaultRegistry m_registry;
  
     /**
      * The compontent info instance backing the type defintion.
      */
      private ComponentInfo m_component;
  
     /**
      * The set of factory profile criteria supplied for this type.
      */
      private Configuration[] m_criteria;
  
     /**
      * The set of factory profiles derived from the supplied criteria.
      */
      private Hashtable m_profiles = new Hashtable();
  
     /**
      * Interal flag indicating that profile initialization has been 
      * applied.
      */
      private boolean m_init = false;
  
  
      //=======================================================================
      // constructor
      //=======================================================================
  
     /**
      * Creation of a new ComponentDefinition.
      * @param registry the component registry
      * @param component a component info descriptor
      * @param profiles a set of configuration fragments describing component profiles
      *    declared for this component type
      */
      public ComponentDefinition( 
        DefaultRegistry registry, ComponentInfo component, Configuration[] profiles )
        throws ConfigurationException
      {
          m_registry = registry;
          m_component = component;
          m_criteria = profiles;
      }
  
      //=======================================================================
      // Initializable
      //=======================================================================
  
     /**
      * Initialization of the component type during which the validation of 
      * type and integrity of dependecies is undertaken.  Initialization failure 
      * may occur is a dependecy cannot be resolved.
      * @exception Initializable
      */
      private void initialize() throws UnresolvedProviderException, ConfigurationException
      {
          if( m_init ) return;
          if( m_criteria.length == 0 )
          {
              // create an implicit profile
              DefaultProfile profile = new DefaultProfile( m_registry, this );
              m_profiles.put( profile.getName(), profile );
          }
          else
          {
              // use the explicit profiles
              for( int i=0; i<m_criteria.length; i++ )
              {
                  DefaultProfile profile = new DefaultProfile( m_registry, this, m_criteria[i] );
                  m_profiles.put( profile.getName(), profile );
              }
          }
          m_init = true;
      }
  
      //=======================================================================
      // ComponentType
      //=======================================================================
  
     /**
      * Convinience operation to construct an abstract name representing this 
      * component defintion.
      * @return an abstract name
      */
      public String getName()
      {
          return getComponentInfo().getComponentDescriptor().getImplementationKey() + ":" 
            + m_component.getComponentDescriptor().getVersion();
      }
  
     /**
      * Returns the <code>ComponentInfo</code> instance describing the meta-info structure
      * for this component type.
      *
      * @return the meta-info set for the component type
      */
      public ComponentInfo getComponentInfo()
      {
          return m_component;
      }
  
     /**
      * Return the set of profiles for this component type.
      * @return the set of profiles available for this component type
      */
      public Profile[] getProfiles() 
        throws UnresolvedProviderException, ConfigurationException
      {
          initialize();
          return (Profile[]) m_profiles.values().toArray( EMPTY_PROFILES );
      }
  
     /**
      * Return a named profile for this component type.
      * @return the named profile or null if the name doers not match a known profile
      */
      public Profile getProfile( String name ) 
        throws UnresolvedProviderException, ConfigurationException
      {
          initialize();
          return (Profile) m_profiles.get( name );
      }
  
     /**
      * Returns a stringified representation of the component definition.
      * @return string representation of the conponent type.
      */
      public String toString()
      {
          return getComponentInfo().getComponentDescriptor().getImplementationKey() + "/" 
            + getComponentInfo().getComponentDescriptor().getVersion() + "/"
            + " (" + getComponentInfo().getComponentDescriptor().getName() + ")";
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ComponentType.java
  
  Index: ComponentType.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.verifier.VerifyException;
  import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  
  /**
   * Definition of a navigable meta information structure representing a component type.
   *  
   * @see org.apache.excalibur.merlin.registry.Registry
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public interface ComponentType
  {
     /**
      * Returns the name of the component type.
      * @return an abstract name
      */
      String getName();
  
     /**
      * Returns the <code>ComponentInfo</code> instance describing the meta-info structure
      * for this component type.
      *
      * @return the meta-info set for the component type
      */
      ComponentInfo getComponentInfo();
  
     /**
      * Return the set of profiles for this component type.
      * @return the set of profiles available for this component type
      */
      Profile[] getProfiles() throws UnresolvedProviderException, ConfigurationException;
  
     /**
      * Return a named profile for this component type.
      * @return the named profile or null if the name doers not match a known profile
      */
      public Profile getProfile( String name ) throws UnresolvedProviderException, ConfigurationException;
  
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultClassLoader.java
  
  Index: DefaultClassLoader.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.util.Dictionary;
  import java.util.Hashtable;
  import java.util.Enumeration;
  import java.util.Vector;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.List;
  import java.util.LinkedList;
  import java.net.URLClassLoader;
  import java.net.URL;
  import java.net.JarURLConnection;
  
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.extension.PackageManager;
  import org.apache.avalon.excalibur.extension.PackageRepository;
  import org.apache.avalon.excalibur.extension.OptionalPackage;
  
  import org.apache.excalibur.merlin.registry.*;
  
  /**
   * Classloader for an assembly of components.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */ 
  
  class DefaultClassLoader extends URLClassLoader implements LogEnabled
  {
  
      //===================================================================
      // static
      //===================================================================
  
      private static final Resources REZ =
          ResourceManager.getPackageResources( DefaultClassLoader.class );
  
      //===================================================================
      // state
      //===================================================================
  
      private File[] m_stack;
  
     /**
      * List of names of block implementation classes.
      */
      private final List m_blocks = new LinkedList();
  
      private PackageManager m_manager;
  
      private Logger m_logger;
  
      //===================================================================
      // constructor
      //===================================================================
  
      DefaultClassLoader( 
        PackageRepository repository, ClassLoader parent, Configuration classpath, Logger logger )
      {
          super( new URL[ 0 ], parent );
          m_logger = logger;
          m_manager = new PackageManager( repository );
          addClasspath( classpath );
      }
  
      public void addClasspath( Configuration classpath )
      {
          try
          {
              URL[] urls = Fileset.expandClasspath( classpath );
              for( int i = 0; i < urls.length; i++ )
              {
                  addURL( urls[ i ] );
              }
              String[] path = Fileset.urlsToStrings( urls );
              final File[] extensions = getOptionalPackagesFor( path );
              for( int i = 0; i < extensions.length; i++ )
              {
                  addURL( extensions[ i ].toURL() );
              }
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while creating classloader";
              throw new RegistryRuntimeException( error, e );
          }
      }
  
      //===================================================================
      // LogEnabled
      //===================================================================
  
      public void enableLogging( Logger logger )
      {
          m_logger = logger;
      }
  
      public Logger getLogger()
      {
          return m_logger;
      }
  
      //===================================================================
      // ClassLoader
      //===================================================================
  
     /**
      * 
      */
      protected void addURL( URL url )
      {
          try
          {
              super.addURL( url );
              getLogger().debug("scanning: " + url );    
              String[] entries = getBlocksEntries( url );
              for( int i=0; i<entries.length; i++ )
              {
                  getLogger().debug("component: " + entries[i] );
                  m_blocks.add( entries[i] );
              }
          }
          catch( Throwable e )
          {
              throw new CascadingRuntimeException(
                "Unexpected error while attempting to add classloader URL: " + url, e );
          }
      }
  
      //===================================================================
      // ClassLoader extensions
      //===================================================================
  
     /**
      * Returns TRUE is the component classname is know by the classloader.
      * @return a component availablity status
      */
      public boolean hasComponent( String classname )
      {
          return m_blocks.contains( classname );
      }
  
     /**
      * Return the array of component implementation class names within the scope
      * of the classloader.
      * @return the block names array
      */
      public String[] getComponentClassnames()
      {
          return (String[]) m_blocks.toArray( new String[0] );
      }
  
      //===================================================================
      // internals
      //===================================================================
  
      /**
       * Returns an array of <code>String</code>s corresponding to the set of classnames
       * where each classname is a declared block within the supplied jar file.
       * @param file a jar file
       * @exception RegistryRuntimeException if a general exception occurs
       */
      private String[] getBlocksEntries( URL base )
          throws RegistryRuntimeException
      {
          Vector vector = new Vector();
          try
          {
              final URL url = new URL( "jar:" + base.toString() + "!/" );
              final JarURLConnection jar = (JarURLConnection)url.openConnection();
              final Map map = jar.getManifest().getEntries();
              final Iterator iterator = map.keySet().iterator();
              while( iterator.hasNext() )
              {
                  final String name = (String)iterator.next();
                  final Attributes attributes = (Attributes)map.get( name );
                  final Iterator it = attributes.keySet().iterator();
                  while( it.hasNext() )
                  {
                      final Object entry = it.next();
                      if( entry.toString().equals( "Avalon-Block" ) )
                      {
                          if( attributes.get( entry ).equals( "true" ) )
                          {
                              vector.add( name.substring( 0, name.indexOf( ".class" ) ) );
                          }
                      }
                  }
              }
          }
          catch( IOException e )
          {
              final String error = "IO exception while attempt to read block manifest.";
              throw new RegistryRuntimeException( error, e );
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while inspecting manifest on file: ";
              throw new RegistryRuntimeException( error + base, e );
          }
          finally
          {
              return (String[]) vector.toArray( new String[0] );
          }
      }
  
      /**
       * Retrieve the files for the optional packages required by
       * the jars in ClassPath.
       *
       * @param classPath the Classpath array
       * @return the files that need to be added to ClassLoader
       */
      private File[] getOptionalPackagesFor( final String[] classPath )
          throws Exception
      {
          final Manifest[] manifests = getManifests( classPath );
          final Extension[] available = Extension.getAvailable( manifests );
          final Extension[] required = Extension.getRequired( manifests );
  
          //if( getLogger().isDebugEnabled() )
          //{            
          //    final String message1 =
          //        REZ.getString( "available-extensions",
          //                       Arrays.asList( available ) );
          //    getLogger().debug( message1 );
          //    final String message2 =
          //        REZ.getString( "required-extensions",
          //                       Arrays.asList( required ) );
          //    getLogger().debug( message2 );
          //}
  
          final ArrayList dependencies = new ArrayList();
          final ArrayList unsatisfied = new ArrayList();
  
          m_manager.scanDependencies( required,
                                             available,
                                             dependencies,
                                             unsatisfied );
  
          if( 0 != unsatisfied.size() )
          {
              final int size = unsatisfied.size();
              for( int i = 0; i < size; i++ )
              {
                  final Extension extension = (Extension)unsatisfied.get( i );
                  final Object[] params = new Object[]
                  {
                      extension.getExtensionName(),
                      extension.getSpecificationVendor(),
                      extension.getSpecificationVersion(),
                      extension.getImplementationVendor(),
                      extension.getImplementationVendorID(),
                      extension.getImplementationVersion(),
                      extension.getImplementationURL()
                  };
                  final String message = REZ.format( "missing.extension", params );
                  getLogger().warn( message );
              }
  
              final String message =
                  REZ.getString( "unsatisfied.extensions", new Integer( size ) );
              throw new Exception( message );
          }
  
          final OptionalPackage[] packages =
              (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] );
          return OptionalPackage.toFiles( packages );
      }
  
      private Manifest[] getManifests( final String[] classPath )
          throws Exception
      {
          final ArrayList manifests = new ArrayList();
  
          for( int i = 0; i < classPath.length; i++ )
          {
              final String element = classPath[ i ];
  
              if( element.endsWith( ".jar" ) )
              {
                  try
                  {
                      final URL url = new URL( "jar:" + element + "!/" );
                      final JarURLConnection connection = (JarURLConnection)url.openConnection();
                      final Manifest manifest = connection.getManifest();
                      manifests.add( manifest );
                  }
                  catch( final IOException ioe )
                  {
                      final String message = REZ.getString( "bad-classpath-entry", element );
                      getLogger().warn( message );
                      throw new Exception( message );
                  }
              }
          }
  
          return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultProfile.java
  
  Index: DefaultProfile.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import java.io.InputStream;
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.net.JarURLConnection;
  import java.net.URLClassLoader;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.Vector;
  import java.util.Iterator;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.security.Policy;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.excalibur.extension.PackageRepository;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.extension.OptionalPackage;
  import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
  
  import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
  import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
  
  import org.apache.excalibur.merlin.registry.Registry;
  import org.apache.excalibur.merlin.registry.UnresolvedProviderException;
  import org.apache.excalibur.configuration.ContextFactory;
  
  /**
   * The default implementation of a profile under which configuration, context
   * and parameterization criteria is associated against a component type defintion.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  class DefaultProfile extends ComponentMetaData 
  implements Profile
  {
      private static String getAbstractName( Configuration profile )
      {
          return profile.getAttribute("name",null);
      }
  
      private static DependencyMetaData[] getDependencyMetaData( 
        final DefaultRegistry registry, final ComponentType type ) 
        throws UnresolvedProviderException
      {
          Vector vector = new Vector();
          DependencyDescriptor[] deps = type.getComponentInfo().getDependencies();
          for( int i=0; i<deps.length; i++ )
          {
              final String role = deps[i].getRole();
              final Profile provider = registry.getCandidateProfile( deps[i] );
              DependencyMetaData data = new DependencyMetaData( 
                 role, 
                 provider.getName() 
              );
              vector.add( data );
          }
          return (DependencyMetaData[]) vector.toArray( new DependencyMetaData[0] );
      }
  
  
      private final ComponentType m_type;
  
      private final Configuration m_profile;
  
      private final DefaultRegistry m_registry;
  
     /**
      * Creation of a default profile.
      * @param type the component type that this profile is qualifying
      */
      public DefaultProfile( final DefaultRegistry registry, final ComponentType type )
         throws ConfigurationException, UnresolvedProviderException
  
      {
          this( registry, type, new DefaultConfiguration("profile") );
      }
  
     /**
      * Creation of a profile of a component type. The 
      * configuration is a profile instance containing criteria for for the 
      * profiles default configuration, parameters and content.
      * 
      * @param type the component type that this profile is qualifying
      * @param profile a configuration instance possibly containing a context, 
      *   parameters and configuration element.
      * @param name the profile name
      */
      public DefaultProfile( 
        final DefaultRegistry registry, final ComponentType type, final Configuration profile )
        throws ConfigurationException, UnresolvedProviderException
      {
          super( 
            getAbstractName( profile ), 
            getDependencyMetaData( registry, type ), 
            Parameters.fromConfiguration( profile.getChild("paramerters") ),
            profile.getChild("configuration"),
            type.getComponentInfo() 
          );
          m_type = type;
          m_profile = profile;
          m_registry = registry;
          m_registry.install( this );
      }
  
     /**
      * Returns the component type bound to the profile.
      * @return the component type
      */
      public ComponentType getComponentType()
      {
          return m_type;
      }
  
     /**
      * Returns the context to be supplied to an instance of the profile
      * @return the profile context object
      */
      public Context getContext( Context parent )
      {
          try
          {
              Configuration criteria = m_profile.getChild("context");
              return ContextFactory.createContextFromConfiguration( parent, criteria );
          }
          catch( Throwable e )
          {
              throw new ProfileRuntimeException( 
                "Unexpected error while creating context.", e );
          }
  
      }
      
      public String toString()
      {
          return "DefaultProfile name: '" + getName() + "' type: " + getComponentType();
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultRegistry.java
  
  Index: DefaultRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import java.io.InputStream;
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.net.JarURLConnection;
  import java.net.URLClassLoader;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.Vector;
  import java.util.Iterator;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.util.Enumeration;
  import java.security.Policy;
  import java.io.FileInputStream;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.AvalonFormatter;
  import org.apache.avalon.framework.logger.LogKitLogger;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Executable;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.DefaultServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.ExceptionUtil;
  import org.apache.avalon.excalibur.extension.PackageRepository;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.extension.OptionalPackage;
  import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
  import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
  import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
  import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
  import org.apache.excalibur.containerkit.verifier.AssemblyVerifier;
  import org.apache.excalibur.containerkit.verifier.MetaDataVerifier;
  import org.apache.excalibur.containerkit.verifier.VerifyException;
  import org.apache.excalibur.containerkit.dependency.DependencyMap;
  import org.apache.log.Hierarchy;
  import org.apache.log.Priority;
  import org.apache.log.output.io.StreamTarget;
  
  import org.apache.excalibur.merlin.registry.*;
  import org.apache.excalibur.merlin.registry.Profile;
  
  /**
   * Provides support for the maintenance of a registry of 
   * component type definitions established within a classloader.
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public class DefaultRegistry extends AbstractLogEnabled implements Contextualizable, Serviceable, Configurable, Initializable, Executable, Disposable, Registry
  {
      //=======================================================================
      // static
      //=======================================================================
  
      private static final ComponentType[] EMPTY_DEFS = new ComponentType[0];
      private static final Profile[] EMPTY_PROFILES = new Profile[0];
      private static final Resources REZ =
          ResourceManager.getPackageResources( DefaultRegistry.class );
  
      //=======================================================================
      // state
      //=======================================================================
  
     /**
      * The context argument supplied by the container.
      */
      private Context m_context;
  
     /**
      * The list of all ComponentDefinition instances keyed by classname.
      */
      private Hashtable m_componentRegistry = new Hashtable();
  
     /**
      * The list of all ComponentDefinition instances keyed by service classname.
      */
      private ServiceRegistry m_services;
  
      private ClassLoader m_classloaderParent;
  
      private DefaultClassLoader m_classloader;
  
     /**
      * List of the component classname recorded in the jar file manifests.
      */
      private List m_classnames = new LinkedList();
  
     /**
      * The extensions repository (supplied by service manager).
      */
      private PackageRepository m_repository;
  
      private Configuration m_config;
  
      private MetaDataVerifier m_verifier;
  
      private AssemblyVerifier m_assemblyVerifier;
  
      private Hashtable m_profileMapping = new Hashtable();
  
      private Hashtable m_profiles = new Hashtable();
  
      private ComponentMetaData[] m_appContext;
  
      //=======================================================================
      // LogEnabled
      //=======================================================================
          
      public void enableLogging( Logger logger )
      {
          super.enableLogging( logger );
      }
  
      //=======================================================================
      // Contextualizable
      //=======================================================================
  
     /**
      * Service context from which the registry classloader is resolved.
      * @param context a context value containing the key 'classloader' 
      */
      public void contextualize( Context context ) throws ContextException
      {
          m_context = context;
          m_classloaderParent = (ClassLoader) context.get( CLASSLOADER_KEY );
      }
  
      //=======================================================================
      // Configure
      //=======================================================================
  
     /**
      * Invoked by the container to establish the registry configuration.
      * @param config a component configuration
      */
      public void configure( Configuration config)
      {
          m_config = config;
      }
  
      //=======================================================================
      // Service
      //=======================================================================
  
     /**
      * Invoked by the container to establish services that this component
      * is dependent on.  The implementation receives the singelton extensions
      * repository which will be used during initalization to construct the 
      * registry classloader.
      *
      * @param manager a component manager
      * @exception ServiceException if a servicing error occurs
      */
      public void service( ServiceManager manager ) throws ServiceException
      {
          m_repository = (PackageRepository) manager.lookup( PackageRepository.ROLE );
      }
  
      //=======================================================================
      // Initializable
      //=======================================================================
  
     /**
      * Initalization of a <code>Registry</code> during which an application
      * scoped classloader is created.
      * @exception Exception if an error occurs during initialization.
      */
      public void initialize() throws Exception
      {
          getLogger().debug("classloader creation");
          m_classloader = new DefaultClassLoader(
            m_repository, 
            m_classloaderParent, 
            m_config.getChild("classpath"), 
            getLogger().getChildLogger( "loader" )
          );
  
          //
          // for all of the compoents declared under manifest jar block entries,
          // register these as potential service providers with the service repository
          //
  
          getLogger().debug("repository creation");
          m_services = new ServiceRegistry( this, m_classloader, m_config.getChild("factories") );
          m_services.enableLogging( getLogger().getChildLogger("services") );
          String[] blocks = m_classloader.getComponentClassnames();
  
          try
          {
  
              //
              // register all of the the componet providers implied by the classpath
              // manifest declarations
              //
  
              for( int i=0; i<blocks.length; i++ )
              {
                  // initialize the component type defintions
                  final String classname = blocks[i].replace('/','.');
                  m_services.register( classname );
              }
  
              //
              // for all of the components declared in the application profiles,
              // install each one in the service repository - the side effect of 
              // this is the buildup of the m_profiles table that will be used to 
              // construct the application context
              //
  
              //getLogger().debug("profile:\n " + ConfigurationUtil.list( m_config ));
              Configuration factories = m_config.getChild("factories");
              Configuration[] entries = factories.getChildren();
              for( int i=0; i<entries.length; i++ )
              {
                  final Configuration factory = entries[i];
                  getLogger().debug("factory: \n" + ConfigurationUtil.list( factory ));
                  final String name = factory.getAttribute("name");
                  final String classname = factory.getAttribute("class");
                  final String mode = factory.getName();
                  if( mode.equals("component") )
                  {
                      m_services.install( classname, name );
                  }
                  else
                  {
                      // unrecognized declaration
                      getLogger().debug(
                        "bypassing unrecognized element " 
                        + ConfigurationUtil.list( factory ) );
                  }
              }
          }
          catch( Throwable e )
          {
              final String error = "Internal registry initialization failure.";
              throw new RegistryException( error, e );
          }
  
      }
  
      //=======================================================================
      // Executable
      //=======================================================================
  
     /**
      * Executes composition of a target component assembly options relative to a target 
      * component classname within the scope of a classpath declaration containing jar file 
      * references (refer contextualize), and generate a report to the logging channel.
      *
      * @exception Exception if an error occurs during execution
      */
      public void execute() throws Exception
      {
          //
          // the m_profiles table contain all of the profiles that
          // have been selected to act as potential service provider for all of the 
          // dependecies - from this point we need to buid the set of profiles needed
          // to execute the targets
          //
  
          Vector vector = new Vector();
          DependencyMap map = new DependencyMap();
          Profile[] profiles = m_services.getInstalledProfiles();
          for( int i=0; i<profiles.length; i++ )
          {
              vector.add( profiles[i] );
              getLogger().debug("profile: " + profiles[i] );
              map.add( (ComponentMetaData) profiles[i] );
          }
          ComponentMetaData[] context = (ComponentMetaData[]) vector.toArray(new ComponentMetaData[0] );
          verify( context );
  
          //
          // build the ordered sequence of dependecies
          //        
  
          getLogger().debug("startup sequence");
          ComponentMetaData[] startup = map.getStartupGraph();
          for( int i=0; i<startup.length; i++ )
          {
              getLogger().debug("start: " + startup[i] );
          }
          getLogger().debug("shutdown sequence");
          ComponentMetaData[] shutdown = map.getShutdownGraph();
          for( int i=0; i<shutdown.length; i++ )
          {
              getLogger().debug("stop: " + shutdown[i] );
          }
      }
  
      //=======================================================================
      // Registry
      //=======================================================================
  
     /**
      * Return the preferred profile for a depedency.
      * @param dependency a consumer component dependecy declaration
      * @return the preferred candidate supplier profile or null if not candidates found
      */
      public Profile getCandidateProfile( DependencyDescriptor dependency ) 
        throws UnresolvedProviderException
      {
          return m_services.getCandidateProfile( dependency );
      }
  
     /**
      * Returns an array of component profiles representing candidate component types 
      * capable of acting as a service supplier relative to the supplied dependecy descriptor.
      * @param dependency the dependency descriptor to evaluate
      * @return the set of profiles
      */
      public Profile[] getCandidateProfiles( DependencyDescriptor dependency ) 
      {
          return m_services.getProfiles( dependency.getService() );
      }
  
     /**
      * Method invoked by a DefaultProfile to declare itself within the application scope.
      * @param profile the Profile to include in application scope
      */
      void install( Profile profile )
      {
          m_services.install( profile );
      }
  
      //=======================================================================
      // implementation
      //=======================================================================
  
     /**
      * Test if the registry can resolve a request for a component with the supplied classname
      * @param classname a component or service class name
      * @return TRUE if the registry can service the request
      */
      private boolean hasComponentDefinition( String classname )
      {
          return m_services.getComponentType( classname ) != null;
      }
  
     /**
      * Returns an component defintion either through referdnce to an exiting defintion
      * or through defintion coreation if no exiting defintion is available relative to 
      * the request classname key.
      * @param classname the class name of the component defintion to locate or create
      * @return the corresponding component defintion
      * @exception RegistryRuntimeException if an error occurs during the 
      *    construction of a new component defintion
      */
      private ComponentType getComponentDefinition( String classname )
      {
          return m_services.getComponentType( classname );
      }
  
      private void verify( ComponentMetaData[] assembly ) throws VerifyException
      {
          if( m_assemblyVerifier == null ) 
          {
              m_assemblyVerifier = new AssemblyVerifier();
              m_assemblyVerifier.enableLogging( getLogger().getChildLogger("verifier") );
          }
          m_assemblyVerifier.verifyAssembly( assembly );
      }
  
     /**
      * Returns the component type implementation class.
      * @param type the component type descriptor
      * @return the class implementing the component type
      */
      private Class getComponentClass( ComponentType type ) throws RegistryException
      {
          if( null == type )
            throw new NullPointerException("Illegal null component type argument.");
  
          final String classname = type.getComponentInfo().getComponentDescriptor().getImplementationKey();
          try
          {
              return m_classloader.loadClass( classname );
          }
          catch( Throwable e )
          {
              final String error = "Could not load implementation class for component type: "
                + classname;
              throw new RegistryException( error, e );
          }
      }
  
  
     /**
      * Returns the service type implementation class.
      * @param service the service type descriptor
      * @return the class implementing the service type
      */
      private Class getServiceClass( ServiceDescriptor service ) throws RegistryException
      {
          final String classname = service.getServiceDesignator().getClassname();
          try
          {
              return m_classloader.loadClass( classname );
          }
          catch( Throwable e )
          {
              final String error = "Could not load implementation class for service type: "
                + classname;
              throw new RegistryException( error, e );
          }
      }
  
      //=======================================================================
      // Disposable
      //=======================================================================
  
     /**
      * Disposal of this component.
      */
      public void dispose()
      {
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/DefaultRegistry.xinfo
  
  Index: DefaultRegistry.xinfo
  ===================================================================
  <?xml version="1.0"?>
  
  <!--  
  Copyright (C) The Apache Software Foundation. All rights reserved.
  This software is published under the terms of the Apache Software License
  version 1.1, a copy of which has been included with this distribution in
  the LICENSE.txt file.
  
  @author  Stephen McConnell
  @version 1.0 12/03/2001
  -->
  
  <blockinfo>
  
    <block>
      <name>registry</name>
      <version>1.0</version>
    </block>
  
    <services>
      <service name="org.apache.excalibur.merlin.registry.Registry" version="1.0"/>
    </services>
  
  </blockinfo>
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Fileset.java
  
  Index: Fileset.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.avalon.framework.configuration.Configuration;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.io.File;
  import java.util.Vector;
  import java.util.StringTokenizer;
  
  
  /**
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  class Fileset 
  {
      //=======================================================================
      // static
      //=======================================================================
  
      public static File[] expandExtensions( Configuration conf )
      {
          Vector vector = new Vector();
          Configuration[] dirsets = conf.getChildren("dirset");
          for( int i=0; i<dirsets.length; i++ )
          {
              expandDirSetToVector( vector, dirsets[i] );
          }
          return (File[]) vector.toArray( new File[ vector.size() ] );
      }
  
      private static void expandDirSetToVector( Vector vector, Configuration dirset )
      {
          File base = new File( dirset.getAttribute("dir", System.getProperty("user.dir") ) );
          if( !base.isDirectory() )
            throw new IllegalArgumentException("Base dir does not refer to a directory in path: " + base );
          Configuration[] includes = dirset.getChildren("include");
          for( int i=0; i<includes.length; i++ )
          {
              String name = includes[i].getAttribute("name", null );
              if( name == null ) 
                throw new IllegalArgumentException(
                  "Include does not contain the name attribute: " + includes[i].getLocation() );
              File file = new File( base, name );
              if( file.isDirectory() )
              {
                  vector.add( file );
              }
              else
              {
                 throw new IllegalArgumentException(
                  "Include dir does not refer to a directory: " + file + ", base: " + base );
              }
          }
      }
  
      public static URL[] expandClasspath( Configuration conf )
      {
          Vector vector = new Vector();
          Configuration[] filesets = conf.getChildren("fileset");
          for( int i=0; i<filesets.length; i++ )
          {
              expandFileSetToVector( vector, filesets[i] );
          }
          return (URL[]) vector.toArray( new URL[ vector.size() ] );
      }
  
      public static URL[] expandFileSet( Configuration conf )
      {
          Vector vector = new Vector();
          expandFileSetToVector( vector, conf );
          return (URL[]) vector.toArray( new URL[ vector.size() ] );
      }
  
      private static void expandFileSetToVector( Vector vector, Configuration conf )
      {
          File base = new File( conf.getAttribute("dir", System.getProperty("user.dir") ) );
          if( !base.isDirectory() )
            throw new IllegalArgumentException("Base dir does not refer to a directory in path: " + base );
          
          Configuration[] includes = conf.getChildren("include");
          for( int i=0; i<includes.length; i++ )
          {
              String name = includes[i].getAttribute("name", null );
              if( name == null ) 
                throw new IllegalArgumentException(
                  "Include does not contain the name attribute: " + includes[i].getLocation() );
              File file = new File( base, name );
              if( !file.exists() ) 
                throw new IllegalArgumentException(
                  "Include references file that does not exist: " + includes[i].getLocation() );
              try
              {
                  vector.add( file.toURL() );
              }
              catch( Throwable e )
              {
                throw new IllegalArgumentException(
                  "Could not convert include to a URL: " + includes[i].getLocation() );
              }
          }
      }
  
  
      public static String[] splitPath( String path, String token )
      {
          StringTokenizer tokenizer = new StringTokenizer( path, token );
          Vector vector = new Vector();
          while( tokenizer.hasMoreElements() )
          {
              vector.add( tokenizer.nextToken() );
          }
          return (String[]) vector.toArray( new String[ vector.size() ] );
      }
  
      public static File[] expandPath( String[] path )
      {
          Vector vector = new Vector();
          for( int i=0; i<path.length; i++ )
          {
              File file = new File( path[i] );
              vector.add( file );
              if( file.isDirectory() )
              {
                  expandDirectory( vector, file );
              }
          }
          return (File[]) vector.toArray( new File[ vector.size() ] );
      }
  
      private static void expandDirectory( Vector vector, File dir )
      {
          if( !dir.isDirectory() ) return;
          final File[] files = dir.listFiles();
          for( int i=0; i<files.length; i++ )
          {
              File file = files[i];
              vector.add( file ); 
              if( file.isDirectory() )
              {
                  expandDirectory( vector, file );
              }
          }
      }
  
      public static String[] urlsToStrings( URL[] urls )
      {
          Vector vector = new Vector();
          for( int i=0; i<urls.length; i++ )
          {
              vector.add( urls[i].toString() );
          }
          return (String[]) vector.toArray( new String[ vector.size() ] );
      }
  
  
      public static URL[] fileToURL( File[] files ) throws MalformedURLException
      {
          Vector vector = new Vector();
          for( int i=0; i<files.length; i++ )
          {
              vector.add( files[i].toURL() );
          }
          return (URL[]) vector.toArray( new URL[ vector.size() ] );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Main.java
  
  Index: Main.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import java.io.InputStream;
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.net.JarURLConnection;
  import java.net.URLClassLoader;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.Vector;
  import java.util.Iterator;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.security.Policy;
  import java.io.FileInputStream;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.AvalonFormatter;
  import org.apache.avalon.framework.logger.LogKitLogger;
  import org.apache.avalon.framework.activity.Initializable;
  import org.apache.avalon.framework.activity.Disposable;
  import org.apache.avalon.framework.activity.Executable;
  import org.apache.avalon.framework.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.DefaultConfiguration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.configuration.Configurable;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.context.Contextualizable;
  import org.apache.avalon.framework.context.ContextException;
  import org.apache.avalon.framework.context.DefaultContext;
  import org.apache.avalon.framework.service.Serviceable;
  import org.apache.avalon.framework.service.ServiceManager;
  import org.apache.avalon.framework.service.DefaultServiceManager;
  import org.apache.avalon.framework.service.ServiceException;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.ExceptionUtil;
  import org.apache.avalon.excalibur.extension.PackageRepository;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.extension.OptionalPackage;
  import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
  import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
  import org.apache.log.Hierarchy;
  import org.apache.log.Priority;
  import org.apache.log.output.io.StreamTarget;
  
  /**
   * Application bootstrap.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public class Main
  {
      //=======================================================================
      // static
      //=======================================================================
  
      private static final ComponentType[] EMPTY_DEFS = new ComponentType[0];
      private static final ServiceDescriptor[] EMPTY_SVCS = new ServiceDescriptor[0];
      private static final File[] EMPTY_FILES = new File[0];
      private static final String DEFAULT_FORMAT =
          "[%7.7{priority}] (%{category}): %{message}\\n%{throwable}";
      private static final Resources REZ =
          ResourceManager.getPackageResources( DefaultRegistry.class );
  
     /**
      * Creation of a root type registry.
      */
      public static void main( String[] args )
      {
  
          DefaultRegistry registry = new DefaultRegistry();
  
          // create a configuration object containing the kernel profile
          // from which we can establish the logger and extensions directory
  
          String path = null;
          Configuration config = null;
          if( args.length > 0 )
            path = args[0];
          if( path == null )
          {
              // FIX ME
              // the following does not make sense - we need at least a target component
              config = new DefaultConfiguration("merlin", null );
          }
          else
          {
              config = getProfile( new File( path ) );
          }
  
          // create a bootstrap logger - this needs to be replaced with
          // the Avalon Exvalibur Logkit package
  
          Logger logger = null;
          Logger main = null;
          try
          {
              // FIX ME
              // logging setup should use the ECM logging setup model
  
              // create an internal logger for the registry
              final Hierarchy hierarchy = createHierarchy(
                 Priority.getPriorityForName( 
                  config.getChild("logger").getAttribute("priority","INFO") 
                )
              );
              logger = new LogKitLogger( hierarchy.getLoggerFor( "" ) );
              main = new LogKitLogger( hierarchy.getLoggerFor( "merlin" ) );
              registry.enableLogging( logger.getChildLogger("registry") );
          }
          catch( Throwable e )
          {
              System.out.println("Unexpected error while supplying registry logger.");
              e.printStackTrace( );
              System.exit(0);
          }
  
          // FIX ME - change this so that the DefaultRegistry uses the 
          // context classloader as a default value if none declared as a context
          // (i.e. make contextualization optional)
  
          // supply a context object with the classloader
   
          ClassLoader parent = Thread.currentThread().getContextClassLoader();
          DefaultContext context = new DefaultContext();
          context.put( DefaultRegistry.CLASSLOADER_KEY, parent );
          try
          {
              registry.contextualize( context );
          }
          catch( Throwable e )
          {
              main.error("Unexpected error while supply registry context.", e);
              System.exit(0);
          }
  
          // FIX ME - change this so that the DefaultRegistry creates an empty
          // extensions repository if none supplied - also, move this to 
          // context and declare it as optional
  
          // supply an service object with the type repository
  
          PackageRepository extensions = new DefaultPackageRepository( 
            Fileset.expandExtensions( config.getChild("extensions") ) );
          try
          {
              DefaultServiceManager manager = new DefaultServiceManager();
              manager.put( PackageRepository.ROLE, extensions );
              registry.service( manager );
          }
          catch( Throwable e )
          {
              main.error("Unexpected error while servicing the registry.", e );
              System.exit(0);
          }
  
          // configure the registry
  
          try
          {
              registry.configure( config.getChild("registry") );
          }
          catch( Throwable e )
          {
              main.error("Unexpected error while configuring the registry.", e );
              System.exit(0);
          }
          
          // initialize the registry 
  
          try
          {
              main.debug("initialization");
              registry.initialize( );
          }
          catch( Throwable e )
          {
              main.error("Unexpected error during registry initialization.", e);
              System.exit(0);
          }
  
          // type registry demo
  
          try
          {
              main.debug("execution");
              registry.execute();
          }
          catch( Throwable e )
          {
              final String error = "Execution error.";
              main.error( ExceptionUtil.printStackTrace( e ) );
          }
      }
  
      private static Hierarchy createHierarchy( Priority priority )
      {
          try
          {
              Hierarchy hierarchy = Hierarchy.getDefaultHierarchy();
              hierarchy.setDefaultLogTarget(
                  new StreamTarget( System.out, new AvalonFormatter( DEFAULT_FORMAT ) ) );
              hierarchy.setDefaultPriority( priority );
              return hierarchy;
          }
          catch( Throwable e )
          {
              final String error = "Unexpected exception while creating bootstrap logger.";
              throw new CascadingRuntimeException( error, e );
          }
      }
  
      private static Configuration getProfile( final File file )
      {
          try
          {
              DefaultConfigurationBuilder builder = new DefaultConfigurationBuilder();
              InputStream is = new FileInputStream( file );
              if( is == null )
              {
                  throw new RuntimeException(
                      "Could not load the configuration resource \"" + file + "\"" );
              }
              return builder.build( is );
          }
          catch( Throwable e )
          {
              final String error = "Unable to create configuration from file: " + file;
              throw new CascadingRuntimeException( error, e );
          }
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Profile.java
  
  Index: Profile.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import java.io.InputStream;
  import java.io.File;
  import java.io.IOException;
  import java.net.URL;
  import java.net.JarURLConnection;
  import java.net.URLClassLoader;
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Map;
  import java.util.Hashtable;
  import java.util.Properties;
  import java.util.Vector;
  import java.util.Iterator;
  import java.util.jar.Attributes;
  import java.util.jar.Manifest;
  import java.security.Policy;
  
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  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.CascadingRuntimeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder;
  import org.apache.avalon.framework.configuration.ConfigurationException;
  import org.apache.avalon.framework.context.Context;
  import org.apache.avalon.framework.parameters.Parameters;
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.excalibur.extension.PackageRepository;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.extension.OptionalPackage;
  import org.apache.excalibur.containerkit.metainfo.ComponentDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
  import org.apache.excalibur.containerkit.metadata.ComponentMetaData;
  import org.apache.excalibur.containerkit.metadata.DependencyMetaData;
  
  
  /**
   * Interface that defines a set of constraints applied to a component type.
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public interface Profile
  {
  
     /**
      * Default role name for this interface.
      */
      static final String ROLE = Profile.class.getName();
  
     /**
      * Returns the name of the component type profile.
      * @return the profile name
      */
      String getName();
  
     /**
      * Returns the component type that this profile constrains.
      * @return the component type
      */
      ComponentType getComponentType();
  
     /**
      * Returns the context to be supplied to an instance of the profile
      * @return the profile context object
      */
      Context getContext( Context parent );
  
     /**
      * Returns the configuration to be supplied to an instance of the profile
      * @return the profile configuration object
      */
      Configuration getConfiguration();
  
     /**
      * Returns the parameters to be supplied to an instance of the profile
      * @return the profile parameter object
      */
      Parameters getParameters();
  
      /**
       * Returns all dependency metadata for the profile.
       * @return the dependency metadata array
       */
      public DependencyMetaData[] getDependencies();
  
      /**
       * Returns dependency metadata for a name dependency.
       * @return the dependency metadata
       */
      public DependencyMetaData getDependency( String role );
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileException.java
  
  Index: ProfileException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.util.Enumeration;
  import java.util.Dictionary;
  import java.util.Hashtable;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate that there was an error relating to a profile.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class ProfileException
      extends CascadingException
  {
  
      private static final Hashtable EMPTY_TABLE = new Hashtable();
  
      private Dictionary m_errors;
  
      /**
       * Construct a new <code>ProfileException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public ProfileException( final String message )
      {
          this( null, message, null );
      }
  
      /**
       * Construct a new <code>ProfileException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       */
      public ProfileException( final Dictionary errors, final String message )
      {
          this( errors, message, null );
      }
  
  
      /**
       * Construct a new <code>ProfileException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ProfileException( final String message, final Throwable throwable )
      {
          this( null, message, throwable );
      }
  
      /**
       * Construct a new <code>ProfileException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ProfileException( final Dictionary errors, final String message, 
        final Throwable throwable )
      {
          super( message, throwable );
          if( errors != null )
          {
              m_errors = errors;
          }
          else
          {
              m_errors = EMPTY_TABLE;
          }
      }
  
     /**
      * Return the table of supplimentary messages.
      * @return the messages table
      */
      public Dictionary getDictionary()
      {
         return m_errors;
      }
  
     /**
      * Returns a stringified representation of the exception.
      * @return the exception as a string.
      */
      public String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append( super.toString() );
          buffer.append( " Errors: " + m_errors.size() );
          Enumeration keys = m_errors.keys();
          while( keys.hasMoreElements() )
          {
               Object key = keys.nextElement();
               buffer.append( "\n  source: " + key.toString() + " cause: " + m_errors.get( key ) );
          }
          return buffer.toString();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ProfileRuntimeException.java
  
  Index: ProfileRuntimeException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.util.Enumeration;
  import java.util.Dictionary;
  import java.util.Hashtable;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  /**
   * Exception to indicate that there was an error during assembly.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class ProfileRuntimeException
      extends CascadingRuntimeException
  {
  
      private static final Hashtable EMPTY_TABLE = new Hashtable();
  
      private Dictionary m_errors;
  
      /**
       * Construct a new <code>ProfileRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public ProfileRuntimeException( final String message )
      {
          this( null, message, null );
      }
  
      /**
       * Construct a new <code>ProfileRuntimeException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       */
      public ProfileRuntimeException( final Dictionary errors, final String message )
      {
          this( errors, message, null );
      }
  
  
      /**
       * Construct a new <code>ProfileRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ProfileRuntimeException( final String message, final Throwable throwable )
      {
          this( null, message, throwable );
      }
  
      /**
       * Construct a new <code>ProfileRuntimeException</code> instance.
       *
       * @param errors a list of warning messages related to the exception.
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public ProfileRuntimeException( final Dictionary errors, final String message, 
        final Throwable throwable )
      {
          super( message, throwable );
          if( errors != null )
          {
              m_errors = errors;
          }
          else
          {
              m_errors = EMPTY_TABLE;
          }
      }
  
     /**
      * Return the table of supplimentary messages.
      * @return the messages table
      */
      public Dictionary getDictionary()
      {
         return m_errors;
      }
  
     /**
      * Returns a stringified representation of the exception.
      * @return the exception as a string.
      */
      public String toString()
      {
          StringBuffer buffer = new StringBuffer();
          buffer.append( super.toString() );
          buffer.append( " Errors: " + m_errors.size() );
          Enumeration keys = m_errors.keys();
          while( keys.hasMoreElements() )
          {
               Object key = keys.nextElement();
               buffer.append( "\n  source: " + key.toString() + " cause: " + m_errors.get( key ) );
          }
          return buffer.toString();
      }
  
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Registry.java
  
  Index: Registry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.merlin.registry.ComponentType;
  import org.apache.excalibur.merlin.registry.Profile;
  
  /**
   * A service that provides support for location of components types.
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public interface Registry
  {
     /**
      * Default role.
      */
      static final String ROLE = Registry.class.getName();
  
     /**
      * Returns an array of component profiles representing candidate component types 
      * capable of acting as a service supplier relative to the supplied dependecy descriptor.
      * @param dependency the dependency descriptor to evaluate
      * @return the set of profiles
      */
      Profile[] getCandidateProfiles( DependencyDescriptor dependency );
  
     /**
      * Return a single preferred profile capable of supporting the supplied dependency.
      * @param dependency a consumer component dependecy declaration
      * @return the preferred candidate supplier profile or null if not candidates found
      */
      Profile getCandidateProfile( DependencyDescriptor dependency )
        throws UnresolvedProviderException;
  
  
     /**
      * Key value used to publish the application classloader.
      */
      static final String CLASSLOADER_KEY = "classloader";
  
      //public void register( Profile profile );
  
     /**
      * Test if the registry can resolve a request for a component with the supplied classname
      * @param classname a component or service class name
      * @return TRUE if the registry can service the request
      */
      //boolean hasComponentDefinition( String classname );
  
     /**
      * Returns an component defintion relative to the requested classname.
      * @param classname the class name of the componet defintion to locate or create
      * @return the corresponding component defintion
      * @exception AssemblyException if an error occurs during the construction of a 
      *    new component defintion
      */
      //ComponentType getComponentDefinition( String classname ) throws RegistryException;
  
     /**
      * Returns an array of component definitions capable of acting as a service supplier
      * relative to the supplied dependecy descriptor.
      * @param dependency the dependency descriptor to evaluate
      * @return the set of matching service descriptors capable of supporting the dependency
      */
      //public ComponentType[] getCandidateProviders( DependencyDescriptor dependency );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/RegistryException.java
  
  Index: RegistryException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate that there was a repository related error.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class RegistryException
      extends CascadingException
  {
  
      /**
       * Construct a new <code>RegistryException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public RegistryException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>AssemblyException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public RegistryException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/RegistryRuntimeException.java
  
  Index: RegistryRuntimeException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.avalon.framework.CascadingRuntimeException;
  
  /**
   * Exception to indicate that there was a repository related runtime error.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class RegistryRuntimeException
      extends CascadingRuntimeException
  {
  
      /**
       * Construct a new <code>RegistryRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       */
      public RegistryRuntimeException( final String message )
      {
          this( message, null );
      }
  
      /**
       * Construct a new <code>RegistryRuntimeException</code> instance.
       *
       * @param message The detail message for this exception.
       * @param throwable the root cause of the exception
       */
      public RegistryRuntimeException( final String message, final Throwable throwable )
      {
          super( message, throwable );
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  xinfo-load=Creating ComponentInfo from {0}.
  xinfo-missing=XINFO resource unavailable for class "{0}".
  xinfo-parse-error=Error occured while parsing xinfo resource "{0}".
  xinfo-nocreate=Failed to create ComponentInfo from resource "{0}" (Reason: {1}).
  xinfo-props-error=Unable to construct attributes using key "{0}" (Reason: {1}).
  cinfo-nocreate=Failed to create ComponentDescriptor from resource "{0}" (Reason: {1}).
  cinfo-properties-error=Failed to create ComponentInfo attributes from resource "{0}" (Reason: {1}).
  sinfo-noname=Missing name attribute in service declaration from resource "{0}".
  sinfo-version=Bad service version in resource "(Reason: {0})".
  sinfo-nocreate=Failed to create ServiceInfo from resource "{0}" (Reason: {1}).
  dinfo-service-error="Could not create dependecy service delcaration (Reason: {0}).
  dinfo-nocreate="Could not create dependecy delcaration from resource "{0}" (Reason: {1}).
  
  missing.extension=Unable to locate an extension that is required by application.\n  Extension Name: {0}\n  Specification Vendor: {1}\n  Specification Version: {2}\n  Implementation Vendor: {3}\n  Implementation Vendor-Id: {4}\n  Implementation Version: {5}\n  Implementation URL: {6}
  unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader for application.
  bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it impossible to load a manifest.
  available-extensions=Available extensions: {0}
  required-extensions=The list of required extensions for application includes: {0}
  optional-packages-added=The list of "Optional Packages" added to the application include: {0}
  classpath-entries=The list of classpath entrys for the application include: {0}
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/Selector.java
  
  Index: Selector.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.excalibur.merlin.registry.Profile;
  
  
  /**
   * Interface implemented by selection services that can provide a sorted 
   * set of profiles for a paricular service type.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public interface Selector
  {
     /**
      * Returns the preferred profile for an available selection of provider profiles.
      * @param profiles the set of profiles of potential service providers
      * @return the preferred provider or null if no satisfactory provider can be established 
      *    from the supplied profiles.
      */
      Profile select( Profile[] profiles ) throws UnresolvedProviderException;
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/ServiceRegistry.java
  
  Index: ServiceRegistry.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.merlin.registry;
  
  import java.util.List;
  import java.util.LinkedList;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.Iterator;
  import org.apache.avalon.framework.CascadingException;
  import org.apache.avalon.framework.logger.Logger;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.excalibur.merlin.registry.ComponentType;
  import org.apache.excalibur.merlin.registry.Profile;
  import org.apache.excalibur.merlin.registry.ComponentDefinition;
  import org.apache.excalibur.containerkit.metainfo.ServiceDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ServiceDesignator;
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  import org.apache.excalibur.containerkit.metainfo.ComponentInfo;
  import org.apache.excalibur.containerkit.infobuilder.ComponentInfoBuilder;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  
  /**
   * Internal table that holds available component type keyed relative
   * to the service it provides.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  final class ServiceRegistry extends AbstractLogEnabled
  {
  
      //=======================================================================
      // state
      //=======================================================================
  
      private ComponentInfoBuilder m_infoBuilder = new ComponentInfoBuilder();
  
      private ClassLoader m_classloader;
      private Configuration m_profiles;
      private DefaultRegistry m_registry;
  
     /**
      * Component type lists keyed by service designator.
      */
      private Hashtable m_services = new Hashtable();
  
     /**
      * Component types keyed by classname.
      */
      private Hashtable m_types = new Hashtable();
  
     /**
      * The set of installed profiles keyed by profile name.
      */
      private Hashtable m_installed = new Hashtable();
  
      //=======================================================================
      // constructor
      //=======================================================================
  
     /**
      * Creation of a new service registry.
      * @param registry the registry that will be supplied to new component defintions
      * @param loader the registry class loader
      * @param profiles the configuration fragment containing explicit component profiles
      */
      public ServiceRegistry( DefaultRegistry registry, ClassLoader loader, Configuration profiles )
      {
          m_classloader = loader;
          m_profiles = profiles;
          m_registry = registry;
      }
  
      //=======================================================================
      // LogEnabled
      //=======================================================================
          
     /**
      * Set the logging channel for the service registry.
      * @param logger the logging channel
      */
      public void enableLogging( Logger logger )
      {
          super.enableLogging( logger );
          m_infoBuilder.enableLogging( logger.getChildLogger("builder") );
      }
  
      //=======================================================================
      // ServiceRegistry
      //=======================================================================
  
     /**
      * Register a potential supplier component type.  The implementation will
      * create a component type instance for the entry if not already known and 
      * return the existing or new instance to the invoking client.
      *
      * @param classname the component class name
      * @return the component type
      */
      public ComponentType register( String classname ) throws Exception
      {
          ComponentType type = getComponentType( classname );
          if( type == null )
          {
              type = createComponentDefinition( classname );
              register( type );
          }
          return type;
      }
  
     /**
      * Install a provider and return the profile.
      * @param classname the classname of the provider to install
      * @param name the component profile to use for the provider
      */
      public Profile install( String classname, String name ) throws Exception
      {
          return install( register( classname ).getProfile( name ) );
      }
  
     /**
      * Install a provider and return the profile.
      * @param classname the classname of the provider to install
      * @param name the component profile to use for the provider
      */
      public Profile install( Profile profile )
      {
          m_installed.put( profile.getName(), profile ); 
          return profile;  
      }
  
     /**
      * Return the set of profiles representing the application scope.
      * @return the installed profiles
      */
      public Profile[] getInstalledProfiles()
      {
          return (Profile[]) m_installed.values().toArray( new Profile[0] );
      }
  
     /**
      * Returns the set of component types know to the registry.
      * @return the set of component types registered with the registry
      */
      public ComponentType[] getTypes()
      {
          return (ComponentType[]) m_types.entrySet().toArray( new ComponentType[0] );
      }
  
     /**
      * Returns the set of component types know to the registry that are capable of 
      * supporting the supplied service.
      * @return the set of candidate component types
      */
      public ComponentType[] getComponentTypes( ServiceDesignator service )
      {
          return (ComponentType[]) getList( service ).toArray( new ComponentType[0] );
      }
  
     /**
      * Returns a registered component type.
      * @return the component type from the registry or null if the type is unknown
      */
      public ComponentType getComponentType( String classname ) throws IllegalArgumentException
      {
          return (ComponentType) m_types.get( classname );
      }
  
  
      public Profile[] getProfiles( ServiceDesignator service )
      {
          Vector vector = new Vector();
          ComponentType[] components = getComponentTypes( service );
          for( int i=0; i<components.length; i++ )
          {
              try
              {
                  Profile[] profiles = components[i].getProfiles();
                  for( int j=0; j<profiles.length; j++ )
                  {
                      vector.add( profiles[j] );
                  }
              }
              catch( Throwable e )
              {
                  getLogger().warn("skipping type: " + components[i], e  );
              }
          }
          return (Profile[]) vector.toArray( new Profile[0] );
      }
  
      public Profile getCandidateProfile( DependencyDescriptor dependency )
          throws UnresolvedProviderException
      {
          Profile[] profiles = getProfiles( dependency.getService() );
          if( profiles.length == 0 )
          {
              throw new UnresolvedProviderException( "No candidates matching dependency.", dependency );
          }
          else
          {
              Selector selector = getSelector( dependency );
              if( selector == null )
              {
                  return profiles[0];
              }
              else
              {
                  return selector.select( profiles );
              }
          }
      }
  
      private void register( ComponentType type )
      {
          getLogger().debug("registering provider type: " + getImplementationKey( type ) );
          m_types.put( getImplementationKey( type ), type );
          ServiceDescriptor[] services = type.getComponentInfo().getServices();
          for( int i=0; i<services.length; i++ )
          {
              register( services[i].getServiceDesignator(), type );
          }
      }
  
      private Selector getSelector( DependencyDescriptor dependency )
      {
  
          // if the dependency declares a selector class then use that, 
          // otherwise, look for a default service type selector
  
          String selectorName = dependency.getAttribute("avalon.service.selector");
          if( selectorName == null )
            selectorName = dependency.getService().getClassname() + "Selector";
  
          try
          {
              Class clazz = m_classloader.loadClass( selectorName );
              Selector selector = (Selector) clazz.newInstance();
              if( selector instanceof LogEnabled ) 
              {
                  ((LogEnabled)selector).enableLogging( getLogger().getChildLogger("selector") );
              }
              return selector;
          }
          catch( Throwable e )
          {
              return null;
          }
      }
  
  
      private void register( ServiceDesignator service, ComponentType type )
      {
          List list = getList( service );
          list.add( type );
      }
  
      private List getList( ServiceDesignator service )
      {
          List list = null;
          Iterator iterator = m_services.keySet().iterator();
          while( iterator.hasNext() )
          {
              ServiceDesignator singleton = (ServiceDesignator) iterator.next();
              if( singleton.matches( service ) )
              {
                  list = (List) m_services.get( singleton );
              }
          }
          if( list == null ) 
          {
              getLogger().debug("registering service type: " + service );
              list = new LinkedList();
              m_services.put( service, list );
          }
          return list;
      }
  
      private String getImplementationKey( ComponentType type )
      {
          return type.getComponentInfo().getComponentDescriptor().getImplementationKey();
      }
  
     /**
      * Create a new ComponentDefintion instance.
      * @param registry the component defintion registry
      * @param classname the name of the component class
      * @return the component info instance
      * @exception AssemblyException if an assembly error occurs
      */
      private ComponentDefinition createComponentDefinition( final String classname ) 
        throws RegistryException
      {
          if( classname == null )
            throw new NullPointerException("classname");
  
          if( classname.indexOf("/") > -1 )
            throw new IllegalArgumentException( "invlaid classname" );
  
          try
          {
              ComponentInfo info = m_infoBuilder.build( classname, m_classloader );
              final String name = info.getComponentDescriptor().getName();
              Configuration[] profiles = ConfigurationUtil.match( 
                m_profiles, "component", "class", classname );
              ComponentDefinition type = new ComponentDefinition( m_registry, info, profiles );
              type.enableLogging( getLogger().getChildLogger( name ) );
              return type;
          }
          catch( Throwable e )
          {
              final String error = "Internal error while attempting to read xinfo.";
              throw new RegistryException( error, e );
          }
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/UnresolvedProviderException.java
  
  Index: UnresolvedProviderException.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  
  package org.apache.excalibur.merlin.registry;
  
  import org.apache.excalibur.containerkit.metainfo.DependencyDescriptor;
  
  import org.apache.avalon.framework.CascadingException;
  
  /**
   * Exception to indicate that a service provider could not be found.
   *
   * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/01 04:27:15 $
   */
  public final class UnresolvedProviderException
      extends CascadingException
  {
  
      private DependencyDescriptor m_dependency;
  
     /**
      * Construct a new <code>UnresolvedProviderException</code> instance.
      *
      * @param dependency the unresolved dependency
      */
      public UnresolvedProviderException( String message, DependencyDescriptor dependency )
      {
          this( message, dependency, null );
      }
  
     /**
      * Construct a new <code>UnresolvedProviderException</code> instance.
      *
      * @param dependency the unresolved dependency
      * @param cause the causal exception
      */
      public UnresolvedProviderException( String message, DependencyDescriptor dependency, Throwable cause )
      {
          super( message, cause );
          m_dependency = dependency;
      }
  
      public String getMessage()
      {
          return "Could not resolve provider for dependency " 
            + m_dependency.getService() 
            + " for role: " + m_dependency.getRole() 
            + " due to " + super.getMessage();
      }
  }
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/package.html
  
  Index: package.html
  ===================================================================
  
  <body>
  <p>
  A geneneric container supporting component lifecycle management. The container serves as a repository for component types and provides support for a type hierarchy based on an formal component type and profile model.  The repository enables resolution of component types based on a classloader, extension directory set defintion, supplied classpath, and application directives.  Components are established based on the publication of components within a jar file manifest together with explicit component profile directives included within the repository configuration. Given a manifest declaration of a component implementation class, a component type definition will be resolvable providing the registry can resolve all type constraints (specifically the validation of the dependecies of candidate supplier components).
  </p>
  <h3>Funtional Summary</h3>
  <ul>
  <li>Geneneric container supporting component lifecycle management.
  <li>Hierachical container composition.
  </ul>
  <h3>Key Features</h3>
  <p>A primary objective of this container is to provide simple deployment of components with minimal administration overhead.  In many cases, no component assembly directives are required as the container will apply assembly logic based on the meta-information association with component types that are either explicity declared, or implicly located via a classpath and extension directories.</p>
  <ul>
  <li>Stand-alone and embeddable deployment.
  <li>Automatic component profile generation.
  <li>Automatic assembly of components based on dependency and service production declarations.
  <li>Service provider selection plug-in architecture.
  <li>Customization of application content.
  <li>Support for multiple extension directories.
  <li>Protected classloading.
  </ul>
  
  <h3>Object Model</h3>
  <p>The container object model provides a simplified view of the <code>containerkit</code> framework.  The princincipal entry point is the {@link org.apache.excalibur.merlin.registry.Registry} and the associated default component based implementation {@link org.apache.excalibur.merlin.registry.DefaultRegistry}.  The registry acts as a component type repository.  Component types are exposed as instances of the {@link org.apache.excalibur.merlin.registry.ComponentType} interface.  Each component type represents a concrete component implementation class.  For each component type, the container associates at least one instantiation {@link org.apache.excalibur.merlin.registry.Profile}.  A profile is either a default profile generated by the container based on meta-information derived from the type, or, an explicit profile declared by the component user under the registry configuration.  Multiple profile for a particular component type can coexist in the same container.
  
  <h3>Package Structure (UML)</h3>
  <p><img src=doc-files/registry.gif border=0></p>
  </body>
  
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/registry/doc-files/registry.gif
  
  	<<Binary file>>
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>