avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mcconn...@apache.org
Subject cvs commit: avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine DefaultRepositoryManager.java Engine.java EngineClassLoader.java RepositoryManager.java
Date Mon, 09 Dec 2002 03:03:47 GMT
mcconnell    2002/12/08 19:03:47

  Modified:    assembly/src/java/org/apache/avalon/assembly/engine
                        DefaultRepositoryManager.java Engine.java
                        EngineClassLoader.java RepositoryManager.java
  Log:
  Applied some rearrangements of locic between the classloader and
  component repository to better support classloader extension.
  
  Revision  Changes    Path
  1.3       +37 -401   avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/DefaultRepositoryManager.java
  
  Index: DefaultRepositoryManager.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/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	7 Dec 2002 14:00:53 -0000	1.2
  +++ DefaultRepositoryManager.java	9 Dec 2002 03:03:47 -0000	1.3
  @@ -77,7 +77,6 @@
   import org.apache.avalon.assembly.profile.ProfileManager;
   import org.apache.avalon.assembly.service.ServiceManager;
   import org.apache.avalon.assembly.engine.model.*;
  -import org.apache.avalon.assembly.util.DefaultFileFilter;
   import org.apache.avalon.excalibur.extension.Extension;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
  @@ -105,32 +104,16 @@
    * @author <a href="mailto:shea@gtsdesign.com">Gary Shea</a>
    * @version $Revision$ $Date$
    */
  -public class DefaultRepositoryManager extends AbstractLogEnabled implements Contextualizable,
Initializable, RepositoryManager
  +public class DefaultRepositoryManager extends AbstractLogEnabled implements Initializable,
RepositoryManager
   {
       //===================================================================
       // static
       //===================================================================
   
  -    private static final FileFilter JAR_FILTER = new DefaultFileFilter( "jar" );
  -
  -
  -    private static final Resources REZ =
  -        ResourceManager.getPackageResources( DefaultRepositoryManager.class );
  -
  -    /**
  -     * Optional context key referencing an instance of {@link LibraryDescriptor}
  -     *   that defines the set of extension directories to use.
  -     */
  -    public static final String EXTENSIONS_DESCRIPTOR_KEY = "urn:assembly:extensions.descriptor";
  -
  -    /**
  -     * Optional classpath key referencing an instance of {@link ClasspathDescriptor}
  -     *   that defines the set of jar files to install.
  -     */
  -    public static final String CLASSPATH_DESCRIPTOR_KEY = "urn:assembly:classpath.descriptor";
  -
       private static final String X_INFO = "xinfo";
  +
       private static final String X_TYPE = "xtype";
  +
       private static final String X_SERVICE = "xservice";
   
       private static final String AVALON_BLOCK_KEY = "Avalon-Block";
  @@ -142,27 +125,12 @@
       /**
        * Parent repository.
        */
  -    private RepositoryManager m_parent = null;
  +    private RepositoryManager m_parent;
   
       /**
        * Parent repository.
        */
  -    private EngineClassLoader m_classloader;
  -
  -    /**
  -     * The base directory.
  -     */
  -    private File m_home;
  -
  -    /**
  -     * Description of the extension directories.
  -     */
  -    private LibraryDescriptor m_extensions;
  -
  -    /**
  -     * Utility class to manage extension jar files.
  -     */
  -    private PackageManager m_manager;
  +    private ClassLoader m_classloader;
   
       /**
        * The registry of installed component types.
  @@ -180,58 +148,28 @@
       private ProfileManager m_profiles;
   
       /**
  -     * The bootstrap flag..
  +     * List of jar files already installed.
        */
  -    private Boolean m_bootstrap = new Boolean( false );
  -
       private List m_scanned = new ArrayList();
   
  -    //==============================================================
  -    // Contextualizable
  -    //==============================================================
  -
  -   /**
  -    * <p>Application of a runtime context to the lifestyle service.
  -    * The context value will be passed directly to lifestyle handlers 
  -    * established by this service.
  -    * @param context the runtime context
  -    */
  -    public void contextualize( Context context ) throws ContextException
  +    //===================================================================
  +    // constructor
  +    //===================================================================
  +
  +    DefaultRepositoryManager( ClassLoader classloader )
       {
  -        m_classloader = (EngineClassLoader) context.get( "urn:assembly:engine.classloader"
);
  -        m_extensions = (LibraryDescriptor) context.get( "urn:assembly:libraries-descriptor"
);
  -        m_home = (File) context.get( "urn:avalon:home" );
  +        this( classloader, null );
  +    }
   
  -        try
  -        {
  -            m_bootstrap = (Boolean) context.get( "urn:assembly:engine.bootstrap" );
  -        }
  -        catch( ContextException ce )
  -        {
  -            // use default value
  -        }
  -        catch( Throwable ce )
  -        {
  -            throw new IllegalArgumentException( "urn:assembly:engine.bootstrap" );
  -        }
  -        
  -        try
  +    DefaultRepositoryManager( ClassLoader classloader, RepositoryManager parent )
  +    {
  +        if( classloader == null )
           {
  -            m_parent = (RepositoryManager) context.get( "urn:assembly:repository.parent"
);
  -            m_types = new TypeManager( m_classloader, m_parent.getTypeManager() );
  -            m_services = new ServiceManager( m_classloader, m_parent.getServiceManager()
 );
  -            m_profiles = new ProfileManager( m_classloader, m_parent.getProfileManager()
 );
  -        }
  -        catch( ContextException ce )
  -        {
  -            m_services = new ServiceManager( m_classloader, null );
  -            m_types = new TypeManager( m_classloader, null );
  -            m_profiles = new ProfileManager( m_classloader, null );
  +            throw new NullPointerException( "classloader" );
           }
   
  -        m_services.enableLogging( getLogger().getChildLogger( "services" ) );
  -        m_types.enableLogging( getLogger().getChildLogger( "types" ) );
  -        m_profiles.enableLogging( getLogger().getChildLogger( "profiles" ) );
  +        m_classloader = classloader;
  +        m_parent = parent;
       }
   
       //===================================================================
  @@ -249,101 +187,25 @@
              throw new IllegalStateException( "logging" );
           }
   
  -        ArrayList list = new ArrayList();
  -        File anchor = new File( m_home, m_extensions.getBaseDirectory() );
  -        IncludeDescriptor[] includes = m_extensions.getIncludeDescriptors();
  -        for( int j = 0; j < includes.length; j++ )
  -        {
  -            File include = new File( anchor, includes[ j ].getFile() );
  -            if( include.isDirectory() )
  -            {
  -                list.add( include );
  -                getLogger().debug( "including kernel extension dir: " + include );
  -            }
  -            else
  -            {
  -                final String error = "Invalid include directory: " + include;
  -                throw new IllegalArgumentException( error );
  -            }
  -        }
  +        ServiceManager services = null;
  +        TypeManager types = null;
  +        ProfileManager profiles = null;
   
  -        if( m_bootstrap.booleanValue() )
  +        if( m_parent != null )
           {
  -            String sep = System.getProperty( "path.separator" );
  -            String exts = System.getProperty( "java.ext.dirs" );
  -            StringTokenizer tokenizer = new StringTokenizer( exts, sep );
  -            while( tokenizer.hasMoreTokens() )
  -            {
  -                String token = tokenizer.nextToken();
  -                File test = new File( token );
  -                if( test.exists() )
  -                {
  -                    list.add( test );
  -                    if( getLogger().isDebugEnabled() )
  -                    {
  -                        getLogger().debug( "including system extension dir: " + test );
  -                    }
  -                }
  -                else
  -                {
  -                    File file = new File( m_home, token );
  -                    if( file.exists() )
  -                    {
  -                        list.add( file  );
  -                        if( getLogger().isDebugEnabled() )
  -                        {
  -                            getLogger().debug( "including relative extension dir: " + file
);
  -                        }
  -                    }
  -                    else
  -                    {
  -                        if( getLogger().isWarnEnabled() )
  -                        {
  -                            final String warning = 
  -                              "The extension directory path: '" + token 
  -                              + "' deas not refer to a directory.";
  -                            getLogger().warn( warning );
  -                        }
  -                    }
  -                }
  -            }
  +            services = m_parent.getServiceManager();
  +            types = m_parent.getTypeManager();
  +            profiles = m_parent.getProfileManager();
           }
   
  -        File[] files = (File[])list.toArray( new File[ 0 ] );
  -        ExtensionManager repository = new DefaultExtensionManager( files );
  -        m_manager = new PackageManager( repository );
  -
  -        //
  -        // handle the system bootstrap process
  -        //
  -
  -        if( m_bootstrap.booleanValue() )
  -        {
  -
  -            if( getLogger().isDebugEnabled() )
  -            {
  -               getLogger().debug( "bootstraping from classpath" );
  -            }
  -
  -            //
  -            // handle the classpath
  -            //
  +        m_services = new ServiceManager( m_classloader, services );
  +        m_services.enableLogging( getLogger().getChildLogger( "services" ) );
   
  -            String sep = System.getProperty( "path.separator" );
  -            String classpath = System.getProperty( "java.class.path" );
  +        m_types = new TypeManager( m_classloader, types );
  +        m_types.enableLogging( getLogger().getChildLogger( "types" ) );
   
  -            StringTokenizer tokenizer = new StringTokenizer( classpath, sep );
  -            while( tokenizer.hasMoreTokens() )
  -            {
  -                String token = tokenizer.nextToken();
  -                URL jar = new File( token ).toURL();
  -                if( getLogger().isDebugEnabled() )
  -                {
  -                    getLogger().debug( "path: " + jar );
  -                }
  -                addLibrary( jar );
  -            }
  -        }
  +        m_profiles = new ProfileManager( m_classloader, profiles );
  +        m_profiles.enableLogging( getLogger().getChildLogger( "profiles" ) );
       }
   
       //=======================================================================
  @@ -366,121 +228,10 @@
       }
   
       /**
  -     * Add a classpath to the repository.
  -     * @param base the base directory from which relative classpath entries
  -     * will be resolved.
  -     */
  -    public void addClasspath( ClasspathDescriptor classpath )
  -    {
  -        if( classpath == null )
  -        {
  -            throw new NullPointerException( "classpath" );
  -        }
  -
  -        if( getLogger() == null )
  -        {
  -            throw new IllegalStateException( "logging" );
  -        }
  -
  -        if( getLogger().isDebugEnabled() )
  -        {
  -           getLogger().debug( "adding classpath" );
  -        }
  -
  -        List list = new ArrayList();
  -        Vector stack = new Vector();
  -        FilesetDescriptor[] dirs = classpath.getFilesetDescriptors();
  -        for( int i = 0; i < dirs.length; i++ )
  -        {
  -            FilesetDescriptor descriptor = dirs[ i ];
  -            File anchor = new File( m_home, descriptor.getBaseDirectory() );
  -            if( !anchor.exists() )
  -            {
  -                final String error =
  -                  "Classpath base directory does not exist: " 
  -                  + anchor;
  -                throw new EngineRuntimeException( error );
  -            }
  -
  -            IncludeDescriptor[] includes = descriptor.getIncludeDescriptors();
  -            for( int j = 0; j < includes.length; j++ )
  -            {
  -                String inc = includes[ j ].getFile();
  -                try
  -                {
  -                    addLibrary( new File( anchor, inc ).toURL() );
  -                }
  -                catch( Throwable e )
  -                {
  -                    final String error = 
  -                      "Error processing a classpath include: " 
  -                      + inc;
  -                    throw new EngineRuntimeException( error, e );
  -                }
  -            }
  -        }
  -
  -        if( getLogger().isDebugEnabled() )
  -        {
  -           getLogger().debug( "classpath ok" );
  -        }
  -    }
  -
  -    /**
        * Add a URL to the classpath.
  -     * @param url the URL to add to the classpath
  -     */
  -    public void addLibrary( URL url )
  -    {
  -        //if( !m_scanned.contains( url ) )
  -        //{
  -            addExtensions( url );
  -            m_classloader.addLibraryURL( url );
  -            scan( url );
  -        //}
  -    }
  -
  -    private void addExtensions( URL url )
  -    {
  -        if( isDirectory( url ) )
  -        {
  -            return;
  -        }
  -
  -        try
  -        {
  -            String[] path = urlsToStrings( new URL[]{ url } );
  -            final File[] extensions = getOptionalPackagesFor( path );
  -            for( int i = 0; i < extensions.length; i++ )
  -            {
  -                File ext = extensions[ i ];
  -                try
  -                {
  -                    URL target = ext.toURL();
  -                    addLibrary( target );
  -                }
  -                catch( Throwable e )
  -                {
  -                    final String error = 
  -                      "Internal error while attempting to add optional package: " + ext;
  -                    throw new EngineRuntimeException( error, e );
  -                }
  -            } 
  -        }
  -        catch( Throwable e )
  -        {
  -            final String error = 
  -             "Internal error while attempting to add extension url: " + url;
  -            throw new EngineRuntimeException( error, e );
  -        }
  -    }
  -
  -    /**
  -     * Register any components declared in the manifest.
  -     * @param url pointing to the jar file
  -     * @exception EngineRuntimeException if an scanning error occurs
  +     * @param url the URL to add to the repository
        */
  -    private void scan( URL url ) throws EngineRuntimeException
  +    public void install( URL url )
       {
           if( isDirectory( url ) )
           {
  @@ -521,8 +272,7 @@
                   getLogger().debug( "scanning: " + url );
               }
               JarFile base = jar.getJarFile();
  -            loadComponents( base );
  -
  +            load( base );
           }
           catch( IOException e )
           {
  @@ -538,7 +288,7 @@
           }
       }
   
  -    private void loadComponents( JarFile base ) throws IOException
  +    private void load( JarFile base ) throws IOException
       {
   
           List list = new ArrayList();
  @@ -634,118 +384,4 @@
           return name.replace( '/', '.' );
       }
   
  -    private String[] urlsToStrings( URL[] urls )
  -    {
  -        Vector vector = new Vector();
  -        for( int i = 0; i < urls.length; i++ )
  -        {
  -            vector.add( urls[ i ].toString() );
  -        }
  -        return (String[])vector.toArray( new String[ vector.size() ] );
  -    }
  -
  -    //================================================================================
  -    // extension libraries
  -    //================================================================================
  -
  -    /**
  -     * Retrieve the files for the optional packages required by
  -     * the jars in ClassPath.
  -     *
  -     * @param classPath the Classpath array
  -     * @return the files that need to be added to ClassLoader
  -     * @exception Exception if a extension error occurs
  -     */
  -    protected File[] getOptionalPackagesFor( final String[] classPath )
  -        throws Exception
  -    {
  -        if( m_manager == null )
  -        {
  -            RepositoryManager parent = getParent();
  -            if( parent != null )
  -            {
  -                if( parent instanceof DefaultRepositoryManager )
  -                {
  -                    return ( (DefaultRepositoryManager)parent).getOptionalPackagesFor(
classPath );
  -                }
  -            }
  -            return new File[ 0 ];
  -        }
  -
  -        final Manifest[] manifests = getManifests( classPath );
  -        final Extension[] available = Extension.getAvailable( manifests );
  -        final Extension[] required = Extension.getRequired( manifests );
  -
  -        final ArrayList dependencies = new ArrayList();
  -        final ArrayList unsatisfied = new ArrayList();
  -
  -        m_manager.scanDependencies( required,
  -                                    available,
  -                                    dependencies,
  -                                    unsatisfied );
  -
  -        if( 0 != unsatisfied.size() )
  -        {
  -            final int size = unsatisfied.size();
  -            for( int i = 0; i < size; i++ )
  -            {
  -                final Extension extension = (Extension)unsatisfied.get( i );
  -                final Object[] params = new Object[]
  -                {
  -                    extension.getExtensionName(),
  -                    extension.getSpecificationVendor(),
  -                    extension.getSpecificationVersion(),
  -                    extension.getImplementationVendor(),
  -                    extension.getImplementationVendorID(),
  -                    extension.getImplementationVersion(),
  -                    extension.getImplementationURL()
  -                };
  -                final String message = REZ.format( "missing.extension", params );
  -                getLogger().warn( message );
  -            }
  -
  -            final String message =
  -                REZ.getString( "unsatisfied.extensions", new Integer( size ) );
  -            throw new Exception( message );
  -        }
  -
  -        final OptionalPackage[] packages =
  -            (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] );
  -        return OptionalPackage.toFiles( packages );
  -    }
  -
  -    private Manifest[] getManifests( final String[] classPath )
  -        throws Exception
  -    {
  -        final ArrayList manifests = new ArrayList();
  -
  -        for( int i = 0; i < classPath.length; i++ )
  -        {
  -            final String element = classPath[ i ];
  -            if( element.endsWith( ".jar" ) )
  -            {
  -                try
  -                {
  -                    final URL url = new URL( "jar:" + element + "!/" );
  -                    final JarURLConnection connection =
  -                        (JarURLConnection)url.openConnection();
  -                    final Manifest manifest = connection.getManifest();
  -                    manifests.add( manifest );
  -                }
  -                catch( final IOException ioe )
  -                {
  -                    final String message =
  -                        REZ.getString( "bad-classpath-entry", element );
  -                    throw new EngineException(
  -                        message + ": " + element, ioe );
  -                }
  -            }
  -        }
  -        return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
  -    }
  -
  -    RepositoryManager getParent()
  -    {
  -        return m_parent;
  -    }
   }
  
  
  
  1.4       +2 -2      avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/Engine.java
  
  Index: Engine.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/Engine.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Engine.java	7 Dec 2002 09:34:28 -0000	1.3
  +++ Engine.java	9 Dec 2002 03:03:47 -0000	1.4
  @@ -71,7 +71,7 @@
    * @author <a href="mailto:avalon-dev@jakarta.apache.org">Avalon Development Team</a>
    * @version $Revision$ $Date$
    */
  -public interface Engine extends RepositoryManager, AssemblyService
  +public interface Engine extends AssemblyService
   {
      /**
       * Creation of a new lifestyle handler.
  
  
  
  1.3       +409 -98   avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java
  
  Index: EngineClassLoader.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/EngineClassLoader.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- EngineClassLoader.java	7 Dec 2002 14:00:53 -0000	1.2
  +++ EngineClassLoader.java	9 Dec 2002 03:03:47 -0000	1.3
  @@ -53,9 +53,22 @@
   import java.io.File;
   import java.util.Map;
   import java.util.Hashtable;
  +import java.util.StringTokenizer;
  +import java.util.List;
   import java.net.URL;
   import java.net.URLClassLoader;
  -
  +import java.util.jar.Manifest;
  +import java.util.jar.Attributes;
  +import java.net.JarURLConnection;
  +import java.util.ArrayList;
  +import java.io.IOException;
  +
  +import org.apache.avalon.excalibur.extension.Extension;
  +import org.apache.avalon.excalibur.i18n.ResourceManager;
  +import org.apache.avalon.excalibur.i18n.Resources;
  +import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  +import org.apache.avalon.excalibur.packagemanager.PackageManager;
  +import org.apache.avalon.excalibur.packagemanager.impl.DefaultExtensionManager;
   import org.apache.avalon.framework.Version;
   import org.apache.avalon.framework.activity.Initializable;
   import org.apache.avalon.framework.logger.Logger;
  @@ -77,6 +90,8 @@
   import org.apache.avalon.meta.info.ReferenceDescriptor;
   import org.apache.avalon.meta.info.Type;
   import org.apache.avalon.meta.model.Profile;
  +import org.apache.avalon.meta.model.LoggingDirective;
  +import org.apache.avalon.meta.model.Category;
   import org.apache.avalon.assembly.type.TypeManager;
   import org.apache.avalon.assembly.profile.ProfileManager;
   import org.apache.avalon.assembly.appliance.Appliance;
  @@ -94,9 +109,14 @@
   import org.apache.avalon.assembly.lifestyle.LifestyleService;
   import org.apache.avalon.assembly.lifestyle.DefaultLifestyleService;
   import org.apache.avalon.assembly.lifestyle.LifestyleHandler;
  +import org.apache.avalon.assembly.logging.LoggingDescriptor;
  +import org.apache.avalon.assembly.logging.DefaultLoggingManager;
   import org.apache.avalon.assembly.logging.LoggingManager;
  +import org.apache.avalon.assembly.logging.TargetDescriptor;
   import org.apache.avalon.assembly.engine.model.LibraryDescriptor;
   import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
  +import org.apache.avalon.assembly.engine.model.FilesetDescriptor;
  +import org.apache.avalon.assembly.engine.model.IncludeDescriptor;
   import org.apache.excalibur.mpool.DefaultPoolManager;
   import org.apache.excalibur.mpool.PoolManager;
   import org.apache.excalibur.event.command.CommandManager;
  @@ -111,6 +131,13 @@
   public class EngineClassLoader extends URLClassLoader implements Engine, LogEnabled, Configurable,
Contextualizable, Serviceable, Initializable
   {
       //==============================================================
  +    // static
  +    //==============================================================
  +
  +    private static final Resources REZ =
  +        ResourceManager.getPackageResources( Engine.class );
  +
  +    //==============================================================
       // state
       //==============================================================
   
  @@ -146,7 +173,7 @@
       * The repository maanger holds the service, types and profiels associated
       * with the class loader.
       */
  -    private RepositoryManager m_repository;
  +    private DefaultRepositoryManager m_repository;
   
      /**
       * The lifestyle service.
  @@ -184,25 +211,34 @@
       /**
        * Description of the extension directories.
        */
  -    private LibraryDescriptor m_extensions;
  +    private LibraryDescriptor m_descriptor;
   
       /**
  -     * Flag indicating if system classpath based bootstrapping should take place.
  +     * The set of facilities.
        */
  -    private Boolean m_bootstrap = new Boolean( false );
  +    private Map m_facilities = new Hashtable();
   
       /**
  -     * The set of facilities.
  +     * Utility class to manage packages.
        */
  -    private Map m_facilities = new Hashtable();
  +    private PackageManager m_packages;
  +
  +    /**
  +     * Utility class to manage extension paths.
  +     */
  +    private DefaultExtensionManager m_extensions;
  +
  +    /**
  +     * Flag indicating if system classpath based bootstrapping should take place.
  +     */
  +    private boolean m_bootstrap = false;
   
       //=======================================================================
       // constructor
       //=======================================================================
   
       /**
  -     * Creation of a new type manager using the supplied parent class loader.
  -     * @param parent the parent class loader
  +     * Creation of a new type manager using.
        */
       public EngineClassLoader()
       {
  @@ -232,7 +268,6 @@
           return m_logger;
       }
   
  -
       //==============================================================
       // Configurable
       //==============================================================
  @@ -274,11 +309,11 @@
   
           try
           {
  -            m_extensions = (LibraryDescriptor)context.get( "urn:assembly:extensions.descriptor"
);
  +            m_descriptor = (LibraryDescriptor)context.get( "urn:assembly:extensions.descriptor"
);
           }
           catch( ContextException e )
           {
  -            m_extensions = new LibraryDescriptor();
  +            m_descriptor = new LibraryDescriptor();
           }
   
           try
  @@ -292,11 +327,11 @@
   
           try
           {
  -            m_bootstrap = (Boolean) context.get( "urn:assembly:engine.bootstrap" );
  +            m_bootstrap = "true".equals( context.get( "urn:assembly:engine.bootstrap" )
);
           }
  -        catch( ContextException e )
  +        catch( ContextException ce )
           {
  -            // default already set
  +            // use default value
           }
       }
   
  @@ -353,84 +388,240 @@
           {
               getLogger().debug( "initialization" );
           }
  -         
  -        m_repository = createRepositoryManager(); 
  +
  +        createRepositoryManager();
  +
           m_lifestyle = createLifestyleService( m_facilities );
           m_appliances = createApplianceManager( m_facilities );
           m_assembly = createAssemblyService( m_facilities, m_graph );
                                    
  -        if( getLogger().isDebugEnabled() )
  +        //
  +        // install the set of extensions
  +        //
  +
  +        ArrayList list = new ArrayList();
  +        File anchor = new File( m_home, m_descriptor.getBaseDirectory() );
  +        IncludeDescriptor[] includes = m_descriptor.getIncludeDescriptors();
  +        for( int j = 0; j < includes.length; j++ )
           {
  -            getLogger().debug( "ready" );
  +            File include = new File( anchor, includes[ j ].getFile() );
  +            if( include.isDirectory() )
  +            {
  +                list.add( include );
  +                getLogger().debug( "including kernel extension dir: " + include );
  +            }
  +            else
  +            {
  +                final String error = "Invalid include directory: " + include;
  +                throw new IllegalArgumentException( error );
  +            }
           }
  -    }
   
  +        if( m_bootstrap )
  +        {
  +            String sep = System.getProperty( "path.separator" );
  +            String exts = System.getProperty( "java.ext.dirs" );
  +            StringTokenizer tokenizer = new StringTokenizer( exts, sep );
  +            while( tokenizer.hasMoreTokens() )
  +            {
  +                String token = tokenizer.nextToken();
  +                File test = new File( token );
  +                if( test.exists() )
  +                {
  +                    list.add( test );
  +                    if( getLogger().isDebugEnabled() )
  +                    {
  +                        getLogger().debug( "including system extension dir: " + test );
  +                    }
  +                }
  +                else
  +                {
  +                    File file = new File( m_home, token );
  +                    if( file.exists() )
  +                    {
  +                        list.add( file  );
  +                        if( getLogger().isDebugEnabled() )
  +                        {
  +                            getLogger().debug( "including relative extension dir: " + file
);
  +                        }
  +                    }
  +                    else
  +                    {
  +                        if( getLogger().isWarnEnabled() )
  +                        {
  +                            final String warning = 
  +                              "The extension directory path: '" + token 
  +                              + "' deas not refer to a directory.";
  +                            getLogger().warn( warning );
  +                        }
  +                    }
  +                }
  +            }
  +        }
   
  -    //==============================================================
  -    // AssemblyService
  -    //==============================================================
  +        File[] files = (File[])list.toArray( new File[ 0 ] );
  +        m_extensions = new DefaultExtensionManager( files );
  +        m_packages = new PackageManager( m_extensions );
   
  -   /**
  -    * Assemble the supplied appliance.
  -    * @param appliance the object to assembly
  -    */
  -    public void assemble( Appliance appliance ) throws AssemblyException
  -    {
  -        m_assembly.assemble( appliance );
  +        //
  +        // handle the system bootstrap process
  +        //
  +
  +        if( m_bootstrap )
  +        {
  +
  +            if( getLogger().isDebugEnabled() )
  +            {
  +               getLogger().debug( "bootstraping from classpath" );
  +            }
  +
  +            //
  +            // handle the classpath
  +            //
  +
  +            String sep = System.getProperty( "path.separator" );
  +            String classpath = System.getProperty( "java.class.path" );
  +
  +            StringTokenizer tokenizer = new StringTokenizer( classpath, sep );
  +            while( tokenizer.hasMoreTokens() )
  +            {
  +                String token = tokenizer.nextToken();
  +                URL url = new File( token ).toURL();
  +                if( getLogger().isDebugEnabled() )
  +                {
  +                    getLogger().debug( "path: " + url );
  +                }
  +                addURL( url );
  +            }
  +        }
  +
  +        if( getLogger().isDebugEnabled() )
  +        {
  +            getLogger().debug( "ready" );
  +        }
       }
   
       //==============================================================
  -    // RepositoryManager
  +    // URLClassLoader
       //==============================================================
   
  -   /**
  -    * Add a URL to a jar file. A repository implementation is responsible for
  -    * the registration of any declared component services, types and packaged
  -    * profiles.
  -    *
  -    * @param url a url to a jar file
  -    */
  -    public void addLibrary( URL url )
  +    /**
  +     * Add a URL to the classpath.
  +     * @param url the URL to add to the classpath
  +     */
  +    protected void addURL( URL url )
       {
  -        m_repository.addLibrary( url );
  +        addExtensions( url );
  +        super.addURL( url );
  +        m_repository.install( url );
       }
   
       /**
        * Add a classpath to the repository.
        * @param base the base directory from which relative classpath entries
        * will be resolved.
  -     * @param classpath the classpath descriptor
        */
       public void addClasspath( ClasspathDescriptor classpath )
       {
  -        m_repository.addClasspath( classpath );
  -    }
  +        if( classpath == null )
  +        {
  +            throw new NullPointerException( "classpath" );
  +        }
   
  -   /**
  -    * Returns the type manager.
  -    * @return the type manager
  -    */
  -    public TypeManager getTypeManager()
  -    {
  -        return m_repository.getTypeManager();
  +        if( getLogger() == null )
  +        {
  +            throw new IllegalStateException( "logging" );
  +        }
  +
  +        if( getLogger().isDebugEnabled() )
  +        {
  +           getLogger().debug( "adding classpath" );
  +        }
  +
  +        List list = new ArrayList();
  +        FilesetDescriptor[] dirs = classpath.getFilesetDescriptors();
  +        for( int i = 0; i < dirs.length; i++ )
  +        {
  +            FilesetDescriptor descriptor = dirs[ i ];
  +            File anchor = new File( m_home, descriptor.getBaseDirectory() );
  +            if( !anchor.exists() )
  +            {
  +                final String error =
  +                  "Classpath base directory does not exist: " 
  +                  + anchor;
  +                throw new EngineRuntimeException( error );
  +            }
  +
  +            IncludeDescriptor[] includes = descriptor.getIncludeDescriptors();
  +            for( int j = 0; j < includes.length; j++ )
  +            {
  +                String inc = includes[ j ].getFile();
  +                try
  +                {
  +                    addURL( new File( anchor, inc ).toURL() );
  +                }
  +                catch( Throwable e )
  +                {
  +                    final String error = 
  +                      "Error processing a classpath include: " 
  +                      + inc;
  +                    throw new EngineRuntimeException( error, e );
  +                }
  +            }
  +        }
  +
  +        if( getLogger().isDebugEnabled() )
  +        {
  +           getLogger().debug( "classpath ok" );
  +        }
       }
   
  -   /**
  -    * Returns the service manager.
  -    * @return the service manager
  -    */
  -    public org.apache.avalon.assembly.service.ServiceManager getServiceManager()
  +    private void addExtensions( URL url )
       {
  -        return m_repository.getServiceManager();
  +        if( isDirectory( url ) )
  +        {
  +            return;
  +        }
  +
  +        try
  +        {
  +            String[] path = urlsToStrings( new URL[]{ url } );
  +            final File[] extensions = getOptionalPackagesFor( path );
  +            for( int i = 0; i < extensions.length; i++ )
  +            {
  +                File ext = extensions[ i ];
  +                try
  +                {
  +                    URL target = ext.toURL();
  +                    addURL( target );
  +                }
  +                catch( Throwable e )
  +                {
  +                    final String error = 
  +                      "Internal error while attempting to add optional package: " + ext;
  +                    throw new EngineRuntimeException( error, e );
  +                }
  +            } 
  +        }
  +        catch( Throwable e )
  +        {
  +            final String error = 
  +             "Internal error while attempting to add extension url: " + url;
  +            throw new EngineRuntimeException( error, e );
  +        }
       }
   
  +    //==============================================================
  +    // AssemblyService
  +    //==============================================================
  +
      /**
  -    * Returns the profile manager.
  -    * @return the profile manager
  +    * Assemble the supplied appliance.
  +    * @param appliance the object to assembly
       */
  -    public ProfileManager getProfileManager()
  +    public void assemble( Appliance appliance ) throws AssemblyException
       {
  -        return m_repository.getProfileManager();
  +        m_assembly.assemble( appliance );
       }
   
       //==============================================================
  @@ -438,6 +629,15 @@
       //==============================================================
   
      /**
  +    * Returns the repository manager.
  +    * @return the repository manager
  +    */
  +    public RepositoryManager getRepository()
  +    {
  +        return m_repository;
  +    }
  +
  +   /**
       * Creation of a new lifestyle handler.
       * @param appliance the appliance that the handler will manage
       * @param context the system context
  @@ -448,20 +648,6 @@
           return m_lifestyle.createHandler( appliance, this, context );
       }
   
  -    /**
  -     * Add a URL to the classpath.
  -     * @param url the URL to add to the classpath
  -     */
  -    void addLibraryURL( URL url )
  -    {
  -        addURL( url );
  -    }
  -
  -    protected void addURL( URL url )
  -    {
  -        super.addURL( url );
  -    }
  -
      /**
       * Register a type and associated profiles with the container.
       * @param path the path to the appliance implementation class
  @@ -474,12 +660,14 @@
               getLogger().debug( "register:" + path );
           }
   
  +        TypeManager types = getRepository().getTypeManager();
  +        ProfileManager profiles = getRepository().getProfileManager();
           try
           {
  -            Type type = getTypeManager().createType( path );
  -            getTypeManager().addType( type );
  -            Profile[] profiles = getProfileManager().loadProfiles( type );
  -            getProfileManager().addProfiles( profiles );
  +            Type type = types.createType( path );
  +            types.addType( type );
  +            Profile[] packaged = profiles.loadProfiles( type );
  +            profiles.addProfiles( packaged );
           }
           catch( Throwable e )
           {
  @@ -510,7 +698,7 @@
           Appliance appliance = m_appliances.getAppliance( dependency );
           if( appliance == null )
           {
  -            Profile profile = getProfileManager().getProfile( dependency );
  +            Profile profile = getRepository().getProfileManager().getProfile( dependency
);
               if( profile == null )
               {
                   final String error = 
  @@ -547,7 +735,7 @@
           Appliance appliance = m_appliances.getAppliance( stage );
           if( appliance == null )
           {
  -            Profile profile = getProfileManager().getProfile( stage );
  +            Profile profile = getRepository().getProfileManager().getProfile( stage );
               if( profile == null )
               {
                   final String error = 
  @@ -607,26 +795,21 @@
       // utilities
       //==============================================================
   
  -    private RepositoryManager createRepositoryManager() throws Exception
  +    private void createRepositoryManager() throws Exception
       {
  -        if( getLogger().isDebugEnabled() )
  +        ClassLoader parent = getParent();
  +        if(( parent != null ) && ( parent instanceof EngineClassLoader ))
           {
  -            getLogger().debug( "creating repository manager" );
  +            m_repository = 
  +             new DefaultRepositoryManager( 
  +               this, ((EngineClassLoader)parent).getRepository() );
           }
  -
  -        DefaultRepositoryManager manager = new DefaultRepositoryManager();
  -
  -        manager.enableLogging( getLogger() );
  -        DefaultContext context = new DefaultContext( getSystemContext() );
  -        context.put( "urn:assembly:engine.classloader", this );
  -        context.put( "urn:assembly:libraries-descriptor", m_extensions );
  -        context.put( "urn:assembly:engine.bootstrap", m_bootstrap );
  -        context.put( "urn:avalon:home", m_home );
  -        context.makeReadOnly();
  -        manager.contextualize( context );
  -        manager.initialize();
  -
  -        return manager;
  +        else
  +        {
  +            m_repository = new DefaultRepositoryManager( this );
  +        }
  +        m_repository.enableLogging( getLogger() );
  +        m_repository.initialize();
       }
   
       private ApplianceManager createApplianceManager( Map facilities ) 
  @@ -809,5 +992,133 @@
                 "Internal error during establishment of the default pool manager.";
               throw new EngineRuntimeException( error, e );
           }
  +    }
  +
  +    private boolean isDirectory( URL url )
  +    {
  +        if( url.getProtocol().equals( "file" ) )
  +        {
  +            File file = new File( url.toString().substring( 5 ) );
  +            return file.isDirectory();
  +        }
  +        return false;
  +    }
  +
  +    private String[] urlsToStrings( URL[] urls )
  +    {
  +        ArrayList list = new ArrayList();
  +        for( int i = 0; i < urls.length; i++ )
  +        {
  +            list.add( urls[ i ].toString() );
  +        }
  +        return (String[])list.toArray( new String[ list.size() ] );
  +    }
  +
  +    //================================================================================
  +    // extension support
  +    //================================================================================
  +
  +    /**
  +     * Retrieve the files for the optional packages required by
  +     * the jars in ClassPath.
  +     *
  +     * @param classPath the Classpath array
  +     * @return the files that need to be added to ClassLoader
  +     * @exception Exception if a extension error occurs
  +     */
  +    protected File[] getOptionalPackagesFor( final String[] classPath )
  +        throws Exception
  +    {
  +        if( m_packages == null )
  +        {
  +            ClassLoader parent = getParent();
  +            if( parent != null )
  +            {
  +                if( parent instanceof EngineClassLoader )
  +                {
  +                    return ((EngineClassLoader)parent).getOptionalPackagesFor( classPath
);
  +                }
  +            }
  +            return new File[ 0 ];
  +        }
  +
  +        final Manifest[] manifests = getManifests( classPath );
  +        final Extension[] available = Extension.getAvailable( manifests );
  +        final Extension[] required = Extension.getRequired( manifests );
  +
  +        final ArrayList dependencies = new ArrayList();
  +        final ArrayList unsatisfied = new ArrayList();
  +
  +        m_packages.scanDependencies( required, available, dependencies, unsatisfied );
  +
  +        if(( 0 != unsatisfied.size() ) && ( getLogger().isWarnEnabled() ))
  +        {
  +            final int size = unsatisfied.size();
  +            for( int i = 0; i < size; i++ )
  +            {
  +                final Extension extension = (Extension)unsatisfied.get( i );
  +                final Object[] params = new Object[]
  +                {
  +                    extension.getExtensionName(),
  +                    extension.getSpecificationVendor(),
  +                    extension.getSpecificationVersion(),
  +                    extension.getImplementationVendor(),
  +                    extension.getImplementationVendorID(),
  +                    extension.getImplementationVersion(),
  +                    extension.getImplementationURL()
  +                };
  +                final String message = REZ.format( "missing.extension", params );
  +                getLogger().warn( message );
  +            }
  +
  +            final String message =
  +                REZ.getString( "unsatisfied.extensions", new Integer( size ) );
  +            throw new Exception( message );
  +        }
  +
  +        final OptionalPackage[] packages =
  +            (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] );
  +        return OptionalPackage.toFiles( packages );
  +    }
  +
  +    private Manifest[] getManifests( final String[] classPath )
  +        throws Exception
  +    {
  +        final ArrayList manifests = new ArrayList();
  +
  +        for( int i = 0; i < classPath.length; i++ )
  +        {
  +            final String element = classPath[ i ];
  +
  +            if( element.endsWith( ".jar" ) )
  +            {
  +                try
  +                {
  +                    final URL url = new URL( "jar:" + element + "!/" );
  +                    final JarURLConnection connection =
  +                        (JarURLConnection)url.openConnection();
  +                    final Manifest manifest = connection.getManifest();
  +                    manifests.add( manifest );
  +                }
  +                catch( final IOException ioe )
  +                {
  +                    final String message =
  +                        REZ.getString( "bad-classpath-entry", element );
  +                    throw new EngineException(
  +                        message + ": " + element, ioe );
  +                }
  +            }
  +        }
  +
  +        return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
  +    }
  +
  +    /**
  +     * Strips the ".class" ending off of a Type/Block/Service name.
  +     */
  +    private final String cleanName( String name )
  +    {
  +        int end = name.indexOf( ".class" );
  +        return name.substring( 0, ( end >= 0 ) ? end : name.length() );
       }
   }
  
  
  
  1.2       +1 -19     avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/RepositoryManager.java
  
  Index: RepositoryManager.java
  ===================================================================
  RCS file: /home/cvs/avalon-sandbox/assembly/src/java/org/apache/avalon/assembly/engine/RepositoryManager.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RepositoryManager.java	7 Dec 2002 09:34:28 -0000	1.1
  +++ RepositoryManager.java	9 Dec 2002 03:03:47 -0000	1.2
  @@ -55,7 +55,6 @@
   import org.apache.avalon.assembly.profile.ProfileManager;
   import org.apache.avalon.assembly.service.ServiceManager;
   import org.apache.avalon.assembly.type.TypeManager;
  -import org.apache.avalon.assembly.engine.model.ClasspathDescriptor;
   
   /**
    * An appliance is a class that encapsulates the deployment criteria
  @@ -70,23 +69,6 @@
   
   public interface RepositoryManager
   {
  -   /**
  -    * Add a URL to a jar file. A repository implementation is responsible for
  -    * the registration of any declared component services, types and packaged
  -    * profiles.
  -    *
  -    * @param url a url to a jar file
  -    */
  -    void addLibrary( URL url );
  -
  -    /**
  -     * Add a classpath to the repository.
  -     * @param base the base directory from which relative classpath entries
  -     * will be resolved.
  -     * @param classpath the classpath descriptor
  -     */
  -    void addClasspath( ClasspathDescriptor classpath );
  -
      /**
       * Returns the type manager.
       * @return the type manager
  
  
  

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


Mime
View raw message