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/30 09:05:56 UTC

cvs commit: jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder XMLFacilityCreator.java XMLTypeCreator.java

mcconnell    2002/07/30 00:05:56

  Modified:    assembly build.xml
               assembly/src/etc kernel.xml sevak.xml
               assembly/src/java/org/apache/excalibur/merlin Main.java
               assembly/src/java/org/apache/excalibur/merlin/assembly
                        ProfileManager.java ProfileRegistry.java
                        TypeManager.java TypeRegistry.java
               assembly/src/java/org/apache/excalibur/merlin/assembly/resource
                        LifecycleHelper.java ProfileDesignator.java
                        ResourceProvider.java
               assembly/src/java/org/apache/excalibur/merlin/container/builder
                        ContainerCreator.java XMLContainerCreator.java
               assembly/src/java/org/apache/excalibur/merlin/kernel/builder
                        XMLKernelCreator.java
               assembly/src/java/org/apache/excalibur/merlin/model
                        Association.java Import.java Profile.java
               assembly/src/java/org/apache/excalibur/meta
                        componentinfo.dtd
               assembly/src/java/org/apache/excalibur/meta/info
                        ExtensionDescriptor.java Facility.java
                        PhaseDescriptor.java
               assembly/src/java/org/apache/excalibur/meta/info/builder
                        XMLFacilityCreator.java XMLTypeCreator.java
  Added:       assembly/src/java/org/apache/excalibur/merlin/assembly
                        Resources.properties
                        UnresolvedManagerException.java
  Log:
  Addition of support for pluggable extensions.
  
  Revision  Changes    Path
  1.33      +9 -12     jakarta-avalon-excalibur/assembly/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/build.xml,v
  retrieving revision 1.32
  retrieving revision 1.33
  diff -u -r1.32 -r1.33
  --- build.xml	26 Jul 2002 15:01:10 -0000	1.32
  +++ build.xml	30 Jul 2002 07:05:54 -0000	1.33
  @@ -70,7 +70,7 @@
     <target name="dist" depends="build"/>
     <target name="meta" depends="meta.javadoc"/>
     <target name="merlin" depends="merlin.javadoc"/>
  -  <target name="all" depends="clean,deploy,docs"/>
  +  <target name="all" depends="clean,deploy,javadocs,docs"/>
     <target name="javadocs" depends="meta.javadoc,merlin.javadoc" />
     <target name="javadoc" depends="meta.javadoc,merlin.javadoc" />
   
  @@ -141,6 +141,7 @@
       <uptodate property="meta.uptodate" targetfile="${dist.dir}/${meta.jar}">
         <srcfiles dir="${src.dir}">
            <include name="**/meta/**/*.*"/>
  +         <include name="etc/meta.mf"/>
         </srcfiles>
       </uptodate>
     </target>
  @@ -180,12 +181,14 @@
       </uptodate>
     </target>
   
  -  <target name="demo.build" depends="demo.context" unless="demo.uptodate" >
  +  <target name="demo.build" depends="merlin.build,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.class.path" />
  +          <pathelement path="${dist.dir}/${meta.jar}" />
  +          <pathelement path="${dist.dir}/${merlin.jar}" />
   	  </classpath>
           <src path="demo/src/java" />
         </javac>
  @@ -265,7 +268,7 @@
       <copy todir="${docs.dir}/api/meta" file="${src.dir}/etc/meta.gif"/>
     </target>
   
  -  <target name="deploy" depends="build">
  +  <target name="deploy" depends="dist">
        <mkdir dir="${extensions}"/>
        <copy todir="${extensions}" preservelastmodified="true">
          <fileset dir="${avalon.tools.path}/lib">
  @@ -294,16 +297,10 @@
        </java>
     </target>
   
  -
     <target name="patch">
  -    <replace 
  -       token="TypeManagerException" 
  -       value="TypeException" dir="src/java">
  -     <include name="org/apache/excalibur/merlin/**/*.*"/>
  -    </replace>
  -    <replace 
  -       token="TypeManagerRuntimeException" 
  -       value="TypeRuntimeException" dir="src/java">
  +    <replace dir="${src.dir}/java" 
  +       token="org.apache.excalibur.merlin.model.TargetProvider" 
  +       value="org.apache.excalibur.merlin.kernel.model.TargetProvider" >
        <include name="org/apache/excalibur/merlin/**/*.*"/>
       </replace>
     </target>
  
  
  
  1.19      +11 -6     jakarta-avalon-excalibur/assembly/src/etc/kernel.xml
  
  Index: kernel.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/kernel.xml,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- kernel.xml	29 Jul 2002 06:14:29 -0000	1.18
  +++ kernel.xml	30 Jul 2002 07:05:54 -0000	1.19
  @@ -58,7 +58,7 @@
        for completness. 
        -->
   
  -     <categories priority="INFO">
  +     <categories priority="DEBUG">
          <category priority="WARN"  name="loader" />
          <category priority="WARN"  name="loader.assembly" />
          <category priority="WARN"  name="loader.lifecycle" />
  @@ -82,7 +82,7 @@
   
        <component name="complex" class="org.apache.excalibur.playground.ComplexComponent" activation="true">
   
  -        <categories priority="INFO">
  +        <categories priority="DEBUG">
             <category name="init" priority="DEBUG" />
           </categories>
   
  @@ -128,10 +128,8 @@
   
          <container name="demo">
   
  -         <categories priority="WARN">
  +         <categories priority="INFO">
              <category priority="WARN"  name="loader" />
  -           <category priority="WARN"  name="loader.assembly" />
  -           <category priority="WARN"  name="loader.lifecycle" />
            </categories>
   
            <!--
  @@ -143,10 +141,17 @@
            to the instantiated component is based primarily on this configuration declared here, 
            and defaults derived from SimpleComponent.xconfig.
            -->
  -         <component name="simple" class="org.apache.excalibur.playground.SimpleComponent" enabled="true" activation="true">
  +         <component name="simple" 
  +           class="org.apache.excalibur.playground.SimpleComponent" 
  +           enabled="true" 
  +           activation="true">
  +
  +           <categories priority="DEBUG"/>
  +
              <configuration>
                <message>This is a custom message.</message>
              </configuration>
  +
            </component>
   
          </container>
  
  
  
  1.7       +1 -1      jakarta-avalon-excalibur/assembly/src/etc/sevak.xml
  
  Index: sevak.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/etc/sevak.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- sevak.xml	25 Jul 2002 18:07:15 -0000	1.6
  +++ sevak.xml	30 Jul 2002 07:05:54 -0000	1.7
  @@ -86,7 +86,7 @@
           activation="true">
   
           <context>
  -          <import key="app.home" name="home"/>
  +          <import key="app.home" name="avalon:work"/>
           </context>
   
           <!-- you need to provide your own sevak-conf.xml file if you want to override defaults -->
  
  
  
  1.10      +2 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/Main.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Main.java	29 Jul 2002 06:14:29 -0000	1.9
  +++ Main.java	30 Jul 2002 07:05:55 -0000	1.10
  @@ -81,7 +81,7 @@
    * assembly profile.
    *
    * <pre>
  - *   <strong><font color="darkred">$ java -jar .\extensions\merlin.jar src\etc\kernel.xml</font></strong>
  + *   <strong><font color="darkred">$ java -Djava.ext.dirs=.\extensions -jar .\extensions\merlin.jar src\etc\kernel.xml</font></strong>
    *
    *   <i><font color="darkslategray">The following logging trace shows the kernel initialization and the invocation of a startup request.</font></i>
    *
  
  
  
  1.2       +143 -13   jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileManager.java
  
  Index: ProfileManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProfileManager.java	29 Jul 2002 06:14:29 -0000	1.1
  +++ ProfileManager.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -40,10 +40,13 @@
   import org.apache.excalibur.merlin.model.Profile;
   import org.apache.excalibur.merlin.model.ResourceDesignator;
   import org.apache.excalibur.merlin.model.builder.ProfileBuilder;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
   import org.apache.excalibur.meta.info.ServiceDescriptor;
   import org.apache.excalibur.meta.info.ReferenceDescriptor;
   import org.apache.excalibur.meta.info.DependencyDescriptor;
  +import org.apache.excalibur.meta.info.ExtensionDescriptor;
   import org.apache.excalibur.meta.info.Type;
  +import org.apache.excalibur.meta.info.Facility;
   import org.apache.excalibur.meta.info.builder.TypeBuilder;
   import org.apache.excalibur.meta.verifier.ComponentVerifier;
   
  @@ -147,11 +150,17 @@
       // constructor
       //===================================================================
   
  -    public ProfileManager( ClassLoader parent, String name )
  +   /**
  +    * Creation of a new Profile Manager.
  +    * @param parent the parent classloader
  +    * @param name the name to assign to this classloader (used with logging)
  +    * @param root if TRUE, logging catagories are top level, otherwise logging 
  +    *    catagories are subsidary to the parent
  +    */
  +    public ProfileManager( ClassLoader parent, String name, boolean root )
       {
           super( parent );
           m_name = name;
  -
           if( parent instanceof ProfileManager )
           {
               m_parent = (ProfileManager) parent;
  @@ -163,6 +172,14 @@
               m_path = DELIMITER + name;
               m_map = new DependencyGraph();
           }
  +        if( !root )
  +        {
  +            m_path = m_parent.getPath() + DELIMITER + name;
  +        }
  +        else 
  +        {
  +            m_path = DELIMITER + name;
  +        }
       }
   
       //=======================================================================
  @@ -246,7 +263,7 @@
                   ResourceDesignator resource = getResource( profile );
                   if( resource.getState() == ResourceDesignator.NOT_STARTED )
                   {
  -                   getLogger().info( "STARTING: " + profile ); 
  +                   getLogger().info( "starting: " + profile ); 
                      resource.getInstance();
                   }
               }
  @@ -264,7 +281,7 @@
                   ResourceDesignator resource = getResource( profile );
                   if( resource.getState() == ResourceDesignator.STARTED )
                   {
  -                   getLogger().info( "STOPPING: " + profile ); 
  +                   getLogger().info( "stopping: " + profile ); 
                      resource.release();    
                   }
               }
  @@ -315,6 +332,7 @@
           final String classname = profile.getType().getInfo().getImplementationKey();
           if( isLocal( classname ) )
           {
  +            getLogger().info("adding: " + profile );
               if( m_profiles.get( name ) != null )
                 throw new IllegalArgumentException(
                   "Profile named '" + name + "' already registered.");
  @@ -323,8 +341,27 @@
               ServiceDescriptor[] services = profile.getType().getServices();
               for( int i=0; i<services.length; i++ )
               {
  +                //
  +                // register the profile against the service it provides
  +                // so we can lookup the profile later based on the supplied
  +                // service descriptor
  +                //
  +
                   addProfile( services[i].getService(), profile );
               }
  +
  +            if( profile.getType() instanceof Facility )
  +            {
  +                //
  +                //  the profile is a facility so we need to 
  +                // cross reference it against the extension support it 
  +                // provides
  +                //
  +                
  +                Facility facility = (Facility) profile.getType();
  +                addProfile( facility.getExtensions(), profile );
  +            }
  +
               getLogger().info("added: " + profile );
           }
           else
  @@ -373,6 +410,39 @@
           return local;
       }
   
  +    public Profile[] getProfiles( PhaseDescriptor phase )
  +    {
  +        Profile[] local = getLocalProfiles( phase );
  +        ProfileManager parent = getParentManager();
  +        if( parent != null )
  +        {
  +            ArrayList list = new ArrayList();
  +            for( int i=0; i<local.length; i++ )
  +            {
  +                list.add( local[i] );
  +            }
  +            Profile[] profiles = parent.getProfiles( phase );
  +            for( int i=0; i<profiles .length; i++ )
  +            {
  +                list.add( profiles[i] );
  +            }
  +            return (Profile[]) list.toArray( new Profile[0] );
  +        }
  +        return local;
  +    }
  +
  +   /**
  +    * Return a single profile matching a supplied phase spec.
  +    *
  +    * @param phase the phase specification
  +    * @return the selected profile
  +    */
  +    public Profile getProfile( PhaseDescriptor phase )
  +    {
  +        Profile[] profiles = getProfiles( phase );
  +        return getSelector( phase ).select( profiles );
  +    }
  +
      /**
       * Return a single profile matching a supplied versioned interface spec 
       * using a supplied selector.
  @@ -432,11 +502,14 @@
           }
       }
   
  -    private ResourceDesignator getLocalResource( Profile profile )
  -    {
  -        return (ResourceDesignator) m_resources.get( profile );
  -    }
  -
  +   /**
  +    * Assemble a set of profiles into a consistent application.  This method 
  +    * attempts to establish associations between all dependencies in order to 
  +    * resolve an operational application context.
  +    *
  +    * @param profiles the set of profiles constituting the core components
  +    *    from which the associations between components will be based
  +    */
       public void assemble( Profile[] profiles ) throws Exception
       {
           m_registry.assemble( profiles );
  @@ -510,7 +583,7 @@
       }
   
      /**
  -    * Returns the ser of exportable resources.
  +    * Returns the set of exportable resources.
       *
       * @return the resource sequence
       */
  @@ -538,6 +611,12 @@
       // private
       //=============================================================================
   
  +    private ResourceDesignator getLocalResource( Profile profile )
  +    {
  +        return (ResourceDesignator) m_resources.get( profile );
  +    }
  +
  +
      /**
       * Returns the set of profiles capable of supporting the supplied service.
       * @return the set of candidate component types
  @@ -548,6 +627,15 @@
       }
   
      /**
  +    * Returns the set of profiles capable of supporting the supplied phase.
  +    * @return the set of candidate profiles
  +    */
  +    private Profile[] getLocalProfiles( PhaseDescriptor phase )
  +    {
  +        return getTable( phase.getReference() ).getProfiles();
  +    }
  +
  +   /**
       * Returns the parent profile manager or null if this is the root manager.
       * @return the parent
       */
  @@ -556,7 +644,6 @@
           return m_parent;        
       }
   
  -
       private void addProfile( ReferenceDescriptor reference, Profile profile )
       {
           ProfileTable table = getTable( reference );
  @@ -564,6 +651,23 @@
       }
   
      /**
  +    * Add a profile and cross-reference this relative to the extensions it 
  +    * is capable of supporting.
  +    *
  +    * @param extensions the set of extensions the facility supports
  +    * @param profile the profile
  +    */
  +    private void addProfile( ExtensionDescriptor[] extensions, Profile profile )
  +    {
  +        for( int i=0; i<extensions.length; i++ )
  +        {
  +            getLogger().debug("adding profile against extension: " + extensions[i].getReference() );
  +            ProfileTable table = getTable( extensions[i].getReference() );
  +            table.add( profile );
  +        }
  +    }
  +
  +   /**
       * Return a table that holds profiles supporting the supplied service reference.
       */
       private ProfileTable getTable( ReferenceDescriptor service )
  @@ -583,6 +687,32 @@
           return table;
       }
   
  +    private Selector getSelector( PhaseDescriptor phase )
  +    {
  +
  +        // if the phase declares a selector class then use that, 
  +        // otherwise, look for a default phase type selector - if none
  +        // use the DefaultSelector
  +
  +        String selectorName = phase.getAttribute("avalon:selector");
  +        if( selectorName == null )
  +          selectorName = phase.getReference().getClassname() + "Selector";
  +        try
  +        {
  +            Class clazz = loadClass( selectorName );
  +            Selector selector = (Selector) clazz.newInstance();
  +            if( selector instanceof LogEnabled ) 
  +            {
  +                ((LogEnabled)selector).enableLogging( getLogger().getChildLogger("selector") );
  +            }
  +            return selector;
  +        }
  +        catch( Throwable e )
  +        {
  +            return m_selector;
  +        }
  +    }
  +
       private Selector getSelector( DependencyDescriptor dependency )
       {
   
  @@ -590,7 +720,7 @@
           // otherwise, look for a default service type selector - if none
           // use the DefaultSelector
   
  -        String selectorName = dependency.getAttribute("avalon.service.selector");
  +        String selectorName = dependency.getAttribute("avalon:selector");
           if( selectorName == null )
             selectorName = dependency.getService().getClassname() + "Selector";
           try
  
  
  
  1.2       +166 -14   jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileRegistry.java
  
  Index: ProfileRegistry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/ProfileRegistry.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProfileRegistry.java	29 Jul 2002 06:14:29 -0000	1.1
  +++ ProfileRegistry.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -28,7 +28,9 @@
   import org.apache.excalibur.meta.info.ServiceDescriptor;
   import org.apache.excalibur.meta.info.ReferenceDescriptor;
   import org.apache.excalibur.meta.info.DependencyDescriptor;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
   import org.apache.excalibur.meta.info.Type;
  +import org.apache.excalibur.meta.info.Facility;
   import org.apache.excalibur.meta.verifier.ComponentVerifier;
   import org.apache.excalibur.merlin.model.Profile;
   import org.apache.excalibur.merlin.model.ResourceDesignator;
  @@ -80,6 +82,11 @@
   
      /**
       * For all of the explicity declared profiles, initiate dependency correlation.
  +    * The implementation will attempt to assembly each profile in the order 
  +    * supplied.
  +    *
  +    * @param profiles the set of profiles to assemble
  +    * @exception Exception if an error occurs during assembly
       */
       public void assemble( Profile[] profiles ) throws Exception
       {
  @@ -90,7 +97,8 @@
               ArrayList visited = new ArrayList();
               assembleProfile( profile, visited, "" );
   
  -            final String name = m_classloader.getPath() + ProfileManager.DELIMITER + profile.getName();
  +            final String name = 
  +              m_classloader.getPath() + ProfileManager.DELIMITER + profile.getName();
               final ResourceDesignator resource = m_classloader.getResource( profile, true );
               getLogger().debug( "created explicit resource for: " + name );
               m_map.add( profile );
  @@ -108,13 +116,36 @@
           return m_classloader.getProfiles( service );
       }
   
  +   /**
  +    * Returns the set of component types know to the registry that are capable of 
  +    * supporting the supplied phase.
  +    * @return the set of candidate component types
  +    */
  +    Profile[] getProfiles( PhaseDescriptor phase )
  +    {
  +        return m_classloader.getProfiles( phase );
  +    }
  +
  +
  +   /**
  +    * Assemble a single profile.
  +    * @param profile the profile to assemble
  +    * @param visited the set of profiles already assessed
  +    * @param extensions the set of extensions already visited
  +    * @param pad used in formatting log messages
  +    */
       private void assembleProfile( 
         Profile profile, List visited, String pad ) throws Exception
       {
           getLogger().debug( pad + "assemble: " + profile );
           String pad2 = pad + "  ";
  +
  +        //
  +        // for all of the declared depedencies - make sure the 
  +        // dependency is satisfied
  +        //
  +
           visited.add( profile );
  -        String warning = null;
           DependencyDescriptor[] dependencies = profile.getType().getDependencies();
           for( int i=0; i<dependencies.length; i++ )
           {
  @@ -122,35 +153,156 @@
               String role = dependency.getRole();
               if( profile.getAssociation( role ) == null )
               {
  -                Profile[] candidates = assembleProfile( profile, dependency, visited, pad2 );
  -                if( candidates.length == 0 )
  +
  +                //
  +                // there is an unresolve association for one of the depedencies
  +                // of the supplied profile - invoking assembleSolutions causes 
  +                // the resolution of associations between potential suppliers
  +                // of the depedency - if assembleSolutions returns true, we 
  +                // have at least one solution
  +                //
  +
  +                boolean ok = assembleProviders( profile, dependency, visited, pad2 );
  +                if( !ok )
                   {
  +                    final String message =
  +                      "No solution for the dependency: " 
  +                      + dependency.getService() + " in profile: " + profile 
  +                      + ", for the role: " + dependency.getRole();
  +                    getLogger().error( pad + "  " + message );
  +
                       profile.setEnabled( false );
  -                    final Exception problem = new Exception( "No available candidates." );
  +                    final Exception problem = new Exception( message );
                       throw new UnresolvedProviderException( dependency, problem );
                   }
   
  +                //
  +                // select the preferred provider for the dependency - the depedency
  +                // argument contains the selection policy to apply
  +                //
  +                
                   Profile supplier = m_classloader.getProfile( dependency );
                   if( supplier == null )
                   {
  +                    final String message =
  +                      "Empty selection for the dependency: " 
  +                      + dependency.getService() + " in profile: " + profile 
  +                      + ", for the role: " + dependency.getRole();
  +                    getLogger().error( pad + "  " + message );
  +
                       profile.setEnabled( false );
                       final Exception problem = new Exception( "No suitable candidates." );
  -                    throw new UnresolvedProviderException( dependency );
  +                    throw new UnresolvedProviderException( dependency, problem );
                   }
   
  +                //
  +                // associate the supplier to the profile via an association
  +                //
  +
  +                getLogger().debug( pad + "  selection: " + supplier );
                   ResourceDesignator resource = m_classloader.getResource( supplier, true );
                   profile.addProvider( role, resource );
  +                m_map.add( supplier );
  +            }
  +        }
  +
  +        //
  +        // for all of the lifecycle phases - make sure we assign an extension
  +        // manager 
  +        //
  +
  +        PhaseDescriptor[] phases = profile.getType().getPhases();
  +        for( int i=0; i<phases.length; i++ )
  +        {
  +            PhaseDescriptor phase = phases[i];
  +            if( profile.getExtension( phase ) == null )
  +            {
  +                boolean ok = assembleManagers( profile, phase, visited, pad2 );
  +                if( !ok )
  +                {
  +                    final String message = "Could not locate an extension for the phase: " 
  +                      + phase.getReference() + ", in profile: " + profile;
  +                    getLogger().error( pad + "  " + message );
  +
  +                    profile.setEnabled( false );
  +                    final AssemblyException problem = new AssemblyException( message );
  +                    throw new UnresolvedManagerException( phase, problem );
  +                }
  +
  +                //
  +                // select the preferred provider for the phase - the phase
  +                // argument contains the selection policy to apply
  +                //
  +                
  +                Profile supplier = m_classloader.getProfile( phase );
  +                if( supplier == null )
  +                {
  +                    final String message =
  +                      "Empty selection for a phase extension supporting: " 
  +                      + phase.getReference() + " in profile: " + profile;
  +                    getLogger().error( pad + "  " + message );
  +
  +                    profile.setEnabled( false );
  +                    final AssemblyException problem = new AssemblyException( message );
  +                    throw new UnresolvedManagerException( phase, problem );
  +                }
  +
  +                //
  +                // associate the supplier to the profile via an association
  +                //
  +
  +                getLogger().debug( pad + "  selection: " + supplier );
  +                ResourceDesignator resource = 
  +                  m_classloader.getResource( supplier, true );
  +                profile.addExtension( phase, supplier, resource );
  +                m_map.add( supplier );
  +
  +            }
  +        }
  +    }
  +
  +    private boolean assembleManagers( 
  +      Profile source, PhaseDescriptor phase, List visited, String pad )
  +      throws Exception
  +    {
  +        boolean ok = false;
  +        Profile[] profiles = getProfiles( phase );
  +        getLogger().debug( 
  +           pad 
  +           + "phase: " + phase.getReference() 
  +           + ", [" + profiles.length + "]" 
  +        );
  +
  +        for( int i=0; i<profiles.length; i++ )
  +        {
  +            Profile profile = profiles[i];
  +            if( !profile.equals( source ) )
  +            {
  +                try
  +                {
  +                    assembleProfile( profile, visited, pad + "  " );
  +                    ok = true;
  +                    getLogger().debug( pad + "  extension: " + profile );
  +                }
  +                catch( Throwable e )
  +                {
  +                    // solution is not resolvable
  +                    getLogger().debug( 
  +                      pad 
  +                      + "  ignoring: " + profile + ", cause: " + e.toString()
  +                    );
  +                }
               }
           }
  +        return ok;
       }
   
  -    private Profile[] assembleProfile( 
  +    private boolean assembleProviders( 
         Profile source, DependencyDescriptor dependency, List visited, String pad )
         throws Exception
       {
  +        boolean ok = false;
           getLogger().debug( pad + "dependency: " + dependency.getRole() );
  -        Vector vector = new Vector();
  -        String pad2 = pad + "  ";
           Profile[] profiles = getProfiles( dependency.getService() );
           for( int i=0; i<profiles.length; i++ )
           {
  @@ -159,9 +311,9 @@
               {
                   try
                   {
  -                    assembleProfile( profile, visited, pad2 );
  -                    vector.add( profile );
  -                    getLogger().debug( pad + "candidate: " + profile );
  +                    assembleProfile( profile, visited, pad + "  " );
  +                    ok = true;
  +                    getLogger().debug( pad + "  provider: " + profile );
                   }
                   catch( Throwable e )
                   {
  @@ -169,7 +321,7 @@
                   }
               }
           }
  -        return (Profile[]) vector.toArray( new Profile[0] );
  +        return ok;
       }
   }
   
  
  
  
  1.2       +20 -1     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java
  
  Index: TypeManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TypeManager.java	29 Jul 2002 06:14:29 -0000	1.1
  +++ TypeManager.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -44,6 +44,7 @@
   import org.apache.excalibur.meta.info.Type;
   import org.apache.excalibur.meta.info.Facility;
   import org.apache.excalibur.meta.info.ReferenceDescriptor;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
   import org.apache.excalibur.merlin.container.model.IncludeDescriptor;
   import org.apache.excalibur.merlin.container.model.ExtensionsDescriptor;
   import org.apache.excalibur.merlin.container.model.DirsetDescriptor;
  @@ -466,6 +467,15 @@
       }
   
      /**
  +    * Returns the set of facilities know to the registry.
  +    * @return the set of facilities registered with the registry
  +    */
  +    public Facility[] getFacilities()
  +    {
  +        return m_types.getFacilities( );
  +    }
  +
  +   /**
       * 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
  @@ -473,6 +483,15 @@
       public Type[] getTypes( ReferenceDescriptor service )
       {
           return m_types.getTypes( service );
  +    }
  +
  +   /**
  +    * Returns the set of facilities know to the registry matching a supplied phase.
  +    * @return the set of facilities 
  +    */
  +    public Facility[] getFacilities( PhaseDescriptor phase )
  +    {
  +        return m_types.getFacilities( phase );
       }
   
      /**
  
  
  
  1.2       +74 -8     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRegistry.java
  
  Index: TypeRegistry.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/TypeRegistry.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- TypeRegistry.java	29 Jul 2002 06:14:29 -0000	1.1
  +++ TypeRegistry.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -9,6 +9,7 @@
   
   import java.util.List;
   import java.util.LinkedList;
  +import java.util.ArrayList;
   import java.util.Hashtable;
   import java.util.Vector;
   import java.util.Iterator;
  @@ -21,6 +22,9 @@
   import org.apache.excalibur.meta.info.ReferenceDescriptor;
   import org.apache.excalibur.meta.info.DependencyDescriptor;
   import org.apache.excalibur.meta.info.Type;
  +import org.apache.excalibur.meta.info.Facility;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
  +import org.apache.excalibur.meta.info.ExtensionDescriptor;
   import org.apache.excalibur.meta.info.builder.TypeBuilder;
   import org.apache.excalibur.meta.info.builder.FacilityBuilder;
   import org.apache.excalibur.merlin.model.Profile;
  @@ -52,6 +56,12 @@
       private Hashtable m_types = new Hashtable();
   
      /**
  +    * Facility types keyed by classname (facilities are also included 
  +    * in the m_types table).
  +    */
  +    private Hashtable m_facilities = new Hashtable();
  +
  +   /**
       * List of TypeTable instances.
       */
       private List m_services = new LinkedList();
  @@ -132,19 +142,19 @@
       * @param classname the component class name
       * @return the component type
       */
  -    public Type addFacility( String path ) throws Exception
  +    public Facility addFacility( String path ) throws Exception
       {
           final String classname = path.replace('/','.');
   
           getLogger().info("facility: " + classname );
  -        Type type = getType( classname );
  -        if( type == null )
  +        Facility facility = getFacility( classname );
  +        if( facility == null )
           {
  -            type = m_facilityBuilder.build( classname, m_classloader );
  -            verify( type );
  -            register( type );
  +            facility = m_facilityBuilder.build( classname, m_classloader );
  +            verify( facility );
  +            register( facility );
           }
  -        return type;
  +        return facility;
       }
   
       private void verify( Type type ) throws Exception
  @@ -226,6 +236,41 @@
       }
   
      /**
  +    * Returns the set of facilities know to the registry.
  +    * @return the set of registered facilities
  +    */
  +    public Facility[] getFacilities()
  +    {
  +        return (Facility[]) m_facilities.values().toArray( new Facility[0] );
  +    }
  +
  +   /**
  +    * Returns the set of facilities matching a supplied phase.
  +    * @return the set of matching facilities 
  +    */
  +    public Facility[] getFacilities( PhaseDescriptor phase )
  +    {
  +        ArrayList list = new ArrayList();
  +        Facility[] facilities = getFacilities();
  +        for( int i=0; i<facilities.length; i++ )
  +        {
  +            Facility facility = facilities[i];
  +            ExtensionDescriptor[] extensions = facility.getExtensions();
  +            for( int j=0; j<extensions.length; j++ )
  +            {
  +                ExtensionDescriptor extension = extensions[j];
  +                if( extension.getReference().matches( phase.getReference() ) )
  +                {
  +                    list.add( facility );
  +                    break;
  +                }
  +            }
  +        }
  +        return (Facility[]) list.toArray( new Facility[ list.size() ] );
  +    }
  +
  +
  +   /**
       * 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
  @@ -242,6 +287,27 @@
       public Type getType( String classname ) 
       {
           return (Type) m_types.get( classname );
  +    }
  +
  +   /**
  +    * Returns a registered facility type.
  +    * @return the facility type from the registry or null if the facility is unknown
  +    */
  +    public Facility getFacility( String classname ) 
  +    {
  +        return (Facility) m_facilities.get( classname );
  +    }
  +
  +   /**
  +    * Register the facility resulting in the cross-referencing of the facility
  +    * with the set of phases is is capable of supporting.
  +    */
  +    protected void registerFacility( Facility facility )
  +    {
  +        register( facility );
  +        String key = facility.getInfo().getImplementationKey();
  +        m_facilities.put( key, facility );
  +        getLogger().debug( "Facility: '" + key + "' registered.");
       }
   
      /**
  
  
  
  1.1                  jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  
  target.nocreate=Error creating LogTarget named "{0}" for file {0}. (Reason: {2}).
  unknown-priority=Unknown priority "{0}" for Logger named "{1}".
  category-create=Creating a log category named "{0}" that writes to "{1}" target at priority "{2}".
  
  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/assembly/UnresolvedManagerException.java
  
  Index: UnresolvedManagerException.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.assembly;
  
  import org.apache.excalibur.meta.info.PhaseDescriptor;
  
  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/30 07:05:55 $
   */
  public final class UnresolvedManagerException
      extends CascadingException
  {
  
      private PhaseDescriptor m_phase;
  
     /**
      * Construct a new <code>UnresolvedManagerException</code> instance.
      *
      * @param phase the unresolved phase
      */
      public UnresolvedManagerException( PhaseDescriptor phase )
      {
          this( phase, null );
      }
  
     /**
      * Construct a new <code>UnresolvedManagerException</code> instance.
      *
      * @param phase the unresolved phase
      * @param cause the causal exception
      */
      public UnresolvedManagerException( PhaseDescriptor phase, Throwable cause )
      {
          super( getStandardMessage( phase ), cause );
          m_phase = phase;
      }
  
     /**
      * Return the dependency description.
      * @return the unresolved dependency.
      */
      public PhaseDescriptor getPhase()
      {
          return m_phase;
      }
  
      private static String getStandardMessage( PhaseDescriptor phase )
      {
          return "Unable to resolve an extensions for the phase '" 
            + phase.getReference();
      }
  
  }
  
  
  
  
  1.2       +84 -7     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleHelper.java
  
  Index: LifecycleHelper.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/LifecycleHelper.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LifecycleHelper.java	29 Jul 2002 06:14:30 -0000	1.1
  +++ LifecycleHelper.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -19,6 +19,7 @@
   import org.apache.avalon.framework.container.ContainerUtil;
   import org.apache.avalon.framework.context.Context;
   import org.apache.avalon.framework.context.Contextualizable;
  +import org.apache.avalon.framework.context.DefaultContext;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
   import org.apache.avalon.framework.logger.LogEnabled;
   import org.apache.avalon.framework.logger.Logger;
  @@ -28,6 +29,10 @@
   import org.apache.avalon.framework.service.Serviceable;
   
   import org.apache.excalibur.merlin.model.Profile;
  +import org.apache.excalibur.merlin.model.ResourceDesignator;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
  +import org.apache.excalibur.meta.info.ExtensionDescriptor;
  +import org.apache.excalibur.meta.info.Facility;
   
   /**
    * This is a class to help an Application manage the lifecycle of a component.
  @@ -50,11 +55,13 @@
       private static final int STAGE_COMPOSE = 3;
       private static final int STAGE_CONFIG = 4;
       private static final int STAGE_PARAMETER = 5;
  -    private static final int STAGE_INIT = 6;
  -    private static final int STAGE_START = 7;
  -    private static final int STAGE_STOP = 8;
  -    private static final int STAGE_DISPOSE = 9;
  -    private static final int STAGE_DESTROY = 10;
  +    private static final int STAGE_EXTENSION_PRE = 6;
  +    private static final int STAGE_INIT = 7;
  +    private static final int STAGE_START = 8;
  +    private static final int STAGE_STOP = 9;
  +    private static final int STAGE_DISPOSE = 10;
  +    private static final int STAGE_EXTENSION_POST = 11;
  +    private static final int STAGE_DESTROY = 12;
   
       /**
        * Method to run a component through it's startup phase.
  @@ -93,10 +100,10 @@
   
               //Contextualize stage
               stage = STAGE_CONTEXT;
  +            final Context context = provider.createContext( profile );
               if( object instanceof Contextualizable )
               {
                   notice( name, stage );
  -                final Context context = provider.createContext( profile );
                   ContainerUtil.contextualize( object, context );
               }
   
  @@ -137,6 +144,40 @@
                   ContainerUtil.parameterize( object, parameters );
               }
   
  +            //
  +            // apply creation phase extensions
  +            //
  +
  +            stage = STAGE_EXTENSION_PRE;
  +            PhaseDescriptor[] phases = profile.getType().getPhases();
  +            if( phases.length > 0 )
  +              notice( name, stage );
  +            for( int i=0; i<phases.length; i++ )
  +            {
  +                PhaseDescriptor phase = phases[i];
  +                final Facility facility = profile.getFacility( phase );
  +                final ExtensionDescriptor ext = facility.getExtension( phase );
  +                if( ext.isApplicable( ExtensionDescriptor.CREATE ) )
  +                {
  +                    ResourceDesignator resource = profile.getExtension( phase );
  +                    Extension extension = (Extension) resource.getInstance();
  +                    try
  +                    {
  +                        getLogger().info("applying phase " + phase.getReference() + " to " + name );
  +                        extension.extend( Extension.CREATE, object, context );
  +                    }
  +                    catch( Throwable e )
  +                    {
  +                        final String error =
  +                          "Extension " + extension.getClass().getName() 
  +                          + " raised an exception " + e.getClass().getName()
  +                          + " while processing the creation phase for the component " 
  +                          + name;
  +                        throw new LifecycleException( error, e );
  +                    }
  +                }
  +            }
  +
               //Initialize stage
               stage = STAGE_INIT;
               if( object instanceof Initializable )
  @@ -167,12 +208,13 @@
   
       /**
        * Method to run a component through it's shutdown phase.
  -     * Errors that occur during shutdown will be logged appropraitely.
  +     * Errors that occur during shutdown will be logged appropriately.
        *
        * @param name the name of the component
        * @param object the component to shutdown
        */
       public void shutdown( final String name,
  +                          final Profile profile,
                             final Object object )
           throws LifecycleException
       {
  @@ -198,6 +240,41 @@
                   safeFail( name, STAGE_STOP, t );
                   failure = t;
                   stage = STAGE_STOP;
  +            }
  +        }
  +
  +        //
  +        // apply disposal extensions
  +        // ### what about context ? ###
  +        // ## what about extension exceptions - it should containue
  +        // to subsequent extensions - needs testing ##
  +        //
  +
  +        stage = STAGE_EXTENSION_POST;
  +        PhaseDescriptor[] phases = profile.getType().getPhases();
  +        if( phases.length > 0 )
  +          notice( name, stage );
  +        for( int i=(phases.length-1); i>-1; i-- )
  +        {
  +            PhaseDescriptor phase = phases[i];
  +            final Facility facility = profile.getFacility( phase );
  +            final ExtensionDescriptor ext = facility.getExtension( phase );
  +            if( ext.isApplicable( ExtensionDescriptor.DESTROY ) )
  +            {
  +                try
  +                {
  +                    ResourceDesignator resource = profile.getExtension( phase );        
  +                    Extension extension = (Extension) resource.getInstance();
  +                    getLogger().info("applying '" + phase.getReference() 
  +                      + "' to '" + name + "'.");
  +                    extension.extend( Extension.DESTROY, object, new DefaultContext() );
  +                }
  +                catch( Throwable e )
  +                {
  +                    safeFail( name, STAGE_EXTENSION_POST, e );
  +                    failure = e;
  +                    stage = STAGE_EXTENSION_POST;
  +                }
               }
           }
   
  
  
  
  1.2       +2 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ProfileDesignator.java
  
  Index: ProfileDesignator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ProfileDesignator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ProfileDesignator.java	29 Jul 2002 06:14:30 -0000	1.1
  +++ ProfileDesignator.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -133,7 +133,7 @@
       public void release() throws LifecycleException
       {
           if( m_service != null )
  -          m_helper.shutdown( m_path, m_service );
  +          m_helper.shutdown( m_path, m_profile, m_service );
           setState( STOPPED );
       }
   
  
  
  
  1.2       +23 -8     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceProvider.java
  
  Index: ResourceProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/assembly/resource/ResourceProvider.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ResourceProvider.java	29 Jul 2002 06:14:30 -0000	1.1
  +++ ResourceProvider.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -104,6 +104,11 @@
       */
       private final Hashtable m_singletons = new Hashtable();
   
  +   /**
  +    * A hashtable of profiles keyed by singleton object.
  +    */
  +    private final Hashtable m_profiles = new Hashtable();
  +
       private DefaultContext m_dictionary;
   
       //=======================================================================
  @@ -122,15 +127,15 @@
           m_classloader = loader;
           m_logging = logging;
   
  -        // ##### WARNING ##########
  -        // The following is a hack to add the avalon:work context key - this needs to 
  -        // constructed using context creation directives at the level of the kernel
  -        // defintion
  -        //#########################
  +        // ## WARNING ###################################################################//
  +        // The following is a hack to add the avalon:work context key - this needs to    //
  +        // constructed using context creation directives at the level of the kernel      //
  +        // defintion (which requires the commons factory interface).                     //
  +        //###############################################################################//
   
           m_dictionary = new DefaultContext( dictionary );
           m_dictionary.put( "classloader", loader );
  -        m_dictionary.put( "home", new File( System.getProperty("user.dir") ) );
  +        m_dictionary.put( "avalon:work", new File( System.getProperty("user.dir") ) );
           m_dictionary.makeReadOnly();
       }
   
  @@ -151,6 +156,10 @@
           Object object = getSingletonInstance( profile );
           if( object == null )
           {
  +            //
  +            // load the class
  +            //
  +
               Class clazz = null;
               String classname = null;
               try
  @@ -166,6 +175,10 @@
                   throw new ResourceException( error, e );
               }
   
  +            //
  +            // create a new instance of the class
  +            //
  +
               try
               {
                   object = clazz.newInstance();
  @@ -178,6 +191,7 @@
                       + profile;
                   throw new ResourceException( error, e );
               }
  +
           }
           return object;
       }
  @@ -309,7 +323,7 @@
           return parameters;
       }
   
  -    public Object getSingletonInstance( Profile profile )
  +    private Object getSingletonInstance( Profile profile )
       {
           return m_singletons.get( profile );
       }
  @@ -317,6 +331,7 @@
       private void putSingletonInstance( Profile profile, Object object )
       {
           m_singletons.put( profile, object );
  +        m_profiles.put( object, profile );
       }
   
      /**
  
  
  
  1.2       +2 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/ContainerCreator.java
  
  Index: ContainerCreator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/ContainerCreator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ContainerCreator.java	29 Jul 2002 06:14:31 -0000	1.1
  +++ ContainerCreator.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -30,7 +30,7 @@
        * @return the newly created {@link ContainerDescriptor}
        * @throws Exception
        */
  -    ContainerDescriptor createContainerDescriptor( Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging )
  +    ContainerDescriptor createContainerDescriptor( Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging, boolean root )
           throws Exception;
   
   }
  
  
  
  1.2       +8 -8      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/XMLContainerCreator.java
  
  Index: XMLContainerCreator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/container/builder/XMLContainerCreator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLContainerCreator.java	29 Jul 2002 06:14:31 -0000	1.1
  +++ XMLContainerCreator.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -59,7 +59,7 @@
       * @exception Exception is a error occurs during container descriptor creation
       */
       public ContainerDescriptor createContainerDescriptor(
  -      Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging )
  +      Parent parent, Configuration config, TypeManager manager, DefaultLoggerManager logging, boolean root )
         throws Exception
       {
   
  @@ -71,12 +71,12 @@
           CategoriesDescriptor categories = 
             super.createCategoriesDescriptor( name, config.getChild("categories") );
           Logger logger;
  -        if( parent instanceof ContainerDescriptor )
  +        if( !root )
           {
  -            final String root = 
  +            final String base = 
                 parent.getPath().replace('/','.').substring(1) + "." + name;
  -            logging.addCategories( root, categories );
  -            logger = logging.getLoggerForCategory( root );
  +            logging.addCategories( base, categories );
  +            logger = logging.getLoggerForCategory( base );
           }
           else
           {
  @@ -90,7 +90,7 @@
   
           logger.info("preparing type manager");
           ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
  -        final ProfileManager loader = new ProfileManager( manager, name );
  +        final ProfileManager loader = new ProfileManager( manager, name, root );
           try
           {
               loader.enableLogging( logger.getChildLogger( "loader" ) );
  @@ -139,7 +139,7 @@
           for( int i=0; i<configs.length; i++ )
           {
               final Configuration conf = configs[i];
  -            container.addContainer( createContainerDescriptor( container, conf, loader, logging ) );
  +            container.addContainer( createContainerDescriptor( container, conf, loader, logging, false ) );
           }
   
           return container;
  
  
  
  1.2       +3 -3      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/XMLKernelCreator.java
  
  Index: XMLKernelCreator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/kernel/builder/XMLKernelCreator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLKernelCreator.java	29 Jul 2002 06:14:32 -0000	1.1
  +++ XMLKernelCreator.java	30 Jul 2002 07:05:55 -0000	1.2
  @@ -76,7 +76,7 @@
           logger.info("preparing kernel type manager");
           ExtensionsDescriptor extensions = createExtensionsDescriptor( config.getChild("extensions") );
           ClasspathDescriptor classpath = createClasspathDescriptor( config.getChild("classpath") );
  -        final ProfileManager manager = new ProfileManager( loader, name );
  +        final ProfileManager manager = new ProfileManager( loader, name, true );
           try
           {
               manager.enableLogging( logger.getChildLogger( "loader" ) );
  @@ -103,7 +103,7 @@
           logger.info("preparing kernel descriptor");
           KernelDescriptor kernel = new KernelDescriptor( name, logger, manager );
           ContainerDescriptor container = createContainerDescriptor( 
  -           kernel, config.getChild("container"), manager, logging );
  +           kernel, config.getChild("container"), manager, logging, true );
           kernel.setContainer( container );
           return kernel;
       }
  
  
  
  1.5       +3 -4      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Association.java
  
  Index: Association.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Association.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Association.java	18 Jul 2002 03:40:11 -0000	1.4
  +++ Association.java	30 Jul 2002 07:05:55 -0000	1.5
  @@ -29,8 +29,7 @@
       private final String m_role;
   
       /**
  -     * the name of the component metadata instance that represents a component
  -     * type that is capable of fullfilling the dependency.
  +     * A reference to the component that is capable of fullfilling the dependency.
        */
       private final ResourceDesignator m_provider;
   
  @@ -60,7 +59,7 @@
       }
   
       /**
  -     * Return the <code>Profile</code> instance that will used to
  +     * Return the <code>ResourceDesignator</code> that will used to
        * fulfill the dependency.
        *
        * @return the profile that will fulfill the dependency.
  
  
  
  1.4       +2 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java
  
  Index: Import.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Import.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Import.java	23 Jul 2002 15:36:04 -0000	1.3
  +++ Import.java	30 Jul 2002 07:05:55 -0000	1.4
  @@ -19,7 +19,7 @@
    *
    *    <font color="gray">
    *    &lt;-- 
  - *    Declare the import of the value of avalon.work as a keyed context
  + *    Declare the import of the value of "avalon.work" as a keyed context
    *    value using the key "home".
    *    --&gt;</font>
    *
  
  
  
  1.12      +47 -1     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Profile.java
  
  Index: Profile.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/merlin/model/Profile.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Profile.java	29 Jul 2002 06:14:32 -0000	1.11
  +++ Profile.java	30 Jul 2002 07:05:55 -0000	1.12
  @@ -14,6 +14,8 @@
   import org.apache.avalon.framework.parameters.Parameters;
   import org.apache.avalon.framework.context.Context;
   import org.apache.excalibur.meta.info.Type;
  +import org.apache.excalibur.meta.info.Facility;
  +import org.apache.excalibur.meta.info.PhaseDescriptor;
   import org.apache.excalibur.merlin.model.Association;
   import org.apache.excalibur.configuration.ConfigurationUtil;
   
  @@ -124,6 +126,16 @@
       private final Hashtable m_dependencies = new Hashtable();
   
       /**
  +     * The phase extension resource descriptor keyed by phase.
  +     */
  +    private final Hashtable m_managers = new Hashtable();
  +
  +    /**
  +     * The phase extension profile keyed by phase.
  +     */
  +    private final Hashtable m_extensions = new Hashtable();
  +
  +    /**
        * The info object for component type.
        */
       private final Type m_type;
  @@ -326,6 +338,40 @@
           m_dependencies.put( role, association );
           return association;
       }
  +
  +   /**
  +    * Add a lifecycle phase extension.
  +    * @param phase the identifier of the phase to assign the manager to
  +    * @param resource the reference to the manager
  +    */
  +    public void addExtension( PhaseDescriptor phase, Profile profile, ResourceDesignator resource )
  +    {
  +        m_managers.put( phase, resource );
  +        m_extensions.put( phase, profile );
  +    }
  +
  +   /**
  +    * Return a reference to the lifecycle phase extension assigned to handle
  +    * the components custom phase.
  +    * @param phase the lifecycle phase specification
  +    * @return a reference to the phase extension
  +    */
  +    public ResourceDesignator getExtension( PhaseDescriptor phase )
  +    {
  +        return (ResourceDesignator) m_managers.get( phase );
  +    }
  +
  +   /**
  +    * Return the facility associated as the phace provider.
  +    * @param phase the lifecycle phase specification
  +    * @return a reference to the phase extension
  +    */
  +    public Facility getFacility( PhaseDescriptor phase )
  +    {
  +        Profile profile = (Profile) m_extensions.get( phase );
  +        return (Facility) profile.getType();
  +    }
  +
   
      /**
       * Return the activation policy for the component.  If TRUE, activation
  
  
  
  1.4       +3 -1      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/componentinfo.dtd
  
  Index: componentinfo.dtd
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/componentinfo.dtd,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- componentinfo.dtd	29 Jul 2002 06:14:33 -0000	1.3
  +++ componentinfo.dtd	30 Jul 2002 07:05:56 -0000	1.4
  @@ -126,8 +126,10 @@
   reference  the version lifecycle interface supported
   attributes	  Optional attributes about the extension
   -->
  +<!ENTITY % stage.attribute "stage (CREATE|ACCESS|RELEASE|DESTROY|ALL|INNER|OUTER) 'ALL'">
   <!ELEMENT extension      (name,reference,attributes?)>
  -  <!ATTLIST extension >
  +<!ATTLIST extension
  +       %stage.attribute; >
   
   <!--
   The phase element defines a lifecycle extension phase that this component provides.
  
  
  
  1.2       +73 -7     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ExtensionDescriptor.java
  
  Index: ExtensionDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/ExtensionDescriptor.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ExtensionDescriptor.java	29 Jul 2002 06:14:33 -0000	1.1
  +++ ExtensionDescriptor.java	30 Jul 2002 07:05:56 -0000	1.2
  @@ -15,22 +15,41 @@
    * @author <a href="mailto:mcconnell@apache.org">Stephen McConnell</a>
    * @version $Revision$ $Date$
    */
  -public final class ExtensionDescriptor extends PhaseDescriptor
  +public final class ExtensionDescriptor extends Descriptor
   {
  +    public static final int CREATE = 0;
  +    public static final int ACCESS = 1;
  +    public static final int RELEASE = 2;
  +    public static final int DESTROY = 3;
  +    public static final int INNER = 4;
  +    public static final int OUTER = 5;
  +    public static final int ALL = 6;
  +
  +    /**
  +     * The lifecycle stage.
  +     */
  +    private final int m_stage;
  +
       /**
        * The name of the lifecycle phase.
        */
       private final String m_name;
   
       /**
  +     * The interface that represents the client view of the lifecycle phase.
  +     */
  +    private final ReferenceDescriptor m_reference;
  +
  +    /**
        * Constructor a phase descriptor without attributes.
        * @param name the phase name
        * @param interface the phase type
        */
       public ExtensionDescriptor( final String name,
  -                                 final ReferenceDescriptor reference )
  +                                final int stage, 
  +                                final ReferenceDescriptor reference )
       {
  -        this( name, reference, null );
  +        this( name, stage, reference, null );
       }
   
       /**
  @@ -39,15 +58,22 @@
        * @param interface the phase type
        */
       public ExtensionDescriptor( final String name,
  -                                 final ReferenceDescriptor reference,
  -                                 final Properties attributes )
  +                                final int stage, 
  +                                final ReferenceDescriptor reference,
  +                                final Properties attributes )
       {
  -        super( reference, attributes );
  +        super( attributes );
   
           if( null == name )
               throw new NullPointerException( "name" );
  +        if( null == reference )
  +            throw new NullPointerException( "reference" );
  +        if( (ALL < stage) || (stage < CREATE ))
  +            throw new IllegalArgumentException( "stage: " + stage );
   
           m_name = name;
  +        m_reference = reference;
  +        m_stage = stage;
       }
   
       /**
  @@ -59,5 +85,45 @@
       {
           return m_name;
       }
  +
  +    /**
  +     * Return the version interface reference.
  +     *
  +     * @return the version interface reference.
  +     */
  +    public ReferenceDescriptor getReference()
  +    {
  +        return m_reference;
  +    }
  +
  +    /**
  +     * Return the lifecycle stage that this phase is to be applied under.
  +     *
  +     * @return one of the phase values {@link #CREATE}, {@link #ACCESS}, {@link #RELEASE}, {@link #DESTORY},
  +     *   {@link #INNER}, {@link #OUTER}, or {@link #ALL}.
  +     */
  +    public int getStage()
  +    {
  +        return m_stage;
  +    }
  +
  +    public boolean isApplicable( int stage )
  +    {
  +        
  +
  +        final int policy = getStage();
  +        if( policy == ALL ) return true;
  +        if( policy == stage ) return true;
  +        if(( stage == CREATE ) || ( stage == DESTROY ))
  +        {
  +            return ( policy == OUTER );
  +        }
  +        else if(( stage == ACCESS ) || ( stage == RELEASE ))
  +        {
  +            return ( policy == INNER );
  +        }
  +        return false;
  +    } 
  +
   
   }
  
  
  
  1.2       +22 -2     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Facility.java
  
  Index: Facility.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/Facility.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Facility.java	29 Jul 2002 06:14:33 -0000	1.1
  +++ Facility.java	30 Jul 2002 07:05:56 -0000	1.2
  @@ -63,12 +63,32 @@
       /**
        * Return the phases supported by this extension.
        *
  -     * @return an array of phase descriptors.
  +     * @return an array of extension descriptors.
        */
       public ExtensionDescriptor[] getExtensions()
       {
           return m_extensions;
       }
  +
  +    /**
  +     * Return the extension supporting the supplied phase.
  +     *
  +     * @return a matching extension or null if no matching extension
  +     */
  +    public ExtensionDescriptor getExtension( PhaseDescriptor phase )
  +    {
  +        ReferenceDescriptor reference = phase.getReference();
  +        ExtensionDescriptor[] extensions = getExtensions();
  +        for( int i=0; i<extensions.length; i++ )
  +        {
  +            ExtensionDescriptor extension = extensions[i];
  +            ReferenceDescriptor ref = extension.getReference();
  +            if( reference.matches( ref ) )
  +               return extension;
  +        }
  +        return null;
  +    }
  +
   
      /**
       * Return a string representation of the type.
  
  
  
  1.3       +4 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/PhaseDescriptor.java
  
  Index: PhaseDescriptor.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/PhaseDescriptor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PhaseDescriptor.java	29 Jul 2002 06:14:33 -0000	1.2
  +++ PhaseDescriptor.java	30 Jul 2002 07:05:56 -0000	1.3
  @@ -17,6 +17,7 @@
    */
   public class PhaseDescriptor extends Descriptor
   {
  +
       /**
        * The interface that represents the client view of the lifecycle phase.
        */
  @@ -38,7 +39,7 @@
        * @param interface the phase type
        */
       public PhaseDescriptor( final ReferenceDescriptor reference,
  -                                 final Properties attributes )
  +                            final Properties attributes )
       {
           super( attributes );
   
  @@ -57,4 +58,5 @@
       {
           return m_reference;
       }
  +
   }
  
  
  
  1.2       +46 -4     jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLFacilityCreator.java
  
  Index: XMLFacilityCreator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLFacilityCreator.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- XMLFacilityCreator.java	29 Jul 2002 06:14:34 -0000	1.1
  +++ XMLFacilityCreator.java	30 Jul 2002 07:05:56 -0000	1.2
  @@ -154,14 +154,56 @@
           {
               Configuration extension = extensions[i];
               final String name = extension.getChild("name").getValue();
  -            ReferenceDescriptor reference = buildReferenceDescriptor( 
  -              extension.getChild("reference") );
  +            final int stage = getStageValue( extension );
  +            ReferenceDescriptor reference = 
  +              buildReferenceDescriptor( extension.getChild("reference") );
               final Properties attributes =
                   super.buildAttributes( extension.getChild( "attributes" ) );
  -            list.add( new ExtensionDescriptor( name, reference, attributes ) );
  +            list.add( new ExtensionDescriptor( name, stage, reference, attributes ) );
           }
           return (ExtensionDescriptor[]) list.toArray( new ExtensionDescriptor[0] );
       }
  +
  +    private int getStageValue( Configuration phase )
  +    {
  +        final String stage = phase.getAttribute("stage","CREATE");
  +        if( stage.equalsIgnoreCase("CREATE") )
  +        {
  +            return ExtensionDescriptor.CREATE;
  +        }
  +        else if( stage.equalsIgnoreCase("DESTORY") )
  +        {
  +            return ExtensionDescriptor.DESTROY;
  +        }
  +        else if( stage.equalsIgnoreCase("ACCESS") )
  +        {
  +            return ExtensionDescriptor.ACCESS;
  +        }
  +        else if( stage.equalsIgnoreCase("RELEASE") )
  +        {
  +            return ExtensionDescriptor.RELEASE;
  +        }
  +        else if( stage.equalsIgnoreCase("INNER") )
  +        {
  +            return ExtensionDescriptor.INNER;
  +        }
  +        else if( stage.equalsIgnoreCase("OUTER") )
  +        {
  +            return ExtensionDescriptor.OUTER;
  +        }
  +        else if( stage.equalsIgnoreCase("ALL") )
  +        {
  +            return ExtensionDescriptor.ALL;
  +        }
  +        else
  +        {
  +            final String error = "Supplied stage argument '" + stage + " invalid at "
  +              + phase.getLocation() 
  +              + ". Allowable values: CREATE,DESTORY,ACCESS, RELEASE, INNER, OUTER or ALL.";
  +             
  +            throw new IllegalArgumentException( error );
  +        }
  +   }
   
   
   }
  
  
  
  1.7       +1 -2      jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLTypeCreator.java
  
  Index: XMLTypeCreator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/assembly/src/java/org/apache/excalibur/meta/info/builder/XMLTypeCreator.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XMLTypeCreator.java	29 Jul 2002 06:14:34 -0000	1.6
  +++ XMLTypeCreator.java	30 Jul 2002 07:05:56 -0000	1.7
  @@ -130,7 +130,6 @@
                                  new Integer( phases.length ) );
               getLogger().info( message );
           }
  -
           return new Type( descriptor, loggers, context, services, dependencies, phases );
       }
   
  
  
  

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