avalon-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dona...@apache.org
Subject cvs commit: jakarta-avalon-excalibur/extension/src/test/org/apache/avalon/excalibur/extension/test PackageRepositoryTestCase.java
Date Sun, 14 Jul 2002 05:45:39 GMT
donaldp     2002/07/13 22:45:39

  Modified:    extension/src/test/org/apache/avalon/excalibur/extension/test
                        PackageRepositoryTestCase.java
  Added:       extension/src/java/org/apache/avalon/excalibur/packagemanager
                        ExtensionManager.java OptionalPackage.java
                        PackageManager.java
                        UnsatisfiedExtensionException.java
               extension/src/java/org/apache/avalon/excalibur/packagemanager/impl
                        DefaultExtensionManager.java
                        DelegatingExtensionManager.java
                        NoopExtensionManager.java
  Removed:     extension/src/java/org/apache/avalon/excalibur/extension
                        DefaultPackageRepository.java
                        DelegatingPackageRepository.java
                        NoopPackageRepository.java OptionalPackage.java
                        PackageManager.java PackageRepository.java
                        UnsatisfiedExtensionException.java
  Log:
  Update extension code to be more cleanly separated
  and fix a few bugs (among them a nasty infinite
  recursive call bug).
  
  Revision  Changes    Path
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/ExtensionManager.java
  
  Index: ExtensionManager.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.avalon.excalibur.packagemanager;
  
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * <p>Interface used to store a collection of "Optional Packages"
   * (formerly known as "Standard Extensions"). It is assumed that each
   * "Optional Package" is represented by a single file on the file system.</p>
   *
   * <p>This repository is responsible for storing the local repository of
   * packages. The method used to locate packages on local filesystem
   * and install packages is not specified.</p>
   *
   * <p>For more information about optional packages, see the document
   * <em>Optional Package Versioning</em> in the documentation bundle for your
   * Java2 Standard Edition package, in file
   * <code>guide/extensions/versioning.html</code></p>.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   */
  public interface ExtensionManager
  {
      String ROLE = ExtensionManager.class.getName();
  
      /**
       * Return all the {@link OptionalPackage}s that satisfy specified
       * {@link Extension}.
       *
       * @param extension Description of the extension that needs to be provided by
       *                  optional packages
       * @return an array of optional packages that satisfy extension and
       *         the extensions dependencies
       * @see OptionalPackage
       * @see Extension
       */
      OptionalPackage[] getOptionalPackages( Extension extension );
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/OptionalPackage.java
  
  Index: OptionalPackage.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.avalon.excalibur.packagemanager;
  
  import java.io.File;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * This contains the required meta-data for an "Optional Package"
   * (formerly known as "Standard Extension") as described in the manifest
   * of a JAR file.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   */
  public final class OptionalPackage
  {
      private final File m_file;
      private final Extension[] m_available;
      private final Extension[] m_required;
  
      /**
       * Convert a list of OptionalPackages into a list of Files.
       *
       * @param packages the list of packages
       * @return the list of files
       */
      public static final File[] toFiles( final OptionalPackage[] packages )
      {
          final File[] results = new File[ packages.length ];
  
          for( int i = 0; i < packages.length; i++ )
          {
              results[ i ] = packages[ i ].getFile();
          }
  
          return results;
      }
  
      /**
       * Constructor for OptionalPackage.
       * No parameter is allowed to be null.
       *
       * @param file absolute location of file
       * @param available the list of Extensions Optional Package provides
       * @param required the list of Extensions Optional Package requires
       */
      public OptionalPackage( final File file,
                              final Extension[] available,
                              final Extension[] required )
      {
          if( null == file )
          {
              throw new NullPointerException( "file property is null" );
          }
  
          if( null == available )
          {
              throw new NullPointerException( "available property is null" );
          }
  
          if( null == required )
          {
              throw new NullPointerException( "required property is null" );
          }
  
          m_file = file;
          m_available = available;
          m_required = required;
      }
  
      /**
       * Return <code>File</code> object in which OptionalPackage
       * is contained.
       *
       * @return the file object for OptionalPackage
       */
      public File getFile()
      {
          return m_file;
      }
  
      /**
       * Return <code>Extension</code>s which OptionalPackage
       * requires to operate.
       *
       * @return the extensions required by OptionalPackage
       */
      public Extension[] getRequiredExtensions()
      {
          return m_required;
      }
  
      /**
       * Return <code>Extension</code>s which OptionalPackage
       * makes available.
       *
       * @return the extensions made available by OptionalPackage
       */
      public Extension[] getAvailableExtensions()
      {
          return m_available;
      }
  
      /**
       * Return <code>true</code> if any of the available <code>Extension</code>s
       * are compatible with specified extension. Otherwise return <code>false</code>.
       *
       * @param extension the extension
       * @return true if compatible, false otherwise
       */
      public boolean isCompatible( final Extension extension )
      {
          for( int i = 0; i < m_available.length; i++ )
          {
              if( m_available[ i ].isCompatibleWith( extension ) )
              {
                  return true;
              }
          }
  
          return false;
      }
  
      /**
       * Return a String representation of this object.
       *
       * @return the string representation of object
       */
      public String toString()
      {
          final StringBuffer sb = new StringBuffer( "OptionalPackage[" );
          sb.append( m_file );
  
          sb.append( ", Available[" );
          for( int i = 0; i < m_available.length; i++ )
          {
              sb.append( m_available );
              sb.append( " " );
          }
  
          sb.append( "], Required[" );
          for( int i = 0; i < m_required.length; i++ )
          {
              sb.append( m_required );
              sb.append( " " );
          }
  
          sb.append( "] ]" );
  
          return sb.toString();
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/PackageManager.java
  
  Index: PackageManager.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.avalon.excalibur.packagemanager;
  
  import java.util.ArrayList;
  import java.util.List;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * Basic Implementation Of PackageManager Interface used to manage
   * "Optional Packages" (formerly known as "Standard Extensions").
   * The "Optional Packages" are stored on file system in a number of
   * directories.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   * @see ExtensionManager
   * @todo Determine an appropriate interface to this service and
   *       an appropriate mechanism via which to do searching and
   *       expansion of a package set. At that point separate out
   *       implementation and interface for mechanism.
   */
  public class PackageManager
  {
      ///Ordered list of repositories to search in
      private ExtensionManager m_repository;
  
      /**
       * Construct a PackageManager for a repositories.
       *
       * @param repository the repository to use in PackageManager
       */
      public PackageManager( final ExtensionManager repository )
      {
          if( null == repository )
          {
              throw new NullPointerException( "repository" );
          }
  
          m_repository = repository;
      }
  
      /**
       * Return the {@link OptionalPackage} that provides specified
       * {@link Extension}. If the specified {@link Extension}
       * can not be found then <code>null</code> is returned. If there is
       * multiple implementations that satisfy {@link Extension},
       * then an {@link OptionalPackage} returned is based on the
       * following heristic;
       *
       * <p>Return the first Optional Package. (This heuristic will
       * be replaced in time).</p>
       *
       * @param extension Description of the extension that needs to be provided by
       *                  optional package
       * @return an array of optional packages that satisfy extension and
       *         the extensions dependencies
       * @see OptionalPackage
       * @see Extension
       */
      public OptionalPackage getOptionalPackage( final Extension extension )
      {
          final OptionalPackage[] packages = m_repository.getOptionalPackages( extension );
  
          if( null == packages || 0 == packages.length )
          {
              return null;
          }
  
          //TODO: Use heurisitic to find which is best package
  
          return packages[ 0 ];
      }
  
      /**
       * Build a list of dependencies based on specified {@link Extension}s.
       * Each specified {@link Extension} is expected to be a required extension
       * of another "Optional Package".
       *
       * <p>If the required {@link Extension} can not be found locally then
       * an UnsatisfiedPackageException is thrown. if an {@link OptionalPackage}
       * is found locally that satisfies specified required {@link Extension}
       * then it is returned in the array of OptionalPackages. scanDependencies() is then
recursively
       * called on all of the candidates required extensions.</p>
       *
       * @param required the array of required Extensions.
       * @param available the array of Extensions already available to caller.
       * @return the list of OptionalPackages that satisfy required Extensions
       * @throws org.apache.avalon.excalibur.packagemanager.UnsatisfiedExtensionException
if extensions could not be satisified
       * @see #scanDependencies
       */
      public OptionalPackage[] scanDependencies( final Extension required,
                                                 final Extension[] available )
          throws UnsatisfiedExtensionException
      {
          return scanDependencies( new Extension[] { required}, available );
      }
  
      /**
       * Build a list of dependencies based on specified {@link Extension}.
       * The specified {@link Extension} is expected to be a required extension
       * of another "Optional Package".
       *
       * <p>If the required {@link Extension} can not be found locally then
       * an UnsatisfiedPackageException is thrown. if an {@link OptionalPackage}
       * is found locally that satisfies specified required {@link Extension}
       * then it is returned in the array of OptionalPackages. scanDependencies() is then
recursively
       * called on all of the candidates required extensions.</p>
       *
       * @param required the array of required Extensions.
       * @param available the array of Extensions already available to caller.
       * @return the list of OptionalPackages that satisfy required Extensions
       * @throws org.apache.avalon.excalibur.packagemanager.UnsatisfiedExtensionException
if extensions could not be satisified
       * @see #scanDependencies
       */
      public OptionalPackage[] scanDependencies( final Extension[] required,
                                                 final Extension[] available )
          throws UnsatisfiedExtensionException
      {
          final ArrayList dependencies = new ArrayList();
          final ArrayList unsatisfied = new ArrayList();
  
          scanDependencies( required, available, dependencies, unsatisfied );
  
          if( 0 != unsatisfied.size() )
          {
              final Extension extension = (Extension)unsatisfied.get( 0 );
              throw new UnsatisfiedExtensionException( extension );
          }
  
          return (OptionalPackage[])dependencies.toArray( new OptionalPackage[ 0 ] );
      }
  
      /**
       * Build a list of dependencies based on specified {@link Extension}s.
       * Each specified {@link Extension} is expected to be a required extension
       * of another "Optional Package".
       *
       * <p>If the required {@link Extension} can not be found locally then
       * it is placed in list of unsatisfied Extensions. If a candidate {@link Extension}
       * is found locally that satisfies specified required {@link Extension}
       * then it is added to list of dependencies. scanDependencies() is then recursively
       * called on all of the candidates required extensions.</p>
       *
       * @param required the array of required Extensions.
       * @param available the array of Extensions already available to caller.
       * @param dependencies the list of dependencies.
       * @param unsatisfied the list of unsatisfied (ie non-local) dependencies.
       * @see #scanDependencies
       */
      public void scanDependencies( final Extension[] required,
                                    final Extension[] available,
                                    final List dependencies,
                                    final List unsatisfied )
      {
          for( int i = 0; i < required.length; i++ )
          {
              scanDependencies( required[ i ], available, dependencies, unsatisfied );
          }
      }
  
      /**
       * Build a list of dependencies based on specified {@link Extension}.
       * The specified {@link Extension} is expected to be a required extension
       * of another "Optional Package".
       *
       * <p>If the required {@link Extension} can not be found locally then
       * it is placed in list of unsatisfied Extensions. If a candidate {@link OptionalPackage}
       * is found locally that satisfies specified required {@link Extension}
       * then it is added to list of dependencies. scanDependencies() is then recursively
       * called on all of the candidates required extensions.</p>
       *
       * @param required the required Extension.
       * @param available the array of Extensions already available to caller.
       * @param dependencies the list of OptionalPackages required to satisfy extension.
       * @param unsatisfied the list of unsatisfied (ie non-local) dependencies.
       * @see #scanDependencies
       */
      public void scanDependencies( final Extension required,
                                    final Extension[] available,
                                    final List dependencies,
                                    final List unsatisfied )
      {
          //Check to see if extension is satisifed by the
          //list of available extensions passed in
          for( int i = 0; i < available.length; i++ )
          {
              final Extension other = available[ i ];
              if( other.isCompatibleWith( required ) )
              {
                  return;
              }
          }
  
          //Check to see if extension is satisifed by one
          //of the extensions already found
          final int size = dependencies.size();
          for( int i = 0; i < size; i++ )
          {
              final OptionalPackage optionalPackage = (OptionalPackage)dependencies.get( i
);
              if( optionalPackage.isCompatible( required ) )
              {
                  return;
              }
          }
  
          final OptionalPackage optionalPackage = getOptionalPackage( required );
          if( null == optionalPackage )
          {
              if( !unsatisfied.contains( required ) )
              {
                  unsatisfied.add( required );
              }
          }
          else
          {
              if( !dependencies.contains( optionalPackage ) )
              {
                  dependencies.add( optionalPackage );
              }
  
              scanDependencies( optionalPackage.getRequiredExtensions(),
                                available,
                                dependencies,
                                unsatisfied );
          }
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/UnsatisfiedExtensionException.java
  
  Index: UnsatisfiedExtensionException.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.avalon.excalibur.packagemanager;
  
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * Exception indicating an extension was not found in Package Repository.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   * @see Extension
   */
  public class UnsatisfiedExtensionException
      extends Exception
  {
      private final Extension m_extension;
  
      /**
       * Construct the <code>UnsatisfiedPackageException</code>
       * for specified {@link Extension}.
       *
       * @param extension the extension that caused exception
       */
      public UnsatisfiedExtensionException( final Extension extension )
      {
          m_extension = extension;
      }
  
      /**
       * Return the unsatisfied {@link Extension} that
       * caused this exception tho be thrown.
       *
       * @return the unsatisfied Extension
       */
      public Extension getUnsatisfiedExtension()
      {
          return m_extension;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/impl/DefaultExtensionManager.java
  
  Index: DefaultExtensionManager.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.avalon.excalibur.packagemanager.impl;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.StringTokenizer;
  import java.util.jar.JarFile;
  import java.util.jar.Manifest;
  import org.apache.avalon.excalibur.packagemanager.ExtensionManager;
  import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * <p>Interface used to contain "Optional Packages" (formerly known as
   * "Standard Extensions"). It is assumed that each "Optional Package" is
   * represented by a single file on the file system. This Repository searches
   * a path to find the Optional Packages.</p>
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   * @see OptionalPackage
   * @see ExtensionManager
   */
  public class DefaultExtensionManager
      implements ExtensionManager
  {
      private static final boolean DEBUG = false;
  
      /**
       * separator used to separate path elements in a string.
       */
      private static final String SEPARATOR = "|";
  
      /**
       * Map between files and {@link OptionalPackage} objects.
       */
      private final HashMap m_packages = new HashMap();
  
      /**
       * The set of directories in which to look for Optional Packages
       */
      private File[] m_path;
  
      /**
       * Flag set when it is necessary to scan paths to
       * build "Optional Package" list
       */
      private boolean m_needToScan;
  
      /**
       * Construct a package repository with no path specified.
       */
      public DefaultExtensionManager()
      {
          this( new File[ 0 ] );
      }
  
      /**
       * Construct a package repository with path.
       *
       * @param path The set of directories in which to look for Optional Packages
       */
      public DefaultExtensionManager( final File[] path )
      {
          setPath( path );
      }
  
      /**
       * Return an array of path elements where each
       * element in array represents a directory
       * in which the ExtensionManager will look
       * for Extensions.
       *
       * @return the list of paths to search in
       */
      public File[] getPaths()
      {
          return m_path;
      }
  
      /**
       * Return all the {@link OptionalPackage}s that satisfy specified
       * {@link Extension}. It is expected that this {@link Extension}
       * object will be one retrieved via getLocalExtension() method. If the
       * specified {@link Extension} is not local then <code>null</code>
       * is returned.
       *
       * @param extension the extension to search for
       * @return an array of optional packages that satisfy the extension
       *         (and the extensions dependencies)
       */
      public synchronized OptionalPackage[] getOptionalPackages( final Extension extension
)
      {
          if( m_needToScan )
          {
              scanPath();
          }
  
          final ArrayList results = new ArrayList();
          final ArrayList candidates = (ArrayList)m_packages.get( extension.getExtensionName()
);
          if( null != candidates )
          {
              final int size = candidates.size();
              for( int i = 0; i < size; i++ )
              {
                  final OptionalPackage optionalPackage = (OptionalPackage)candidates.get(
i );
                  final Extension[] extensions = optionalPackage.getAvailableExtensions();
  
                  for( int j = 0; j < extensions.length; j++ )
                  {
                      if( extensions[ j ].isCompatibleWith( extension ) )
                      {
                          results.add( optionalPackage );
                      }
                  }
              }
          }
  
          //TODO: Sort packages so that most relevant is first
          //ie Sort on spec version first and then on Imp version
  
          return (OptionalPackage[])results.toArray( new OptionalPackage[ 0 ] );
      }
  
      /**
       * Add path elements to repository search path
       *
       * @param pathElements the path elements to add to repository search path
       */
      protected synchronized void addPathElements( final String[] pathElements )
      {
          final File[] path = toFiles( pathElements );
          addPathElements( path );
      }
  
      /**
       * Add path elements to repository search path
       *
       * @param path the path elements to add to repository search path
       */
      protected synchronized void addPathElements( final File[] path )
      {
          validatePath( path );
          final File[] files = resolvePath( path );
          m_path = mergePaths( files );
          m_needToScan = true;
      }
  
      /**
       * Add path elements to repository search path.
       * Note that each path element is separated by a '|' character.
       *
       * @param pathString the path elements to add to repository search path
       */
      protected synchronized void addPathElements( final String pathString )
      {
          final String[] pathElements = split( pathString, SEPARATOR );
          addPathElements( pathElements );
      }
  
      /**
       * Set the path for the Repository.
       * Note thart each path element is separated by a '|' character.
       *
       * @param pathString the list of directories in which to search
       */
      protected synchronized void setPath( final String pathString )
      {
          final String[] pathElements = split( pathString, SEPARATOR );
          setPath( pathElements );
      }
  
      /**
       * Set the path for the Repository.
       *
       * @param pathElements the list of directories in which to search
       */
      protected synchronized void setPath( final String[] pathElements )
      {
          final File[] path = toFiles( pathElements );
          setPath( path );
      }
  
      /**
       * Set the path for the Repository.
       *
       * @param path the list of directories in which to search
       */
      protected synchronized void setPath( final File[] path )
      {
          validatePath( path );
          m_path = resolvePath( path );
          m_needToScan = true;
      }
  
      /**
       * Scan the path for this repository and reload all
       * the "Optional Packages" found in the path.
       * All of the old Extensions/Optional Packages will
       * be removed.
       */
      protected final synchronized void scanPath()
      {
          clearCache();
  
          for( int i = 0; i < m_path.length; i++ )
          {
              scanDirectory( m_path[ i ] );
          }
      }
  
      /**
       * Utility method to scan a directory for
       * all jar fi;les in directory and add them as
       * OptionalPackages.
       *
       * @param directory the directory to scan
       */
      private synchronized void scanDirectory( final File directory )
      {
          final File[] files = directory.listFiles();
          for( int i = 0; i < files.length; i++ )
          {
              final File file = files[ i ];
              final String name = file.getName();
  
              if( !name.endsWith( ".jar" ) )
              {
                  final String message =
                      "Skipping " + file + " as it does not end with '.jar'";
                  debug( message );
                  continue;
              }
  
              if( !file.isFile() )
              {
                  final String message =
                      "Skipping " + file + " as it is not a file.";
                  debug( message );
                  continue;
              }
  
              if( !file.canRead() )
              {
                  final String message =
                      "Skipping " + file + " as it is not readable.";
                  debug( message );
                  continue;
              }
  
              try
              {
                  final OptionalPackage optionalPackage = getOptionalPackage( file );
                  cacheOptionalPackage( optionalPackage );
              }
              catch( final IOException ioe )
              {
                  final String message =
                      "Skipping " + file + " as it could not be loaded " +
                      "due to " + ioe;
                  debug( message );
              }
          }
      }
  
      /**
       * Clear internal cache of optional packages.
       */
      protected final synchronized void clearCache()
      {
          m_packages.clear();
          m_needToScan = true;
      }
  
      /**
       * Add OptionalPackage to internal cache of Optional Packages.
       * Note that this method is only protected so that unit tests can sub-class
       * and add entries to PackageRepository by calling this method.
       *
       * @param optionalPackage the OptionalPackage to be added to repository
       */
      protected final synchronized void cacheOptionalPackage( final OptionalPackage optionalPackage
)
      {
          m_needToScan = false;
  
          // added to avoid out of bounds exception
          if( optionalPackage.getAvailableExtensions().length == 0 )
          {
              return;
          }
  
          final Extension extension = optionalPackage.getAvailableExtensions()[ 0 ];
          ArrayList candidates = (ArrayList)m_packages.get( extension.getExtensionName() );
          if( null == candidates )
          {
              candidates = new ArrayList();
              m_packages.put( extension.getExtensionName(), candidates );
          }
  
          //TODO: Add this in descending order so that don't have to sort in
          //getOptionalPackages ????
          //yes, sort by Spec Version then vendor, Imp Version
          candidates.add( optionalPackage );
      }
  
      /**
       * Construct an OptionalPackage out of the specified jar archive.
       *
       * @param archive the file object for Jar archive
       * @return the OptionalPackage constructed
       * @throws java.io.IOException if an error occurs
       */
      private OptionalPackage getOptionalPackage( final File archive )
          throws IOException
      {
          final File file = archive.getCanonicalFile();
          final JarFile jarFile = new JarFile( file );
          final Manifest manifest = jarFile.getManifest();
  
          try
          {
              if( null == manifest )
              {
                  return null;
              }
              final Extension[] available = Extension.getAvailable( manifest );
              final Extension[] required = Extension.getRequired( manifest );
  
              return new OptionalPackage( file, available, required );
          }
          finally
          {
              jarFile.close();
          }
      }
  
      /**
       * Output a debug message for repository.
       *
       * @param message the debug message
       */
      protected void debug( final String message )
      {
          if( DEBUG )
          {
              System.out.println( message );
          }
      }
  
      /**
       * Get Canonical or failing that the absolute file
       * for every specified file.
       *
       * @param path the files that make up path
       * @return the resolved path
       */
      private File[] resolvePath( final File[] path )
      {
          final File[] resultPath = new File[ path.length ];
          for( int i = 0; i < path.length; i++ )
          {
              resultPath[ i ] = resolveFile( path[ i ] );
          }
          return resultPath;
      }
  
      /**
       * Get Canonical or failing that the absolute file
       * for specified file.
       *
       * @param file the file
       * @return the resolved file
       */
      private File resolveFile( final File file )
      {
          try
          {
              return file.getCanonicalFile();
          }
          catch( IOException e )
          {
              return file.getAbsoluteFile();
          }
      }
  
      /**
       * Validate each element in path to make sure they are valid.
       *
       * @param path the path
       */
      private void validatePath( final File[] path )
      {
          if( null == path )
          {
              throw new NullPointerException( "path" );
          }
  
          for( int i = 0; i < path.length; i++ )
          {
              validatePathElement( path[ i ] );
          }
      }
  
      /**
       * Make sure specified path element is valid.
       * The elements should exist and should be a directory.
       *
       * @param file the path element
       */
      private void validatePathElement( final File file )
      {
          if( !file.exists() || !file.isDirectory() )
          {
              final String message = "path element " + file +
                  " must exist and must be a directory";
              throw new IllegalArgumentException( message );
          }
      }
  
      /**
       * Merge the specified file list with existing path.
       *
       * @param files the files to merge
       * @return the merged path
       */
      private File[] mergePaths( final File[] files )
      {
          final File[] resultPath =
              new File[ m_path.length + files.length ];
          System.arraycopy( m_path, 0, resultPath, 0, m_path.length );
          System.arraycopy( files, m_path.length, resultPath, 0, files.length );
          return resultPath;
      }
  
      /**
       * Convert set of string elements into file objects
       *
       * @param pathElements the string path elements
       * @return the file array representing each element
       */
      private File[] toFiles( final String[] pathElements )
      {
          final File[] path = new File[ pathElements.length ];
          for( int i = 0; i < path.length; i++ )
          {
              path[ i ] = new File( pathElements[ i ] );
          }
          return path;
      }
  
      /**
       * Splits the string on every token into an array of strings.
       *
       * @param string the string
       * @param onToken the token
       * @return the resultant array
       */
      private static String[] split( final String string, final String onToken )
      {
          final StringTokenizer tokenizer = new StringTokenizer( string, onToken );
          final String[] result = new String[ tokenizer.countTokens() ];
  
          for( int i = 0; i < result.length; i++ )
          {
              result[ i ] = tokenizer.nextToken();
          }
  
          return result;
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/impl/DelegatingExtensionManager.java
  
  Index: DelegatingExtensionManager.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.avalon.excalibur.packagemanager.impl;
  
  import java.util.ArrayList;
  import org.apache.avalon.excalibur.packagemanager.ExtensionManager;
  import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * A {@link org.apache.avalon.excalibur.packagemanager.ExtensionManager} that can delegate
to multiple
   * different package repositories.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   */
  public class DelegatingExtensionManager
      implements ExtensionManager
  {
      /**
       * The list containing the package repositories.
       */
      private final ArrayList m_repositories = new ArrayList();
  
      /**
       * Default constructor that does not add any repositories.
       */
      public DelegatingExtensionManager()
      {
      }
  
      /**
       * Default constructor that delegates to specified repositories.
       */
      public DelegatingExtensionManager( final ExtensionManager[] repositories )
      {
          for( int i = 0; i < repositories.length; i++ )
          {
              addPackageRepository( repositories[ i ] );
          }
      }
  
      /**
       * Add a repository to list of repositories delegated to
       * to find Optional Packages.
       *
       * @param repository the repository to add
       */
      protected synchronized void addPackageRepository( final ExtensionManager repository
)
      {
          if( !m_repositories.contains( repository ) )
          {
              m_repositories.add( repository );
          }
      }
  
      /**
       * Remove a repository from list of repositories delegated to
       * to find Optional Packages.
       *
       * @param repository the repository to remove
       */
      protected synchronized void removePackageRepository( final ExtensionManager repository
)
      {
          m_repositories.remove( repository );
      }
  
      /**
       * Scan through list of respositories and return all the matching {@link OptionalPackage}
       * objects that match in any repository.
       *
       * @param extension the extension to search for
       * @return the matching {@link OptionalPackage} objects.
       */
      public synchronized OptionalPackage[] getOptionalPackages( final Extension extension
)
      {
          final ArrayList resultPackages = new ArrayList();
  
          final int size = m_repositories.size();
          for( int i = 0; i < size; i++ )
          {
              final ExtensionManager repository =
                  (ExtensionManager)m_repositories.get( i );
              final OptionalPackage[] packages =
                  repository.getOptionalPackages( extension );
              if( null == packages || 0 == packages.length )
              {
                  continue;
              }
  
              for( int j = 0; j < packages.length; j++ )
              {
                  resultPackages.add( packages[ j ] );
              }
          }
  
          final OptionalPackage[] resultData =
              new OptionalPackage[ resultPackages.size() ];
          return (OptionalPackage[])resultPackages.toArray( resultData );
      }
  }
  
  
  
  1.1                  jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/packagemanager/impl/NoopExtensionManager.java
  
  Index: NoopExtensionManager.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.avalon.excalibur.packagemanager.impl;
  
  import org.apache.avalon.excalibur.packagemanager.ExtensionManager;
  import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  import org.apache.avalon.excalibur.extension.Extension;
  
  /**
   * A Noop PackageRepository that can't provide any extensions.
   * This is for use in certain environments (ala Servlets) that
   * require apps to be be self-contained.
   *
   * @author <a href="mailto:peter@apache.org">Peter Donald</a>
   * @version $Revision: 1.1 $ $Date: 2002/07/14 05:45:39 $
   */
  public class NoopExtensionManager
      implements ExtensionManager
  {
      /**
       * Return an empty array of <code>OptionalPackage</code>s.
       *
       * @param extension the extension looking for
       * @see org.apache.avalon.excalibur.packagemanager.ExtensionManager#getOptionalPackages
       */
      public OptionalPackage[] getOptionalPackages( final Extension extension )
      {
          return new OptionalPackage[ 0 ];
      }
  }
  
  
  
  1.13      +12 -12    jakarta-avalon-excalibur/extension/src/test/org/apache/avalon/excalibur/extension/test/PackageRepositoryTestCase.java
  
  Index: PackageRepositoryTestCase.java
  ===================================================================
  RCS file: /home/cvs/jakarta-avalon-excalibur/extension/src/test/org/apache/avalon/excalibur/extension/test/PackageRepositoryTestCase.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- PackageRepositoryTestCase.java	2 Apr 2002 10:43:10 -0000	1.12
  +++ PackageRepositoryTestCase.java	14 Jul 2002 05:45:39 -0000	1.13
  @@ -13,11 +13,11 @@
   import java.util.ArrayList;
   import java.util.jar.Manifest;
   import junit.framework.TestCase;
  -import org.apache.avalon.excalibur.extension.DefaultPackageRepository;
  +import org.apache.avalon.excalibur.packagemanager.impl.DefaultExtensionManager;
   import org.apache.avalon.excalibur.extension.Extension;
  -import org.apache.avalon.excalibur.extension.OptionalPackage;
  -import org.apache.avalon.excalibur.extension.PackageManager;
  -import org.apache.avalon.excalibur.extension.PackageRepository;
  +import org.apache.avalon.excalibur.packagemanager.OptionalPackage;
  +import org.apache.avalon.excalibur.packagemanager.PackageManager;
  +import org.apache.avalon.excalibur.packagemanager.ExtensionManager;
   
   /**
    * TestCases for PackageRepository.
  @@ -49,7 +49,7 @@
       public void testGoodPath()
           throws Exception
       {
  -        new DefaultPackageRepository( m_path );
  +        new DefaultExtensionManager( m_path );
       }
   
       public void testBadPath()
  @@ -59,7 +59,7 @@
           {
               final File pathElement3 = new File( m_baseDirectory, "path3" );
               final File[] path = new File[]{m_pathElement1, m_pathElement2, pathElement3};
  -            new DefaultPackageRepository( path );
  +            new DefaultExtensionManager( path );
           }
           catch( final IllegalArgumentException iae )
           {
  @@ -72,18 +72,18 @@
       public void testBasicScanDependencies()
           throws Exception
       {
  -        final PackageRepository repository = newPackagerepository();
  +        final ExtensionManager repository = newPackagerepository();
           doRepositoryTest( repository );
       }
   
       public void testFSScanDependencies()
           throws Exception
       {
  -        final PackageRepository repository = new DefaultPackageRepository( m_path );
  +        final ExtensionManager repository = new DefaultExtensionManager( m_path );
           doRepositoryTest( repository );
       }
   
  -    private void doRepositoryTest( final PackageRepository repository )
  +    private void doRepositoryTest( final ExtensionManager repository )
           throws Exception
       {
           final PackageManager manager = new PackageManager( repository );
  @@ -124,7 +124,7 @@
           return new Manifest( inputStream );
       }
   
  -    private PackageRepository newPackagerepository()
  +    private ExtensionManager newPackagerepository()
           throws Exception
       {
           final TestPackageRepository repository = new TestPackageRepository();
  @@ -141,7 +141,7 @@
   }
   
   class TestPackageRepository
  -    extends DefaultPackageRepository
  +    extends DefaultExtensionManager
   {
       TestPackageRepository()
           throws Exception
  
  
  

--
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