donaldp     2002/10/27 20:16:08

  Modified:    loader   build.xml
  Added:       loader/src/java/org/apache/excalibur/loader/builder
                        Resources.properties SimpleLoaderResolver.java
  Log:
  Start to implement a simple resolver that does not handle filesets.
  
  Revision  Changes    Path
  1.5       +1 -0      jakarta-avalon-excalibur/loader/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/loader/build.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- build.xml 1 Oct 2002 13:10:28 -0000       1.4
  +++ build.xml 28 Oct 2002 04:16:07 -0000      1.5
  @@ -180,6 +180,7 @@
   
       <target name="build-test-data" depends="compile-test" unless="skip.tests">
           <mkdir dir="${build.testdata}"/>
  +        <mkdir dir="${build.tests}"/>
           <jar jarfile="${build.tests}/cl1.jar"
               basedir="${build.testdata}">
               <include name="org/apache/excalibur/loader/test/data/cl1/**"/>
  
  
  
  1.1                  
jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  missing.extension=Unable to locate an extension that is required by 
application.\nExtension Name: {0}\nSpecification Vendor: {1}\nSpecification Version: 
{2}\nImplementation Vendor: {3}\nImplementation Vendor-Id: {4}\nImplementation 
Version: {5}\nImplementation URL: {6}
  unsatisfied.extensions=Missing {0} extensions and thus can not build ClassLoader for 
application.
  bad-classpath-entry=There is a bad entry ("{0}") on classpath that made it 
impossible to load a manifest.
  available-extensions=The list of available extensions for application includes; {0}
  required-extensions=The list of required extensions for application includes; {0}
  optional-packages-added=The list of "Optional Packages" added to the application 
includes; {0}
  classpath-entries=The list of classpath entries for the application includes; {0}
  missing-packagemanager=Unable to resolve Extension as no PackageManager has been 
specified.
  
  
  1.1                  
jakarta-avalon-excalibur/loader/src/java/org/apache/excalibur/loader/builder/SimpleLoaderResolver.java
  
  Index: SimpleLoaderResolver.java
  ===================================================================
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE.txt file.
   */
  package org.apache.excalibur.loader.builder;
  
  import java.net.URL;
  import java.net.URLClassLoader;
  import java.net.JarURLConnection;
  import java.io.File;
  import java.io.IOException;
  import java.util.jar.Manifest;
  import java.util.Arrays;
  import java.util.ArrayList;
  import org.apache.avalon.excalibur.extension.Extension;
  import org.apache.avalon.excalibur.packagemanager.PackageManager;
  import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  import org.apache.avalon.excalibur.i18n.Resources;
  import org.apache.avalon.excalibur.i18n.ResourceManager;
  import org.apache.excalibur.loader.runtime.JoinClassLoader;
  
  /**
   *
   * @author <a href="mailto:peter at apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/10/28 04:16:08 $
   */
  public class SimpleLoaderResolver
      implements LoaderResolver
  {
      private final static Resources REZ =
          ResourceManager.getPackageResources( SimpleLoaderResolver.class );
  
      /**
       * The base directory relative to which to aquire files.
       */
      private File m_baseDirectory;
  
      /**
       * The PackageManager to use to resolve Extensions.
       */
      private PackageManager m_manager;
  
      /**
       * Create a resolver that resolves all files according to specied
       * baseDirectory and using specified {@link PackageManager} to aquire
       * {@link Extension} objects.
       *
       * @param baseDirectory the base directory
       * @param manager the {@link PackageManager}
       */
      public SimpleLoaderResolver( final File baseDirectory,
                                   final PackageManager manager )
      {
          setBaseDirectory( baseDirectory );
          setManager( manager );
      }
  
      /**
       * Retrieve a URL for specified extension.
       *
       * @param extension the extension
       * @return the URL
       * @throws Exception if unable to locate URL for extension
       */
      public URL resolveExtension( final Extension extension )
          throws Exception
      {
          if( null == getManager() )
          {
              final String message =
                  REZ.getString( "missing-packagemanager" );
              throw new IllegalStateException( message );
          }
          final OptionalPackage optionalPackage =
              getManager().getOptionalPackage( extension );
          return optionalPackage.getFile().toURL();
      }
  
      /**
       * Resolve a location to a particular URL.
       *
       * @param location the location
       * @return the URL
       * @throws Exception if unable to resolve location
       */
      public URL resolveURL( final String location )
          throws Exception
      {
          return getFileFor( location ).toURL();
      }
  
      /**
       * Resolve all URLs in a particular fileset.
       *
       * @param baseDirectory the basedirectory
       * @param includes the pattern for includes
       * @param excludes the pattern for excludes
       * @return an array of URLs in fileset
       * @throws Exception if unable to aquire URLs.
       */
      public URL[] resolveFileSet( final String baseDirectory,
                                   final String[] includes,
                                   final String[] excludes )
          throws Exception
      {
          throw new UnsupportedOperationException();
      }
  
      /**
       * Create a Join ClassLoader for specified ClassLoaders.
       * Use {@link JoinClassLoader} to implement functionality.
       *
       * @param classLoaders the ClassLoaders to "join"
       * @return the joined ClassLoader
       * @throws Exception if unable to create classloader
       */
      public ClassLoader createJoinClassLoader( final ClassLoader[] classLoaders )
          throws Exception
      {
          return new JoinClassLoader( classLoaders,
                                      ClassLoader.getSystemClassLoader() );
      }
  
      /**
       * Create a ClassLoader with specified parent and
       * containing specified URLs. This implementation just creates
       * it using the default URLClassLoader.
       *
       * @param parent the parent classloader
       * @param urls the URLs that the ClassLoader should contain
       * @return the newly created ClassLoader
       * @throws Exception if unable to create classloader
       */
      public ClassLoader createClassLoader( final ClassLoader parent,
                                            final URL[] urls )
          throws Exception
      {
          final ArrayList classpathSet = new ArrayList();
  
          //Add all supplied URLS to classpath
          for( int i = 0; i < urls.length; i++ )
          {
              final URL url = urls[ i ];
              classpathSet.add( url );
          }
  
          //Add all the optional packages that are declared as
          // dependencies of class path elements
          final File[] files = getOptionalPackagesFor( urls );
          for( int i = 0; i < files.length; i++ )
          {
              final File file = files[ i ];
              classpathSet.add( file.toURL() );
          }
  
          //Define final classpath with all dependencies added
          final URL[] classpath =
              (URL[])classpathSet.toArray( new URL[ classpathSet.size() ] );
  
          return new URLClassLoader( classpath, parent );
      }
  
      /**
       * Utility class to retrieve a file object for specified location.
       *
       * @param location which to get file for.
       * @return the file for specified location
       */
      protected File getFileFor( final String location )
      {
          File base = getBaseDirectory();
          if( null == base )
          {
              base = new File( "." );
          }
          return new File( base, location );
      }
  
      /**
       * Return the base directory against which to resolve relative files.
       *
       * @return the base directory against which to resolve relative files.
       */
      protected File getBaseDirectory()
      {
          return m_baseDirectory;
      }
  
      /**
       * Set the base directory.
       *
       * @param baseDirectory the base directory.
       */
      protected void setBaseDirectory( File baseDirectory )
      {
          m_baseDirectory = baseDirectory;
      }
  
      /**
       * Return the PackageManager for resolver.
       *
       * @return the PackageManager for resolver.
       */
      protected PackageManager getManager()
      {
          return m_manager;
      }
  
      /**
       * Set the PackageManager for resolver.
       *
       * @param manager the PackageManager for resolver.
       */
      protected void setManager( final PackageManager manager )
      {
          m_manager = manager;
      }
  
      /**
       * 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
       */
      protected final File[] getOptionalPackagesFor( final URL[] classPath )
          throws Exception
      {
          final Manifest[] manifests = getManifests( classPath );
          final Extension[] available = Extension.getAvailable( manifests );
          final Extension[] required = Extension.getRequired( manifests );
  
          if( isDebugEnabled() )
          {
              final String message1 =
                  REZ.getString( "available-extensions",
                                 Arrays.asList( available ) );
              debug( message1 );
              final String message2 =
                  REZ.getString( "required-extensions",
                                 Arrays.asList( required ) );
              debug( message2 );
          }
  
          if( 0 == required.length )
          {
              return new File[ 0 ];
          }
  
          final ArrayList dependencies = new ArrayList();
          final ArrayList unsatisfied = new ArrayList();
  
          if( null == getManager() )
          {
              final String message =
                  REZ.getString( "missing-packagemanager" );
              throw new IllegalStateException( message );
          }
  
          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 );
                  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 );
      }
  
      /**
       * write out a warning message. Subclasses may overide this
       * method to redirect logging as appropriate.
       *
       * @param message the warning message
       */
      protected void warn( final String message )
      {
      }
  
      /**
       * Determine if debug messages are turned on.
       * Subclasses should overide this method.
       *
       * @return true if debugging enabled.
       */
      protected boolean isDebugEnabled()
      {
          return false;
      }
  
      /**
       * write out a debug message. Subclasses may overide this
       * method to redirect logging as appropriate.
       *
       * @param message the debug message
       */
      protected void debug( final String message )
      {
      }
  
      /**
       * Retrieve all the Manifests from the specified Classlpath.
       *
       * @param classPath the classpath
       * @return the set of manifests on the classpath
       * @throws Exception if there is an error reading manifests
       *                   from files on classpath
       */
      private Manifest[] getManifests( final URL[] classPath )
          throws Exception
      {
          final ArrayList manifests = new ArrayList();
  
          for( int i = 0; i < classPath.length; i++ )
          {
              final URL element = classPath[ i ];
              if( element.getFile().endsWith( ".jar" ) )
              {
                  try
                  {
                      final JarURLConnection connection =
                          (JarURLConnection)element.openConnection();
                      final Manifest manifest = connection.getManifest();
                      if( null != manifest )
                      {
                          manifests.add( manifest );
                      }
                  }
                  catch( final IOException ioe )
                  {
                      final String message =
                          REZ.getString( "bad-classpath-entry", element );
                      throw new Exception( message );
                  }
              }
          }
  
          return (Manifest[])manifests.toArray( new Manifest[ 0 ] );
      }
  }
  
  
  

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

Reply via email to