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