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 2003/04/24 14:20:20 UTC

cvs commit: avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/type DefaultTypeRepository.java package.html DefaultTypeManager.java

mcconnell    2003/04/24 05:20:20

  Modified:    merlin/assembly/src/java/org/apache/avalon/assembly/engine
                        DefaultRepositoryManager.java
                        EngineClassLoader.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/model
                        DefaultClasspath.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile
                        DefaultProfileSelector.java package.html
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/type
                        package.html
  Added:       merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile
                        DefaultProfileRepository.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/service
                        DefaultServiceRepository.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/type
                        DefaultTypeRepository.java
  Removed:     merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile
                        DefaultProfileManager.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/service
                        ClassloaderServiceManager.java
               merlin/assembly/src/java/org/apache/avalon/assembly/engine/type
                        DefaultTypeManager.java
  Log:
  Terminology enhancements.
  
  Revision  Changes    Path
  1.3       +25 -25    avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/DefaultRepositoryManager.java
  
  Index: DefaultRepositoryManager.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/DefaultRepositoryManager.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DefaultRepositoryManager.java	11 Apr 2003 19:39:17 -0000	1.2
  +++ DefaultRepositoryManager.java	24 Apr 2003 12:20:19 -0000	1.3
  @@ -68,12 +68,12 @@
   import java.util.jar.JarInputStream;
   import java.util.zip.ZipEntry;
   
  -import org.apache.avalon.assembly.engine.profile.DefaultProfileManager;
  -import org.apache.avalon.assembly.engine.profile.ProfileManager;
  -import org.apache.avalon.assembly.engine.service.ClassloaderServiceManager;
  -import org.apache.avalon.assembly.engine.service.ServiceManager;
  -import org.apache.avalon.assembly.engine.type.DefaultTypeManager;
  -import org.apache.avalon.assembly.engine.type.TypeManager;
  +import org.apache.avalon.assembly.engine.profile.DefaultProfileRepository;
  +import org.apache.avalon.assembly.engine.profile.ProfileRepository;
  +import org.apache.avalon.assembly.engine.service.DefaultServiceRepository;
  +import org.apache.avalon.assembly.engine.service.ServiceRepository;
  +import org.apache.avalon.assembly.engine.type.DefaultTypeRepository;
  +import org.apache.avalon.assembly.engine.type.TypeRepository;
   import org.apache.avalon.assembly.util.ExceptionHelper;
   import org.apache.avalon.framework.activity.Initializable;
   import org.apache.avalon.framework.logger.AbstractLogEnabled;
  @@ -116,17 +116,17 @@
       /**
        * The registry of installed component types.
        */
  -    private TypeManager m_types;
  +    private TypeRepository m_types;
   
       /**
        * The service registry.
        */
  -    private ServiceManager m_services;
  +    private ServiceRepository m_services;
   
       /**
        * The profile registry.
        */
  -    private ProfileManager m_profiles;
  +    private ProfileRepository m_profiles;
   
       /**
        * List of jar files already installed.
  @@ -182,23 +182,23 @@
               throw new IllegalStateException( "logging" );
           }
   
  -        ClassloaderServiceManager services = null;
  -        DefaultProfileManager profiles = null;
  -        DefaultTypeManager types = null;
  +        DefaultServiceRepository services = null;
  +        DefaultProfileRepository profiles = null;
  +        DefaultTypeRepository types = null;
   
           if( m_parent == null )
           {
  -            types = new DefaultTypeManager( m_classloader );
  -            services = new ClassloaderServiceManager( m_classloader );
  -            profiles = new DefaultProfileManager( m_classloader );
  +            types = new DefaultTypeRepository( m_classloader );
  +            services = new DefaultServiceRepository( m_classloader );
  +            profiles = new DefaultProfileRepository( m_classloader );
           } else
           {
  -            types = new DefaultTypeManager(
  -                    m_classloader, m_parent.getTypeManager() );
  -            services = new ClassloaderServiceManager(
  -                    m_classloader, m_parent.getServiceManager() );
  -            profiles = new DefaultProfileManager(
  -                    m_classloader, m_parent.getProfileManager() );
  +            types = new DefaultTypeRepository(
  +                    m_classloader, m_parent.getTypeRepository() );
  +            services = new DefaultServiceRepository(
  +                    m_classloader, m_parent.getServiceRepository() );
  +            profiles = new DefaultProfileRepository(
  +                    m_classloader, m_parent.getProfileRepository() );
           }
   
           types.enableLogging( getLogger().getChildLogger( "types" ) );
  @@ -214,17 +214,17 @@
       // Repository
       //=======================================================================
   
  -    public TypeManager getTypeManager()
  +    public TypeRepository getTypeRepository()
       {
           return m_types;
       }
   
  -    public ServiceManager getServiceManager()
  +    public ServiceRepository getServiceRepository()
       {
           return m_services;
       }
   
  -    public ProfileManager getProfileManager()
  +    public ProfileRepository getProfileRepository()
       {
           return m_profiles;
       }
  
  
  
  1.10      +56 -35    avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java
  
  Index: EngineClassLoader.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- EngineClassLoader.java	20 Apr 2003 12:05:41 -0000	1.9
  +++ EngineClassLoader.java	24 Apr 2003 12:20:19 -0000	1.10
  @@ -75,12 +75,14 @@
   import org.apache.avalon.assembly.engine.model.DefaultClasspath;
   import org.apache.avalon.assembly.engine.model.IncludeDescriptor;
   import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
  -import org.apache.avalon.assembly.engine.profile.ProfileManager;
  -import org.apache.avalon.assembly.engine.type.TypeManager;
  +import org.apache.avalon.assembly.engine.profile.ProfileRepository;
  +import org.apache.avalon.assembly.engine.type.TypeRepository;
   import org.apache.avalon.assembly.locator.Contextualizable;
   import org.apache.avalon.assembly.locator.DefaultLocator;
   import org.apache.avalon.assembly.locator.Locator;
   import org.apache.avalon.assembly.logging.LoggingManager;
  +import org.apache.avalon.assembly.repository.Repository;
  +import org.apache.avalon.assembly.repository.impl.FileRepository;
   import org.apache.avalon.excalibur.extension.Extension;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
  @@ -97,6 +99,7 @@
   import org.apache.avalon.meta.info.ReferenceDescriptor;
   import org.apache.avalon.meta.info.StageDescriptor;
   import org.apache.avalon.meta.info.Type;
  +import org.apache.avalon.meta.model.Mode;
   import org.apache.avalon.meta.model.Profile;
   import org.apache.excalibur.mpool.PoolManager;
   
  @@ -148,7 +151,7 @@
        * The repository maanger holds the service, types and profiels associated
        * with the class loader.
        */
  -    private DefaultRepositoryManager m_repository;
  +    private DefaultRepositoryManager m_meta;
   
       /**
        * A map of custom context entries that suppliment the standard system
  @@ -213,6 +216,11 @@
        */
       private PoolManager m_pool;
   
  +    /**
  +     * The resource repository.
  +     */
  +    private Repository m_repository;
  +
       //=======================================================================
       // constructor
       //=======================================================================
  @@ -280,6 +288,29 @@
        */
       public void contextualize( Locator context ) throws ContextException
       {
  +        if( context.hasEntry( "urn:assembly:system" ) )
  +        {
  +            m_root = (File) context.get( "urn:assembly:system" );
  +        }
  +
  +        //
  +        // a repository is option - if not supplied and no root system directory
  +        // if declared, then resource references in a classpath will raise an error.
  +        //
  +
  +        if( context.hasEntry( Repository.KEY ) )
  +        {
  +            m_repository = (Repository) context.get( Repository.KEY );
  +        }
  +        else
  +        {
  +            if( m_root != null )
  +            {
  +                File repository = new File( m_root, "repository" );
  +                m_repository = FileRepository.newInstance( repository );
  +            }
  +        }
  +
           if( context.hasEntry( "urn:assembly:system-map" ) )
           {
               m_map = (Map) context.get( "urn:assembly:system-map" );
  @@ -318,11 +349,6 @@
               m_home = new File( System.getProperty( "user.dir" ) );
           }
   
  -        if( context.hasEntry( "urn:assembly:system" ) )
  -        {
  -            m_root = (File) context.get( "urn:assembly:system" );
  -        }
  -
           if( context.hasEntry( "urn:assembly:engine.bootstrap" ) )
           {
               m_bootstrap = "true".equals(
  @@ -388,7 +414,7 @@
               getLogger().debug( REZ.getString( "initialization" ) );
           }
   
  -        m_repository = createRepositoryManager();
  +        m_meta = createRepositoryManager();
           m_factory = DefaultApplianceFactory.createApplianceFactory(
                   this, getLogger(), m_manager, getSystemContext() );
   
  @@ -545,7 +571,7 @@
   
           for( int k = 0; k < m_parsable.length; k++ )
           {
  -            m_repository.install( m_parsable[k] );
  +            m_meta.install( m_parsable[k] );
           }
   
           //
  @@ -688,6 +714,10 @@
               {
                   context.put( "urn:assembly:system", m_root );
               }
  +            if( m_repository != null )
  +            {
  +                context.put( Repository.KEY, m_repository );
  +            }
               if( extensions != null )
               {
                   context.put( "urn:assembly:engine.extensions", extensions );
  @@ -724,7 +754,7 @@
               getLogger().debug( REZ.getString( "add.url", url ) );
           }
           super.addURL( url );
  -        m_repository.install( url );
  +        m_meta.install( url );
       }
   
       /**
  @@ -755,7 +785,8 @@
   
           try
           {
  -            URL[] urls = classpath.expand( m_root, m_home );
  +            //URL[] urls = classpath.expand( m_root, m_home );
  +            URL[] urls = classpath.expand( m_repository, m_home );
               for( int j = 0; j < urls.length; j++ )
               {
                   URL inc = urls[j];
  @@ -821,7 +852,7 @@
        */
       public RepositoryManager getRepository()
       {
  -        return m_repository;
  +        return m_meta;
       }
   
       /**
  @@ -836,8 +867,8 @@
               getLogger().debug( REZ.getString( "register.path", path ) );
           }
   
  -        TypeManager types = getRepository().getTypeManager();
  -        ProfileManager profiles = getRepository().getProfileManager();
  +        TypeRepository types = getRepository().getTypeRepository();
  +        ProfileRepository profiles = getRepository().getProfileRepository();
           try
           {
               Type type = types.createType( path );
  @@ -914,7 +945,7 @@
           if( appliance == null )
           {
               Profile profile =
  -                    getRepository().getProfileManager().getProfile( dependency );
  +                    getRepository().getProfileRepository().getProfile( dependency );
               if( profile == null )
               {
                   final String error = REZ.getString( "resolve.fail", dependency );
  @@ -925,7 +956,8 @@
                           new DefaultApplianceContext( profile );
                   context.setPartitionName( partition );
                   context.makeReadOnly();
  -                appliance = createAppliance( context, true );
  +                appliance = createAppliance( 
  +                      context, !profile.getMode().equals( Mode.IMPLICIT ) );
               }
           }
   
  @@ -977,7 +1009,7 @@
           Appliance appliance = m_manager.getAppliance( stage );
           if( appliance == null )
           {
  -            Profile profile = getRepository().getProfileManager().getProfile( stage );
  +            Profile profile = getRepository().getProfileRepository().getProfile( stage );
               if( profile == null )
               {
                   final String error = REZ.getString( "resolve.stage.fail", stage );
  @@ -987,7 +1019,9 @@
                   DefaultApplianceContext context = new DefaultApplianceContext( profile );
                   context.setPartitionName( partition );
                   context.makeReadOnly();
  -                appliance = createAppliance( context, true );
  +                appliance = createAppliance( 
  +                      context, !profile.getMode().equals( Mode.IMPLICIT ) );
  +                //appliance = createAppliance( context, true );
               }
           }
   
  @@ -1024,19 +1058,6 @@
       public Appliance createAppliance(
               ApplianceContext context, boolean shared ) throws ApplianceException
       {
  -        return createAppliance( context, shared, true );
  -    }
  -
  -    /**
  -     * Create a new non-assembled appliance.
  -     * @param context the appliance creation context
  -     * @param shared TRUE if this appliance can be shared
  -     * @param nested if TRUE the return appliance is assigned a child logging channel
  -     * @return the appliance
  -     */
  -    public Appliance createAppliance(
  -            ApplianceContext context, boolean shared, boolean nested ) throws ApplianceException
  -    {
           if( context == null )
           {
               throw new NullPointerException( "context" );
  @@ -1052,8 +1073,8 @@
           } else
           {
               factory =
  -                    DefaultApplianceFactory.createApplianceFactory(
  -                            this, classname, logger, m_manager, getSystemContext() );
  +              DefaultApplianceFactory.createApplianceFactory(
  +                this, classname, logger, m_manager, getSystemContext() );
           }
   
           Appliance appliance = factory.createAppliance( getSystemContext(), this, context, logger );
  
  
  
  1.5       +61 -5     avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/model/DefaultClasspath.java
  
  Index: DefaultClasspath.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/model/DefaultClasspath.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultClasspath.java	20 Apr 2003 12:07:15 -0000	1.4
  +++ DefaultClasspath.java	24 Apr 2003 12:20:19 -0000	1.5
  @@ -60,6 +60,9 @@
   import java.util.ArrayList;
   import java.util.List;
   
  +import org.apache.avalon.assembly.repository.Repository;
  +import org.apache.avalon.assembly.repository.RepositoryException;
  +
   /**
    * <p>A classpath directive that describes a scoped set of jar files and
    * a relative base directory.
  @@ -97,8 +100,46 @@
           {
               throw new NullPointerException( "base" );
           }
  +        
  +        List list = new ArrayList();
  +        expand( base, list );
  +        if( system != null )
  +        {
  +            expandResources( system, list );
  +        }
  +
  +        return (URL[]) list.toArray( new URL[0] );
  +    }
  +
  +    /**
  +     * Expand a classpath to an array of URLS.
  +     * @param repository the system repository
  +     * @param base the base directory from which relative classpath entries
  +     * will be resolved.
  +     */
  +    public URL[] expand( Repository repository, File base )
  +      throws RepositoryException
  +    {
  +        if( base == null )
  +        {
  +            throw new NullPointerException( "base" );
  +        }
   
           List list = new ArrayList();
  +        expand( base, list );
  +        expand( repository, list );
  +
  +        return (URL[]) list.toArray( new URL[0] );
  +    }
  +
  +    /**
  +     * Expand a classpath to an array of URLS.
  +     * @param system the parent directory of the system repository
  +     * @param base the base directory from which relative classpath entries
  +     * will be resolved.
  +     */
  +    private void expand( File base, List list )
  +    {
           FilesetDescriptor[] dirs = m_classpath.getFilesetDescriptors();
           for( int i = 0; i < dirs.length; i++ )
           {
  @@ -129,13 +170,28 @@
                   }
               }
           }
  +    }
   
  -        if( system != null )
  +    /**
  +     * Expand any resource declarations and add them to the supplied list.
  +     */
  +    private void expand( Repository repository, List list ) throws RepositoryException
  +    {
  +        ResourceDescriptor[] resources = m_classpath.getResourceDescriptors();
  +
  +        if(( repository == null ) && resources.length > 0 )
           {
  -            expandResources( system, list );
  +            throw new IllegalStateException( "repository" );
           }
   
  -        return (URL[]) list.toArray( new URL[0] );
  +        for( int i = 0; i < resources.length; i++ )
  +        {
  +            final ResourceDescriptor resource = resources[i];
  +            final String group = resource.getGroupID();
  +            final String name = resource.getName();
  +            final String version = resource.getVersion();
  +            list.add( repository.getArtifact( group, name, version, "jar" ) );
  +        }
       }
   
       /**
  @@ -175,7 +231,7 @@
                   {
                       final String error =
                         "Malformed URL error while attempting add resource: " + resource;
  -                    throw new RuntimeException( error );
  +                    throw new IllegalArgumentException( error );
                   }
               } else
               {
  
  
  
  1.4       +2 -2      avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile/DefaultProfileSelector.java
  
  Index: DefaultProfileSelector.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile/DefaultProfileSelector.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DefaultProfileSelector.java	11 Apr 2003 19:39:18 -0000	1.3
  +++ DefaultProfileSelector.java	24 Apr 2003 12:20:19 -0000	1.4
  @@ -157,7 +157,7 @@
           for( int i = 0; i < profiles.length; i++ )
           {
               Profile profile = profiles[i];
  -            if( profile.getType().getService( dependency.getReference() ) != null )
  +            if( profile.getService( dependency.getReference() ) != null )
               {
                   if( profile.getMode().equals( mode ) )
                   {
  
  
  
  1.3       +1 -1      avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile/package.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- package.html	11 Apr 2003 19:39:18 -0000	1.2
  +++ package.html	24 Apr 2003 12:20:19 -0000	1.3
  @@ -1,4 +1,4 @@
   <p>The <code>profile</code> package contains classes and interfaces for the
  -{@link org.apache.avalon.assembly.engine.profile.DefaultProfileManager} and
  +{@link org.apache.avalon.assembly.engine.profile.DefaultProfileRepository} and
   related default implementations supporting the management of a repository
   of profiles.</p>
  
  
  
  1.1                  avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/profile/DefaultProfileRepository.java
  
  Index: DefaultProfileRepository.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.engine.profile;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.avalon.assembly.engine.type.UnknownTypeException;
  import org.apache.avalon.framework.configuration.Configuration;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.framework.logger.LogEnabled;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.meta.info.ReferenceDescriptor;
  import org.apache.avalon.meta.info.StageDescriptor;
  import org.apache.avalon.meta.info.Type;
  import org.apache.avalon.meta.model.Profile;
  import org.apache.avalon.meta.model.builder.ProfileBuilder;
  import org.apache.avalon.meta.model.verifier.ProfileVerifier;
  import org.apache.excalibur.configuration.ConfigurationUtil;
  
  /**
   * A profile manager implemetation provides support for the creation,
   * storage and retrival of component types.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/04/24 12:20:19 $
   */
  public class DefaultProfileRepository extends AbstractLogEnabled implements ProfileRepository
  {
      //==============================================================
      // static
      //==============================================================
  
      /**
       * The profile builder.
       */
      private static final ProfileBuilder PROFILE_BUILDER = new ProfileBuilder();
  
      //==============================================================
      // state
      //==============================================================
  
      /**
       * The classloader supplied to the manager.
       */
      private ClassLoader m_classloader;
  
      /**
       * The parent profile manager (may be null)
       */
      private ProfileRepository m_parent;
  
      /**
       * List of component profiles.
       */
      private final List m_profiles = new ArrayList();
  
      /**
       * The default profile selector.
       */
      private final DefaultProfileSelector m_selector = new DefaultProfileSelector();
  
      //==============================================================
      // constructor
      //==============================================================
  
      /**
       * Creation of a new root profile manager.
       * @param classloader the classloder to use
       * @exception NullPointerException if the classloader is null
       */
      public DefaultProfileRepository( ClassLoader classloader ) throws NullPointerException
      {
          this( classloader, null );
      }
  
      /**
       * Creation of a new profile manager.
       * @param classloader the classloder to use
       * @param parent the parent type manager
       * @exception NullPointerException if the classloader is null
       */
      public DefaultProfileRepository( ClassLoader classloader, ProfileRepository parent )
              throws NullPointerException
      {
          if( classloader == null )
          {
              throw new NullPointerException( "classloader" );
          }
          m_classloader = classloader;
          m_parent = parent;
      }
  
      //==============================================================
      // implemetation
      //==============================================================
  
      /**
       * Load a set of packaged profiles associated with the supplied class.
       * Profiles returned from this operation are not included within the
       * manager.  To register a profile with the manager use the {@link #addProfile}
       * operation.
       *
       * @param type the component type used to locate an packaged profiles
       * @return the set of packaged component profiles
       * @exception ProfileException if an error occurs while loading package profiles
       */
      public Profile[] loadProfiles( Type type ) throws ProfileException
      {
          if( type == null )
          {
              throw new NullPointerException( "type" );
          }
  
          try
          {
              return PROFILE_BUILDER.build( m_classloader, type );
          } catch( Throwable e )
          {
              final String error =
                      "Unable to create packaged profiles for type: "
                      + type.getInfo().getClassname();
              throw new ProfileException( error, e );
          }
      }
  
      /**
       * Create a profile from a supplied configuration.
       *
       * @param type the component type that the profile qualifies
       * @param config a configuration fragment describing the deployment profile
       * @return the deployment profile
       * @exception ProfileException if an error occurs while attempting to create a profiles
       */
      public Profile createProfile( Type type, Configuration config )
              throws ProfileException
      {
          if( type == null )
          {
              throw new NullPointerException( "type" );
          }
          if( config == null )
          {
              throw new NullPointerException( "config" );
          }
  
          try
          {
              return PROFILE_BUILDER.build( type, config );
          } catch( Throwable e )
          {
              final String error =
                      "Profile build error while constructing a profile from supplied configuration:\n"
                      + ConfigurationUtil.list( config );
              throw new ProfileException( error, e );
          }
      }
  
      /**
       * Add a set of profiles to the manager.
       * @param profiles the deployment profiles to added to the manager
       * @exception DuplicateProfileException if a profile of the same name
       *   is already registered with the manager and the supplied profile
       *   is a equal or lower in priority
       * @exception ProfileException if a profile verification failure occurs
       * @see #createProfile
       */
      public void addProfiles( Profile[] profiles ) throws DuplicateProfileException, ProfileException
      {
          for( int i = 0; i < profiles.length; i++ )
          {
              Profile profile = profiles[i];
              addProfile( profile );
          }
      }
  
      /**
       * Add or replace profile to the manager.
       * @param profile the deployment profile to add to the manager
       * @exception DuplicateProfileException if a profile of the same name
       *   is already registered with the manager and the replacement policy is true
       * @exception ProfileException if a profile verification failure occurs
       * @see #createProfile
       */
      public void addProfile( Profile profile ) throws DuplicateProfileException, ProfileException
      {
          addProfile( profile, true );
      }
  
      /**
       * Add a profile to the manager using the supplied profile and replacement policy
       * @param profile the deployment profile to add to the manager
       * @exception DuplicateProfileException if a profile of the same name
       *   is already registered with the manager and the replacement policy is true
       * @exception ProfileException if a profile verification failure occurs
       * @see #createProfile
       */
      public void addProfile( Profile profile, boolean replace )
              throws DuplicateProfileException, ProfileException
      {
          if( profile == null )
          {
              throw new NullPointerException( "profile" );
          }
  
          if( getLogger() == null )
          {
              throw new IllegalStateException( "logging" );
          }
  
          try
          {
              verify( profile );
          } catch( Throwable e )
          {
              final String error =
                      "Could not register the profile: " + profile
                      + " due to a verification failure.";
              throw new ProfileException( error, e );
          }
  
          if( getLogger().isDebugEnabled() )
          {
              getLogger().debug(
                      "add: " + profile + " " + profile.getMode() );
          }
  
          m_profiles.add( profile );
  
      }
  
      /**
       * Get the preferred profile for a supplied type.
       * @param type the component type
       * @return the profile matching the type
       * @exception UnknownTypeException if the type is unknown to the manager
       */
      public Profile getProfile( Type type ) throws UnknownTypeException
      {
          Iterator iterator = m_profiles.iterator();
          while( iterator.hasNext() )
          {
              Profile profile = (Profile) iterator.next();
              if( profile.getType().equals( type ) )
              {
                  return profile;
              }
          }
  
          if( m_parent != null )
          {
              return m_parent.getProfile( type );
          } else
          {
              return null;
          }
      }
  
      /**
       * Get the set of profiles declared for a particular type.
       * @param type the component type
       * @return the set of profile matching the type.
       * @exception UnknownTypeException if the type is unknown to the manager
       */
      public Profile[] getProfiles( Type type ) throws UnknownTypeException
      {
          if( type == null )
          {
              throw new NullPointerException( "type" );
          }
  
          ArrayList list = new ArrayList();
          if( m_parent != null )
          {
              Profile[] profiles = m_parent.getProfiles( type );
              for( int i = 0; i < profiles.length; i++ )
              {
                  list.add( profiles[i] );
              }
          }
  
          Iterator iterator = m_profiles.iterator();
          while( iterator.hasNext() )
          {
              Profile profile = (Profile) iterator.next();
              if( profile.getType().equals( type ) )
              {
                  list.add( type );
              }
          }
  
          return (Profile[]) list.toArray( new Profile[0] );
      }
  
      /**
       * Locate the set of component profiles capable of services the supplied
       * dependency.
       * @param dependency a service dependency descriptor
       * @return a set of profiles capable of servicing the supplied dependency
       */
      public Profile[] getProfiles( DependencyDescriptor dependency )
      {
          if( dependency == null )
          {
              throw new NullPointerException( "dependency" );
          }
  
          ArrayList list = new ArrayList();
          if( m_parent != null )
          {
              Profile[] profiles = m_parent.getProfiles( dependency );
              for( int i = 0; i < profiles.length; i++ )
              {
                  list.add( profiles[i] );
              }
          }
  
          ReferenceDescriptor reference = dependency.getReference();
  
          Iterator iterator = m_profiles.iterator();
          while( iterator.hasNext() )
          {
              Profile profile = (Profile) iterator.next();
              Object service = profile.getService( reference );
              if( service != null )
              {
                  list.add( profile );
              }
          }
  
          return (Profile[]) list.toArray( new Profile[0] );
      }
  
      /**
       * Locate the set of component profiles that provide the supplied extension.
       * @param stage a stage descriptor
       * @return a set of types that provide the supplied service
       */
      public Profile[] getProfiles( StageDescriptor stage )
      {
          if( stage == null )
          {
              throw new NullPointerException( "stage" );
          }
  
          ArrayList list = new ArrayList();
          if( m_parent != null )
          {
              Profile[] profiles = m_parent.getProfiles( stage );
              for( int i = 0; i < profiles.length; i++ )
              {
                  list.add( profiles[i] );
              }
          }
  
          Iterator iterator = m_profiles.iterator();
          while( iterator.hasNext() )
          {
              Profile profile = (Profile) iterator.next();
              if( profile.getType().getExtension( stage ) != null )
              {
                  list.add( profile );
              }
          }
  
          return (Profile[]) list.toArray( new Profile[0] );
      }
  
      /**
       * Locate the set of profiles tied to a type capable of supporting a service
       * referenced by a supplied dependency descriptor using the default selector.
       * @param dependency a service depedency descriptor
       * @return a set of profiles capable of servicing the supplied dependency
       * @todo replace the code concerning selector establishment with full
       *   component support
       */
      public Profile getProfile( DependencyDescriptor dependency )
      {
          String classname = dependency.getAttribute( "urn:avalon:profile.selector", null );
          if( classname == null )
          {
              return getProfile( dependency, m_selector );
          } else
          {
              try
              {
                  Class clazz = m_classloader.loadClass( classname );
                  ProfileSelector selector = (ProfileSelector) clazz.newInstance();
                  if( selector instanceof LogEnabled )
                  {
                      ((LogEnabled) selector).enableLogging( getLogger().getChildLogger( "selector" ) );
                  }
                  return getProfile( dependency, selector );
              } catch( Throwable e )
              {
                  final String error =
                          "Unexpected error while attempting to create a custom seletor: "
                          + classname;
                  throw new ProfileRuntimeException( error, e );
              }
          }
      }
  
      /**
       * Locate the set of profiles tied to a type capable of supporting a service
       * referenced by a supplied dependency descriptor using a supplied selector.
       * @param dependency a service depedency descriptor
       * @param selector a profile selector
       * @return a set of profiles capable of servicing the supplied dependency
       */
      public Profile getProfile( DependencyDescriptor dependency, ProfileSelector selector )
      {
          Profile[] profiles = getProfiles( dependency );
          return selector.select( profiles, dependency );
      }
  
      /**
       * Locate a profile tied to a type capable of supporting an extension
       * referenced by a supplied stage descriptor usign the default selector.
       * @param stage a stage descriptor
       * @return a set of types that provide the supplied service
       * @todo add selector support
       */
      public Profile getProfile( StageDescriptor stage )
      {
          return getProfile( stage, m_selector );
      }
  
      /**
       * Locate a profile tied to a type capable of supporting an extension
       * referenced by a supplied stage descriptor usign the a suplied selector.
       * @param stage a stage descriptor
       * @param selector a profile selector
       * @return a set of types that provide the supplied service
       */
      public Profile getProfile( StageDescriptor stage, ProfileSelector selector )
      {
          Profile[] profiles = getProfiles( stage );
          return selector.select( profiles, stage );
      }
  
      /**
       * Verify the supplied profile.
       * @param profile the profile to verify
       * @exception ProfileException if the verification failes
       */
      private void verify( Profile profile ) throws ProfileException
      {
          if( profile == null )
          {
              throw new NullPointerException( "profile" );
          }
  
          ProfileVerifier verifier = new ProfileVerifier();
          try
          {
              verifier.verifyType( profile, m_classloader );
          } catch( Throwable e )
          {
              final String error = "Verification failure for profile: "
                      + profile.getName() + " from type: "
                      + profile.getType().getInfo().getClassname();
              throw new ProfileException( error, e );
          }
      }
  }
  
  
  
  1.1                  avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/service/DefaultServiceRepository.java
  
  Index: DefaultServiceRepository.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.engine.service;
  
  import java.util.ArrayList;
  import java.util.Iterator;
  import java.util.List;
  
  import org.apache.avalon.framework.Version;
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.meta.info.ReferenceDescriptor;
  import org.apache.avalon.meta.info.Service;
  import org.apache.avalon.meta.info.builder.ServiceBuilder;
  
  /**
   * A service repository provides support for the storage and retrival
   * of service defintions.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/04/24 12:20:19 $
   */
  public class DefaultServiceRepository extends AbstractLogEnabled implements ServiceRepository
  {
      //==============================================================
      // state
      //==============================================================
  
      /**
       * The classloader supplied to the manager.
       */
      private ClassLoader m_classloader;
  
      /**
       * The parent service manager (may be null)
       */
      private ServiceRepository m_parent;
  
      /**
       * The service builder.
       */
      private static final ServiceBuilder DEFAULT_BUILDER = new ServiceBuilder();
  
      /**
       * List of service entries.
       */
      private List m_services = new ArrayList();
  
      //==============================================================
      // constructor
      //==============================================================
  
      /**
       * Creation of a new root service manager.
       * @param classloader the classloder to use
       * @exception NullPointerException if the classloader is null
       */
      public DefaultServiceRepository( ClassLoader classloader ) throws NullPointerException
      {
          this( classloader, null );
      }
  
      /**
       * Creation of a new service manager.
       * @param classloader the classloder to use
       * @param parent the parent type manager
       * @exception NullPointerException if the classloader is null
       */
      public DefaultServiceRepository( ClassLoader classloader, ServiceRepository parent ) throws NullPointerException
      {
          if( classloader == null )
          {
              throw new NullPointerException( "classloader" );
          }
          m_classloader = classloader;
          m_parent = parent;
      }
  
      //==============================================================
      // implemetation
      //==============================================================
  
      /**
       * Create a services associated from a supplied path.
       *
       * @param clazz the service class
       * @return the service defintions
       * @exception ServiceException if an error occurs during service creation
       */
      public Service createService( Class clazz ) throws ServiceException
      {
          if( clazz == null )
          {
              throw new NullPointerException( "clazz" );
          }
  
          try
          {
              return DEFAULT_BUILDER.build( clazz.getName(), clazz.getClassLoader() );
          } catch( Throwable e )
          {
              final String error =
                      "Could not create a service relative to the path: "
                      + clazz.getName() + " due to a service build error.";
              throw new ServiceException( error, e );
          }
      }
  
      /**
       * Create a service instance based on a supplied classname.
       *
       * @param classname the component implementation classname
       * @return the service defintion
       * @exception ServiceException if an error occurs during service creation
       */
      public Service createService( String classname ) throws ServiceException
      {
          if( classname == null )
          {
              throw new NullPointerException( "classname" );
          }
  
          try
          {
              Class clazz = m_classloader.loadClass( classname );
              return createService( clazz );
          } catch( Throwable e )
          {
              final String error =
                "Unexpected error while attempting to build a service from the classname: " 
                + classname;
              throw new ServiceException( error, e );
          }
      }
  
      /**
       * Locate a {@link Service} instances associated with the
       * supplied classname and version. If a service defintion is not
       * found locally, the implementation redirects the request to
       * the parent service manager.
       *
       * @param classname the service class name
       * @param version the service version
       * @return the service matching the supplied classname and version.
       * @exception UnknownServiceException if a matching service cannot be found
       */
      public Service getService( String classname, Version version ) throws UnknownServiceException
      {
          return getService( new ReferenceDescriptor( classname, version ) );
      }
  
      /**
       * Locate a {@link Service} instances associated with the
       * supplied referecne descriptor. If a service defintion is not
       * found locally, the implementation redirects the request to
       * the parent service manager.
       *
       * @param classname the service class name
       * @param reference the reference descriptor
       * @return the service matching the supplied descriptor.
       * @exception UnknownServiceException if a matching service cannot be found
       */
      public Service getService( ReferenceDescriptor reference ) throws UnknownServiceException
      {
          Service service = getLocalService( reference );
          if( service == null )
          {
              if( m_parent != null )
              {
                  return m_parent.getService( reference );
              } else
              {
                  final String error = "Unknown service defintion: " + reference;
                  throw new UnknownServiceException( error );
              }
          }
          return service;
      }
  
      private Service getLocalService( ReferenceDescriptor reference )
      {
          Iterator iterator = m_services.iterator();
          while( iterator.hasNext() )
          {
              Service service = (Service) iterator.next();
              if( service.equals( reference ) )
              {
                  return service;
              }
          }
          return null;
      }
  
      /**
       * Add a service to the manager.
       *
       * @param service the service defintion
       * @exception DuplicateServiceException if the service already exists
       * @exception ServiceException if the service definition is invalid
       */
      public void addService( Service service ) throws DuplicateServiceException, ServiceException
      {
          if( getLogger() == null )
          {
              throw new IllegalStateException( "logging" );
          }
  
          //
          // make sure that there is not already a local defintion for
          // this service
          //
  
          try
          {
              getService( service.getReference() );
              throw new DuplicateServiceException( service.toString() );
          } catch( UnknownServiceException use )
          {
              // continue
          }
  
          //
          // make sure we are dealing with a service that is verified
          //
  
          verifyService( service );
  
          //
          // make sure that there is not already a local defintion for
          // this service
          //
  
          m_services.add( service );
  
          if( getLogger().isDebugEnabled() )
          {
              StringBuffer buffer = new StringBuffer();
              buffer.append( "add: " + service.getClassname() );
              buffer.append( ":" + service.getVersion() );
              buffer.append( ", entries: " + service.getEntries().length );
              buffer.append( ", attributes: " + service.getAttributeNames().length );
              getLogger().debug( buffer.toString() );
          }
      }
  
      /**
       * Verify that a class exists within the classloader representing the
       * service type.
       * @param service the service to verify
       * @exception ServiceException if a verification error occurs
       */
      private void verifyService( Service service ) throws ServiceException
      {
          Class clazz;
          try
          {
              clazz = m_classloader.loadClass( service.getClassname() );
          } catch( Throwable e )
          {
              final String error = "Unresolvable service class.";
              throw new ServiceException( error, e );
          }
      }
  }
  
  
  
  1.3       +1 -1      avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/type/package.html
  
  Index: package.html
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/type/package.html,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- package.html	11 Apr 2003 19:39:18 -0000	1.2
  +++ package.html	24 Apr 2003 12:20:19 -0000	1.3
  @@ -1,4 +1,4 @@
   <p>The <code>type</code> package contains classes and interfaces for the
  -{@link org.apache.avalon.assembly.engine.type.DefaultTypeManager} and
  +{@link org.apache.avalon.assembly.engine.type.DefaultTypeRepository} and
   related default implementations supporting the management of a repository
   of component types.</p>
  
  
  
  1.1                  avalon-sandbox/merlin/assembly/src/java/org/apache/avalon/assembly/engine/type/DefaultTypeRepository.java
  
  Index: DefaultTypeRepository.java
  ===================================================================
  /*
  
   ============================================================================
                     The Apache Software License, Version 1.1
   ============================================================================
  
   Copyright (C) 1999-2002 The Apache Software Foundation. All rights reserved.
  
   Redistribution and use in source and binary forms, with or without modifica-
   tion, are permitted provided that the following conditions are met:
  
   1. Redistributions of  source code must  retain the above copyright  notice,
      this list of conditions and the following disclaimer.
  
   2. Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
  
   3. The end-user documentation included with the redistribution, if any, must
      include  the following  acknowledgment:  "This product includes  software
      developed  by the  Apache Software Foundation  (http://www.apache.org/)."
      Alternately, this  acknowledgment may  appear in the software itself,  if
      and wherever such third-party acknowledgments normally appear.
  
   4. The names "Jakarta", "Apache Avalon", "Avalon Framework" and
      "Apache Software Foundation"  must not be used to endorse or promote
      products derived  from this  software without  prior written
      permission. For written permission, please contact apache@apache.org.
  
   5. Products  derived from this software may not  be called "Apache", nor may
      "Apache" appear  in their name,  without prior written permission  of the
      Apache Software Foundation.
  
   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
   FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
   APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
   INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
   DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
   OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
   ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
   (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
   This software  consists of voluntary contributions made  by many individuals
   on  behalf of the Apache Software  Foundation. For more  information on the
   Apache Software Foundation, please see <http://www.apache.org/>.
  
  */
  
  package org.apache.avalon.assembly.engine.type;
  
  import java.util.ArrayList;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Iterator;
  
  import org.apache.avalon.framework.logger.AbstractLogEnabled;
  import org.apache.avalon.meta.info.DependencyDescriptor;
  import org.apache.avalon.meta.info.ReferenceDescriptor;
  import org.apache.avalon.meta.info.ServiceDescriptor;
  import org.apache.avalon.meta.info.StageDescriptor;
  import org.apache.avalon.meta.info.Type;
  import org.apache.avalon.meta.info.builder.TypeBuilder;
  import org.apache.avalon.meta.verifier.ComponentVerifier;
  
  /**
   * A type manager implemetation provides support for the creation,
   * storage and retrival of component types.
   *
   * @author <a href="mailto:dev@avalon.apache.org">Avalon Development Team</a>
   * @version $Revision: 1.1 $ $Date: 2003/04/24 12:20:19 $
   */
  public class DefaultTypeRepository extends AbstractLogEnabled implements TypeRepository
  {
      //==============================================================
      // static
      //==============================================================
  
      /**
       * The type builder.
       */
      private static final TypeBuilder DEFAULT_BUILDER = new TypeBuilder();
  
      //==============================================================
      // state
      //==============================================================
  
      /**
       * The classloader supplied to the manager.
       */
      private ClassLoader m_classloader;
  
      /**
       * The parent type manager (may be null)
       */
      private TypeRepository m_parent;
  
      /**
       * Table of component types keyed by implementation classname.
       */
      private final Hashtable m_types = new Hashtable();
  
      //==============================================================
      // constructor
      //==============================================================
  
      /**
       * Creation of a new root type manager.
       * @param classloader the classloder to use
       * @exception NullPointerException if the classloader is null
       */
      public DefaultTypeRepository( ClassLoader classloader ) throws NullPointerException
      {
          this( classloader, null );
      }
  
      /**
       * Creation of a new type manager.
       * @param classloader the classloder to use
       * @param parent the parent type manager
       * @exception NullPointerException if the classloader is null
       */
      public DefaultTypeRepository( ClassLoader classloader, TypeRepository parent )
        throws NullPointerException
      {
          if( classloader == null )
          {
              throw new NullPointerException( "classloader" );
          }
          m_classloader = classloader;
          m_parent = parent;
      }
  
      //==============================================================
      // DefaultTypeRepository
      //==============================================================
  
      /**
       * Create a new type instance.  The type instance returned is not
       * registered with the manager.  To register the type the client
       * must explicity declare the type using the {@link #addType}
       * operation.
       *
       * @param clazz the component implementation class
       * @return the component type
       * @exception TypeException is a type creation error occurs
       * @see #addType
       */
      public Type createType( Class clazz ) throws TypeException
      {
          if( clazz == null )
          {
              throw new NullPointerException( "clazz" );
          }
  
          try
          {
              return DEFAULT_BUILDER.build( clazz.getName(), clazz.getClassLoader() );
          } catch( Throwable e )
          {
              final String error =
                      "Could not register a type relative to the path: "
                      + clazz.getName()
                      + " due to a type build error.";
              throw new TypeException( error, e );
          }
      }
  
      /**
       * Create a type instance based on a supplied classname and classloader.
       *
       * @param classname the component implementation classname
       * @return the component type
       * @exception TypeException is a type creation error occurs
       */
      public Type createType( String classname ) throws TypeException
      {
          if( classname == null )
          {
              throw new NullPointerException( "classname" );
          }
  
          try
          {
              Class clazz = m_classloader.loadClass( classname );
              return createType( clazz );
          } catch( Throwable e )
          {
              final String error =
                "Unexpected error while attempting to build a type from the classname: " 
                + classname;
              throw new TypeException( error, e );
          }
      }
  
      /**
       * Add a type to the manager.
       * @param type the component type description.
       * @exception DuplicateTypeException if the supplied type is already registered
       * @exception TypeException if a type verification failure occurs
       * @see #createType
       */
      public void addType( Type type ) throws DuplicateTypeException, TypeException
      {
          if( type == null )
          {
              throw new NullPointerException( "type" );
          }
  
          if( getLogger() == null )
          {
              throw new IllegalStateException( "logging" );
          }
  
          final String classname = type.getInfo().getClassname();
  
          try
          {
              type = getType( classname );
              //throw new DuplicateTypeException( classname );
              return;
          } catch( UnknownTypeException ute )
          {
              try
              {
                  verify( type );
              } catch( Throwable e )
              {
                  final String error =
                          "Could not register the type: " + classname
                          + " due to a verification failure.";
                  throw new TypeException( error, e );
              }
  
              if( getLogger().isDebugEnabled() )
              {
                  getLogger().debug( "add: " + type );
              }
  
              m_types.put( classname, type );
          }
      }
  
      /**
       * Locate a {@link Type} instances associated with the
       * supplied implementation classname.
       * @param clazz the component type implementation class.
       * @return the type matching the supplied implementation classname.
       * @exception UnknownTypeException if a matching type cannot be found
       */
      public Type getType( Class clazz ) throws UnknownTypeException
      {
          if( clazz == null )
          {
              throw new NullPointerException( "clazz" );
          }
  
          return getType( clazz.getName() );
      }
  
      /**
       * Locate a {@link Type} instances associated with the
       * supplied implementation classname.
       * @param classname the component type implementation class name.
       * @return the type matching the supplied implementation classname.
       * @exception UnknownTypeException if a matching type cannot be found
       */
      public Type getType( String classname ) throws UnknownTypeException
      {
          if( classname == null )
          {
              throw new NullPointerException( "classname" );
          }
  
          Type type = (Type) m_types.get( classname );
          if( type == null )
          {
              if( m_parent != null )
              {
                  return m_parent.getType( classname );
              } else
              {
                  throw new UnknownTypeException( classname );
              }
          }
          return type;
      }
  
      /**
       * Locate the set of component types capable of services the supplied
       * dependency.
       * @param dependency a service dependency descriptor
       * @return a set of types capable of servicing the supplied dependency
       */
      public Type[] getTypes( DependencyDescriptor dependency )
      {
          if( dependency == null )
          {
              throw new NullPointerException( "dependency" );
          }
  
          ArrayList list = new ArrayList();
          if( m_parent != null )
          {
              Type[] types = m_parent.getTypes( dependency );
              for( int i = 0; i < types.length; i++ )
              {
                  list.add( types[i] );
              }
          }
  
          ReferenceDescriptor reference = dependency.getReference();
          Enumeration enum = m_types.elements();
          while( enum.hasMoreElements() )
          {
              Type type = (Type) enum.nextElement();
              Object service = type.getService( reference );
              if( service != null )
              {
                  list.add( type );
              }
          }
          return (Type[]) list.toArray( new Type[0] );
      }
  
      /**
       * Locate the set of component types that provide the supplied extension.
       * @param stage a stage descriptor
       * @return a set of types that support the supplied stage
       */
      public Type[] getTypes( StageDescriptor stage )
      {
          if( stage == null )
          {
              throw new NullPointerException( "stage" );
          }
  
          ArrayList list = new ArrayList();
          if( m_parent != null )
          {
              Type[] types = m_parent.getTypes( stage );
              for( int i = 0; i < types.length; i++ )
              {
                  list.add( types[i] );
              }
          }
  
          Iterator iterator = m_types.entrySet().iterator();
          while( iterator.hasNext() )
          {
              Type type = (Type) iterator.next();
              if( type.getExtension( stage ) != null )
              {
                  list.add( type );
              }
          }
  
          return (Type[]) list.toArray( new Type[0] );
      }
  
      /**
       * Verify the intergrity of the supplied type.
       * @param type the type to verify
       * @exception Exception if an verification failure occurs
       */
      private void verify( Type type ) throws Exception
      {
          String name = type.getInfo().getName();
          Class clazz = getComponentClass( type );
          Class[] classes = getServiceClasses( type );
          ComponentVerifier verifier = new ComponentVerifier();
          verifier.verifyComponent( name, clazz, classes );
      }
  
      /**
       * Return the set of interface classes for a given type that are declared
       * or default to the "native" service access protocol and where the
       * service access model is undefined (i.e. native implementation).
       * access mode.
       *
       * @param type the component type
       * @return an array of classes represnting the type's service interfaces
       */
      private Class[] getServiceClasses( Type type )
      {
          ArrayList list = new ArrayList();
          ServiceDescriptor[] services = type.getServices();
          for( int i = 0; i < services.length; i++ )
          {
              ServiceDescriptor service = services[i];
              if( (service.getAttribute(
                      "urn:avalon:service.protocol", "native" ).equals( "native" ))
                      && (service.getAttribute( "urn:avalon:service.accessor", null ) == null) )
              {
                  list.add( getServiceClass( services[i] ) );
              }
          }
          return (Class[]) list.toArray( new Class[0] );
      }
  
      /**
       * Returns the component type implementation class.
       * @param type the component type descriptor
       * @return the class implementing the component type
       * @exception TypeException if a classloader error occurs
       */
      private Class getComponentClass( Type type ) throws TypeException
      {
          if( null == type )
          {
              throw new NullPointerException( "type" );
          }
  
          final String classname = type.getInfo().getClassname();
  
          try
          {
              return m_classloader.loadClass( classname );
          } catch( Throwable e )
          {
              final String error =
                      "Could not load implementation class for component type: "
                      + classname;
              throw new TypeException( error, e );
          }
      }
  
      /**
       * Returns the service type implementation class.
       * @param service the service type descriptor
       * @return the class implementing the service type
       * @exception TypeRuntimeException if a classloader error occurs
       */
      private Class getServiceClass( ServiceDescriptor service ) throws TypeRuntimeException
      {
          final String classname = service.getReference().getClassname();
          try
          {
              return m_classloader.loadClass( classname );
          } catch( Throwable e )
          {
              final String error =
                      "Could not load implementation class for service type: "
                      + classname;
              throw new TypeRuntimeException( error, e );
          }
      }
  }
  
  
  

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