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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>