donaldp 2002/07/13 18:29:59 Modified: extension/src/java/org/apache/avalon/excalibur/extension DefaultPackageRepository.java Log: Start fleshing out the package repository implementation by pushing back functionality that was implemented in subclasses. Revision Changes Path 1.17 +239 -30 jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/extension/DefaultPackageRepository.java Index: DefaultPackageRepository.java =================================================================== RCS file: /home/cvs/jakarta-avalon-excalibur/extension/src/java/org/apache/avalon/excalibur/extension/DefaultPackageRepository.java,v retrieving revision 1.16 retrieving revision 1.17 diff -u -r1.16 -r1.17 --- DefaultPackageRepository.java 15 Jun 2002 07:21:09 -0000 1.16 +++ DefaultPackageRepository.java 14 Jul 2002 01:29:59 -0000 1.17 @@ -11,6 +11,7 @@ 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; @@ -31,7 +32,12 @@ private static final boolean DEBUG = false; /** - * Map between files and <code>OptionalPackage</code> objects. + * 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(); @@ -47,6 +53,14 @@ private boolean m_needToScan; /** + * Construct a package repository with no path specified. + */ + public DefaultPackageRepository() + { + this( new File[ 0 ] ); + } + + /** * Construct a package repository with path. * * @param path The set of directories in which to look for Optional Packages @@ -57,10 +71,23 @@ } /** - * Return all the <code>OptionalPackage</code>s that satisfy specified - * <code>Extension</code>. It is expected that this <code>Extension</code> + * 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 <code>Extension</code> is not local then <code>null</code> + * specified {@link Extension} is not local then <code>null</code> * is returned. * * @param extension the extension to search for @@ -71,7 +98,6 @@ { if( m_needToScan ) { - //Check cache consistency and reload if necessary.. scanPath(); } @@ -102,36 +128,81 @@ } /** - * Set the path for the Repository. + * Add path elements to repository search path * - * @param path the list of directories in which to search + * @param pathElements the path elements to add to repository search path */ - protected synchronized void setPath( final File[] path ) + protected synchronized void addPathElements( final String[] pathElements ) { - if( null == path ) - { - throw new NullPointerException( "path property is null" ); - } + final File[] path = toFiles( pathElements ); + addPathElements( path ); + } - for( int i = 0; i < path.length; i++ ) - { - final File directory = path[ i ]; + /** + * 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; + } - if( !directory.exists() || !directory.isDirectory() ) - { - throw new IllegalArgumentException( "path element " + directory + - " must exist and must be a directory" ); - } - } + /** + * 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 ); + } - m_path = path; + /** + * 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() { @@ -143,6 +214,13 @@ } } + /** + * 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(); @@ -153,19 +231,25 @@ if( !name.endsWith( ".jar" ) ) { - debug( "Skipping " + file + " as it does not end with '.jar'" ); + final String message = + "Skipping " + file + " as it does not end with '.jar'"; + debug( message ); continue; } if( !file.isFile() ) { - debug( "Skipping " + file + " as it is not a file." ); + final String message = + "Skipping " + file + " as it is not a file."; + debug( message ); continue; } if( !file.canRead() ) { - debug( "Skipping " + file + " as it is not readable." ); + final String message = + "Skipping " + file + " as it is not readable."; + debug( message ); continue; } @@ -176,7 +260,10 @@ } catch( final IOException ioe ) { - debug( "Skipping " + file + " as it could not be loaded due to " + ioe ); + final String message = + "Skipping " + file + " as it could not be loaded " + + "due to " + ioe; + debug( message ); } } } @@ -201,9 +288,11 @@ { m_needToScan = false; - // SJM: added to avoid out of bounds exception - pending validation + // 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() ); @@ -261,6 +350,126 @@ { System.out.println( message ); } - //getLogger().debug( 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; } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>