diff --git a/proposal/myrmidon/build.xml b/proposal/myrmidon/build.xml index c63e4b46f..a05d8af2a 100644 --- a/proposal/myrmidon/build.xml +++ b/proposal/myrmidon/build.xml @@ -557,6 +557,9 @@ Legal: + + +

The VFS needs plenty of work:

*/ - public void normalisePath( final StringBuffer path ) throws FileSystemException + public void normalisePath( final StringBuffer path ) + throws FileSystemException { if( path.length() == 0 ) { @@ -515,14 +544,20 @@ public class UriParser path.charAt( startElem + 1 ) == '.' ) { // A '..' element - remove the previous element - if( startElem > startFirstElem ) + if( startElem == startFirstElem ) { - int pos = startElem - 2; - for( ; pos >= 0 && path.charAt( pos ) != m_separatorChar; pos -- ) - { - } - startElem = pos + 1; + // Previous element is missing + final String message = REZ.getString( "invalid-relative-path.error" ); + throw new FileSystemException( message ); } + + // Find start of previous element + int pos = startElem - 2; + for( ; pos >= 0 && path.charAt( pos ) != m_separatorChar; pos-- ) + { + } + startElem = pos + 1; + path.delete( startElem, endElem + 1 ); maxlen = path.length(); continue; @@ -595,7 +630,8 @@ public class UriParser * @return * The scheme name. Returns null if there is no scheme. */ - protected static String extractScheme( final String uri, final StringBuffer buffer ) + public static String extractScheme( final String uri, + final StringBuffer buffer ) { if( buffer != null ) { @@ -642,4 +678,103 @@ public class UriParser // No scheme in URI return null; } + + /** + * Removes %nn encodings from a string. + */ + public static String decode( final String encodedStr ) + throws FileSystemException + { + final StringBuffer buffer = new StringBuffer( encodedStr ); + decode( buffer, 0, buffer.length() ); + return buffer.toString(); + } + + /** + * Removes %nn encodings from a string. + */ + public static void decode( final StringBuffer buffer, + final int offset, + final int length ) + throws FileSystemException + { + int index = offset; + int count = length; + for( ; count > 0; count--, index++ ) + { + final char ch = buffer.charAt( index ); + if( ch != '%' ) + { + continue; + } + if( count < 3 ) + { + final String message = REZ.getString( "invalid-escape-sequence.error", buffer.substring( index, index + count ) ); + throw new FileSystemException( message ); + } + + // Decode + int dig1 = Character.digit( buffer.charAt( index + 1 ), 16 ); + int dig2 = Character.digit( buffer.charAt( index + 2 ), 16 ); + if( dig1 == -1 || dig2 == -1 ) + { + final String message = REZ.getString( "invalid-escape-sequence.error", buffer.substring( index, index + 3 ) ); + throw new FileSystemException( message ); + } + char value = (char)( dig1 << 4 | dig2 ); + + // Replace + buffer.setCharAt( index, value ); + buffer.delete( index + 1, index + 3 ); + count -= 2; + } + } + + /** + * Encodes and appends a string to a StringBuffer. + */ + public static void appendEncoded( final StringBuffer buffer, + final String unencodedValue, + final char[] reserved ) + { + final int offset = buffer.length(); + buffer.append( unencodedValue ); + encode( buffer, offset, unencodedValue.length(), reserved ); + } + + /** + * Encodes a set of reserved characters in a StringBuffer, using the URI + * %nn encoding. Always encodes % characters. + */ + public static void encode( final StringBuffer buffer, + final int offset, + final int length, + final char[] reserved ) + { + int index = offset; + int count = length; + for( ; count > 0; index++, count-- ) + { + final char ch = buffer.charAt( index ); + boolean match = ( ch == '%' ); + for( int i = 0; !match && i < reserved.length; i++ ) + { + if( ch == reserved[ i ] ) + { + match = true; + } + } + if( match ) + { + // Encode + char[] digits = { + Character.forDigit( ( ( ch >> 4 ) & 0xF ), 16 ), + Character.forDigit( ( ch & 0xF ), 16 ) + }; + buffer.setCharAt( index, '%' ); + buffer.insert( index + 1, digits ); + index += 2; + } + } + } } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java index eb9b7e7b1..5b2f4f12e 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java @@ -8,7 +8,6 @@ package org.apache.aut.vfs.provider.ftp; import org.apache.aut.vfs.FileSystemException; -import org.apache.aut.vfs.provider.ParsedUri; import org.apache.aut.vfs.provider.UriParser; /** @@ -21,15 +20,27 @@ public class FtpFileNameParser extends UriParser /** * Parses an absolute URI, splitting it into its components. */ - public ParsedUri parseUri( String uriStr ) throws FileSystemException + public ParsedFtpUri parseFtpUri( final String uriStr ) + throws FileSystemException { - ParsedFtpUri uri = new ParsedFtpUri(); + final ParsedFtpUri uri = new ParsedFtpUri(); // FTP URI are generic URI (as per RFC 2396) parseGenericUri( uriStr, uri ); + // Adjust the hostname to lower-case + final String hostname = uri.getHostName().toLowerCase(); + uri.setHostName( hostname ); + + // Drop the port if it is 21 + final String port = uri.getPort(); + if( port != null && port.equals( "21" ) ) + { + uri.setPort( null ); + } + // Split up the userinfo into a username and password - String userInfo = uri.getUserInfo(); + final String userInfo = uri.getUserInfo(); if( userInfo != null ) { int idx = userInfo.indexOf( ':' ); @@ -46,6 +57,11 @@ public class FtpFileNameParser extends UriParser } } + // Now build the root URI + final StringBuffer rootUri = new StringBuffer(); + appendRootUri( uri, rootUri ); + uri.setRootUri( rootUri.toString() ); + return uri; } } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java index 18670c235..4684abec2 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java @@ -8,39 +8,44 @@ package org.apache.aut.vfs.provider.ftp; import org.apache.aut.vfs.FileName; +import org.apache.aut.vfs.FileObject; import org.apache.aut.vfs.FileSystemException; import org.apache.aut.vfs.provider.AbstractFileSystemProvider; import org.apache.aut.vfs.provider.DefaultFileName; import org.apache.aut.vfs.provider.FileSystem; import org.apache.aut.vfs.provider.ParsedUri; -import org.apache.aut.vfs.provider.UriParser; /** * A provider for FTP file systems. * * @author Adam Murdoch + * + * @ant:type type="file-system" name="ftp" */ public class FtpFileSystemProvider extends AbstractFileSystemProvider { - private UriParser m_parser = new FtpFileNameParser(); + private final FtpFileNameParser m_parser = new FtpFileNameParser(); /** * Parses a URI into its components. */ - protected ParsedUri parseURI( String uri ) throws FileSystemException + protected ParsedUri parseUri( final FileObject baseFile, + final String uri ) + throws FileSystemException { - return m_parser.parseUri( uri ); + return m_parser.parseFtpUri( uri ); } /** * Creates the filesystem. */ - protected FileSystem createFileSystem( ParsedUri uri ) throws FileSystemException + protected FileSystem createFileSystem( final ParsedUri uri ) + throws FileSystemException { - ParsedFtpUri ftpUri = (ParsedFtpUri)uri; + final ParsedFtpUri ftpUri = (ParsedFtpUri)uri; // Build the root name - FileName rootName = new DefaultFileName( m_parser, ftpUri.getRootURI(), "/" ); + final FileName rootName = new DefaultFileName( m_parser, ftpUri.getRootUri(), "/" ); // Determine the username and password to use String username = ftpUri.getUserName(); diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java index d55db0f27..5ac42a39d 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java @@ -50,21 +50,22 @@ abstract class LocalFileNameParser * * @param uriStr The URI. */ - public ParsedUri parseUri( final String uriStr ) + public ParsedUri parseFileUri( final String uriStr ) throws FileSystemException { - StringBuffer name = new StringBuffer(); - ParsedFileUri uri = new ParsedFileUri(); + final StringBuffer name = new StringBuffer(); + final ParsedFileUri uri = new ParsedFileUri(); // Extract the scheme - String scheme = extractScheme( uriStr, name ); + final String scheme = extractScheme( uriStr, name ); uri.setScheme( scheme ); - // Adjust the separators + // Remove encoding, and adjust the separators + decode( name, 0, name.length() ); fixSeparators( name ); // Extract the root prefix - String rootFile = extractRootPrefix( uriStr, name ); + final String rootFile = extractRootPrefix( uriStr, name ); uri.setRootFile( rootFile ); // Normalise the path @@ -72,11 +73,11 @@ abstract class LocalFileNameParser uri.setPath( name.toString() ); // Build the root URI - StringBuffer rootUri = new StringBuffer(); + final StringBuffer rootUri = new StringBuffer(); rootUri.append( scheme ); rootUri.append( "://" ); rootUri.append( rootFile ); - uri.setRootURI( rootUri.toString() ); + uri.setRootUri( rootUri.toString() ); return uri; } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java index 694f3a0a8..be00f376d 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java @@ -51,20 +51,22 @@ public class LocalFileSystemProvider extends AbstractFileSystemProvider /** * Finds a local file, from its local name. */ - public FileObject findLocalFile( final String name ) throws FileSystemException + public FileObject findLocalFile( final String name ) + throws FileSystemException { // TODO - tidy this up, no need to turn the name into an absolute URI, // and then straight back again - return findFile( "file:" + name ); + return findFile( null, "file:" + name ); } /** * Finds a local file. */ - public FileObject findFileByLocalName( final File file ) throws FileSystemException + public FileObject findLocalFile( final File file ) + throws FileSystemException { // TODO - tidy this up, should build file object straight from the file - return findFile( "file:" + file.getAbsolutePath() ); + return findFile( null, "file:" + file.getAbsolutePath() ); } /** @@ -75,22 +77,25 @@ public class LocalFileSystemProvider extends AbstractFileSystemProvider *

The provider can annotate this object with any additional * information it requires to create a file system from the URI. */ - protected ParsedUri parseURI( final String uri ) throws FileSystemException + protected ParsedUri parseUri( final FileObject baseFile, + final String uri ) + throws FileSystemException { - return m_parser.parseUri( uri ); + return m_parser.parseFileUri( uri ); } /** * Creates the filesystem. */ - protected FileSystem createFileSystem( final ParsedUri uri ) throws FileSystemException + protected FileSystem createFileSystem( final ParsedUri uri ) + throws FileSystemException { // Build the name of the root file. final ParsedFileUri fileUri = (ParsedFileUri)uri; final String rootFile = fileUri.getRootFile(); // Create the file system - final DefaultFileName rootName = new DefaultFileName( m_parser, fileUri.getRootURI(), "/" ); + final DefaultFileName rootName = new DefaultFileName( m_parser, fileUri.getRootUri(), "/" ); return new LocalFileSystem( rootName, rootFile ); } } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java index 2f2a5e788..2f0248854 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java @@ -27,19 +27,27 @@ public class SmbFileNameParser /** * Parses an absolute URI, splitting it into its components. */ - public ParsedUri parseUri( String uriStr ) throws FileSystemException + public ParsedUri parseSmbUri( final String uriStr ) + throws FileSystemException { - ParsedSmbUri uri = new ParsedSmbUri(); - StringBuffer name = new StringBuffer(); + final ParsedSmbUri uri = new ParsedSmbUri(); + final StringBuffer name = new StringBuffer(); // Extract the scheme and authority parts extractToPath( uriStr, name, uri ); - // Normalise paths + // Convert the hostname to lowercase + final String hostname = uri.getHostName().toLowerCase(); + uri.setHostName( hostname ); + + // TODO - drop the default port + + // Decode and adjust separators + decode( name, 0, name.length() ); fixSeparators( name ); // Extract the share - String share = extractFirstElement( name ); + final String share = extractFirstElement( name ); if( share == null ) { final String message = REZ.getString( "missing-share-name.error", uriStr ); @@ -47,23 +55,18 @@ public class SmbFileNameParser } uri.setShare( share ); + // Normalise the path + normalisePath( name ); + // Set the path uri.setPath( name.toString() ); // Set the root URI StringBuffer rootUri = new StringBuffer(); - rootUri.append( uri.getScheme() ); - rootUri.append( "://" ); - String userInfo = uri.getUserInfo(); - if( userInfo != null ) - { - rootUri.append( userInfo ); - rootUri.append( '@' ); - } - rootUri.append( uri.getHostName() ); + appendRootUri( uri, rootUri ); rootUri.append( '/' ); rootUri.append( share ); - uri.setRootURI( rootUri.toString() ); + uri.setRootUri( rootUri.toString() ); return uri; } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java index f9e7eb276..ba62eec70 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java @@ -8,6 +8,7 @@ package org.apache.aut.vfs.provider.smb; import org.apache.aut.vfs.FileName; +import org.apache.aut.vfs.FileObject; import org.apache.aut.vfs.FileSystemException; import org.apache.aut.vfs.provider.AbstractFileSystemProvider; import org.apache.aut.vfs.provider.DefaultFileName; @@ -19,27 +20,31 @@ import org.apache.aut.vfs.provider.ParsedUri; * A provider for SMB (Samba, Windows share) file systems. * * @author Adam Murdoch + * + * @ant:type type="file-system" name="smb" */ public class SmbFileSystemProvider extends AbstractFileSystemProvider implements FileSystemProvider { - SmbFileNameParser m_parser = new SmbFileNameParser(); + private final SmbFileNameParser m_parser = new SmbFileNameParser(); /** * Parses a URI into its components. */ - protected ParsedUri parseURI( String uri ) throws FileSystemException + protected ParsedUri parseUri( final FileObject baseFile, + final String uri ) + throws FileSystemException { - return m_parser.parseUri( uri ); + return m_parser.parseSmbUri( uri ); } /** * Creates the filesystem. */ - protected FileSystem createFileSystem( ParsedUri uri ) throws FileSystemException + protected FileSystem createFileSystem( final ParsedUri uri ) + throws FileSystemException { - ParsedSmbUri smbUri = (ParsedSmbUri)uri; - - FileName rootName = new DefaultFileName( m_parser, smbUri.getRootURI(), "/" ); + final ParsedSmbUri smbUri = (ParsedSmbUri)uri; + final FileName rootName = new DefaultFileName( m_parser, smbUri.getRootUri(), "/" ); return new SmbFileSystem( rootName ); } } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java index 0dda462ae..9bc36d0c8 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java @@ -7,6 +7,7 @@ */ package org.apache.aut.vfs.provider.zip; +import org.apache.aut.vfs.FileObject; import org.apache.aut.vfs.provider.ParsedUri; /** @@ -16,14 +17,25 @@ import org.apache.aut.vfs.provider.ParsedUri; */ public class ParsedZipUri extends ParsedUri { - private String m_zipFile; + private String m_zipFileName; + private FileObject m_zipFile; - public String getZipFile() + public String getZipFileName() + { + return m_zipFileName; + } + + public void setZipFileName( final String zipFileName ) + { + m_zipFileName = zipFileName; + } + + public FileObject getZipFile() { return m_zipFile; } - public void setZipFile( String zipFile ) + public void setZipFile( final FileObject zipFile ) { m_zipFile = zipFile; } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java index 7f804efd7..caeab439c 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java @@ -8,7 +8,6 @@ package org.apache.aut.vfs.provider.zip; import org.apache.aut.vfs.FileSystemException; -import org.apache.aut.vfs.provider.ParsedUri; import org.apache.aut.vfs.provider.UriParser; /** @@ -16,66 +15,77 @@ import org.apache.aut.vfs.provider.UriParser; * * @author Adam Murdoch */ -public class ZipFileNameParser extends UriParser +public class ZipFileNameParser + extends UriParser { + private static final char[] ZIP_URL_RESERVED_CHARS = { '!' }; + /** * Parses an absolute URI, splitting it into its components. * - * @param name + * @param uriStr * The URI. */ - public ParsedUri parseUri( String uriStr ) throws FileSystemException + public ParsedZipUri parseZipUri( final String uriStr ) + throws FileSystemException { - StringBuffer name = new StringBuffer(); - ParsedZipUri uri = new ParsedZipUri(); + final StringBuffer name = new StringBuffer(); + final ParsedZipUri uri = new ParsedZipUri(); // Extract the scheme - String scheme = extractScheme( uriStr, name ); + final String scheme = extractScheme( uriStr, name ); uri.setScheme( scheme ); // Extract the Zip file name - String zipName = extractZipName( name ); - uri.setZipFile( zipName ); - - // Adjust the separators - fixSeparators( name ); + final String zipName = extractZipName( name ); + uri.setZipFileName( zipName ); - // Normalise the file name + // Decode and normalise the file name + decode( name, 0, name.length() ); normalisePath( name ); uri.setPath( name.toString() ); - // Build root URI - StringBuffer rootUri = new StringBuffer(); - rootUri.append( scheme ); + return uri; + } + + /** + * Assembles a root URI from the components of a parsed URI. + */ + public String buildRootUri( final ParsedZipUri uri ) + { + final StringBuffer rootUri = new StringBuffer(); + rootUri.append( uri.getScheme() ); rootUri.append( ":" ); - rootUri.append( zipName ); + appendEncoded( rootUri, uri.getZipFile().getName().getURI(), ZIP_URL_RESERVED_CHARS ); rootUri.append( "!" ); - uri.setRootURI( rootUri.toString() ); - - return uri; + return rootUri.toString(); } /** * Pops the root prefix off a URI, which has had the scheme removed. */ - protected String extractZipName( StringBuffer uri ) throws FileSystemException + private String extractZipName( final StringBuffer uri ) + throws FileSystemException { // Looking for ! - // TODO - how does '!' in the file name get escaped? int maxlen = uri.length(); - for( int pos = 0; pos < maxlen; pos++ ) + int pos = 0; + for( ; pos < maxlen && uri.charAt( pos ) != '!'; pos++ ) + { + } + + // Extract the name + String prefix = uri.substring( 0, pos ); + if( pos < maxlen ) + { + uri.delete( 0, pos + 1 ); + } + else { - if( uri.charAt( pos ) == '!' ) - { - String prefix = uri.substring( 0, pos ); - uri.delete( 0, pos + 1 ); - return prefix; - } + uri.setLength( 0 ); } - // Assume the URI is the Jar file name - String prefix = uri.toString(); - uri.setLength( 0 ); - return prefix; + // Decode the name + return decode( prefix ); } } diff --git a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java index 21f540646..f1ab31d82 100644 --- a/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java +++ b/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java @@ -8,6 +8,8 @@ package org.apache.aut.vfs.provider.zip; import java.io.File; +import java.io.IOException; +import org.apache.aut.vfs.FileObject; import org.apache.aut.vfs.FileSystemException; import org.apache.aut.vfs.provider.AbstractFileSystemProvider; import org.apache.aut.vfs.provider.DefaultFileName; @@ -20,31 +22,83 @@ import org.apache.aut.vfs.provider.ParsedUri; * systems, for local Zip files only. * * @author Adam Murdoch + * + * @ant:type type="file-system" name="zip" */ -public class ZipFileSystemProvider extends AbstractFileSystemProvider +public class ZipFileSystemProvider + extends AbstractFileSystemProvider implements FileSystemProvider { - private ZipFileNameParser m_parser = new ZipFileNameParser(); + private final ZipFileNameParser m_parser = new ZipFileNameParser(); /** * Parses a URI into its components. */ - protected ParsedUri parseURI( String uri ) throws FileSystemException + protected ParsedUri parseUri( final FileObject baseFile, + final String uriStr ) + throws FileSystemException { - return m_parser.parseUri( uri ); + // Parse the URI + final ParsedZipUri uri = m_parser.parseZipUri( uriStr ); + + // Make the URI canonical + + // Resolve the Zip file name + final String fileName = uri.getZipFileName(); + final FileObject file = getContext().resolveFile( baseFile, fileName ); + uri.setZipFile( file ); + + // Rebuild the root URI + final String rootUri = m_parser.buildRootUri( uri ); + uri.setRootUri( rootUri ); + + return uri; + } + + /** + * Builds the URI for the root of a layered file system. + */ + protected ParsedUri buildUri( final String scheme, + final FileObject file ) + throws FileSystemException + { + ParsedZipUri uri = new ParsedZipUri(); + uri.setScheme( scheme ); + uri.setZipFile( file ); + final String rootUri = m_parser.buildRootUri( uri ); + uri.setRootUri( rootUri ); + uri.setPath( "/" ); + return uri; } /** * Creates the filesystem. */ - protected FileSystem createFileSystem( ParsedUri uri ) throws FileSystemException + protected FileSystem createFileSystem( final ParsedUri uri ) + throws FileSystemException { - // Locate the Zip file - ParsedZipUri zipUri = (ParsedZipUri)uri; - String fileName = zipUri.getZipFile(); - // TODO - use the context to resolve zip file to a FileObject - File file = new File( fileName ).getAbsoluteFile(); - DefaultFileName name = new DefaultFileName( m_parser, zipUri.getRootURI(), "/" ); - return new ZipFileSystem( name, file ); + final ParsedZipUri zipUri = (ParsedZipUri)uri; + final FileObject file = zipUri.getZipFile(); + + // TODO - temporary hack; need to use a converter + File destFile = null; + try + { + final File cacheDir = new File( "ant_vfs_cache" ); + cacheDir.mkdirs(); + destFile = File.createTempFile( "cache_", "_" + file.getName().getBaseName(), cacheDir ); + destFile.deleteOnExit(); + } + catch( IOException e ) + { + throw new FileSystemException( "Could not replicate file", e ); + } + FileObject destFileObj = getContext().resolveFile( null, destFile.getAbsolutePath() ); + destFileObj.copy( file ); + + // Create the file system + DefaultFileName name = new DefaultFileName( m_parser, zipUri.getRootUri(), "/" ); + return new ZipFileSystem( name, destFile ); } + } diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties index 9d1e2fbf5..22651c223 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties @@ -1,2 +1,3 @@ missing-home-dir.error=Cannot locate antRun scripts: Property 'myrmidon.home' not specified -create-vfs-manager.error=Could not create the VFS manager. \ No newline at end of file +create-vfs-manager.error=Could not create the VFS manager. +create-provider.error=Could not create file system provider "{0}". \ No newline at end of file diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManager.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManager.java new file mode 100644 index 000000000..faa50d46c --- /dev/null +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManager.java @@ -0,0 +1,108 @@ +/* + * 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.myrmidon.framework.factories; + +import org.apache.aut.vfs.impl.DefaultFileSystemManager; +import org.apache.aut.vfs.provider.FileSystemProvider; +import org.apache.aut.vfs.FileSystemException; +import org.apache.avalon.framework.activity.Disposable; +import org.apache.avalon.framework.activity.Initializable; +import org.apache.avalon.framework.service.Serviceable; +import org.apache.avalon.framework.service.ServiceManager; +import org.apache.avalon.framework.service.ServiceException; +import org.apache.avalon.excalibur.i18n.ResourceManager; +import org.apache.avalon.excalibur.i18n.Resources; +import org.apache.myrmidon.interfaces.type.TypeManager; +import org.apache.myrmidon.interfaces.type.TypeFactory; +import org.apache.myrmidon.interfaces.type.TypeException; + +/** + * The myrmidon FileSystemManager implementation. + * + * @author Adam Murdoch + * @version $Revision$ $Date$ + */ +public class VfsManager + extends DefaultFileSystemManager + implements Serviceable, Initializable, Disposable +{ + private final static Resources REZ + = ResourceManager.getPackageResources( VfsManager.class ); + + private TypeFactory m_typeFactory; + + /** + * Locate the services used by this service. + */ + public void service( final ServiceManager serviceManager ) throws ServiceException + { + final TypeManager typeManager = (TypeManager)serviceManager.lookup( TypeManager.ROLE ); + try + { + m_typeFactory = typeManager.getFactory( FileSystemProvider.class ); + } + catch( TypeException e ) + { + throw new ServiceException( e.getMessage(), e ); + } + } + + /** + * Initialises this service. + */ + public void initialize() throws Exception + { + // TODO - make this list configurable + + // Required providers + addProvider( new String[] { "zip", "jar" }, "zip", false ); + + // Optional providers + addProvider( new String[] { "smb" }, "smb", true ); + addProvider( new String[] { "ftp" }, "ftp", true ); + } + + /** + * Disposes this service. + */ + public void dispose() + { + // Clean-up + close(); + } + + /** + * Registers a file system provider. + */ + public void addProvider( final String[] urlSchemes, + final String providerName, + final boolean ignoreIfNotPresent ) + throws FileSystemException + { + // Create an instance + if( ignoreIfNotPresent && ! m_typeFactory.canCreate( providerName ) ) + { + return; + } + + final FileSystemProvider provider; + try + { + provider = (FileSystemProvider)m_typeFactory.create( providerName ); + } + catch( Exception e ) + { + final String message = REZ.getString( "create-provider.error", providerName ); + throw new FileSystemException( message, e ); + } + + // Register the provider + addProvider( urlSchemes, provider ); + } + +} diff --git a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java index 4ff530dcb..bf4c941c5 100644 --- a/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java +++ b/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java @@ -8,7 +8,6 @@ package org.apache.myrmidon.framework.factories; import org.apache.aut.vfs.FileSystemManager; -import org.apache.aut.vfs.impl.DefaultFileSystemManager; import org.apache.avalon.excalibur.i18n.ResourceManager; import org.apache.avalon.excalibur.i18n.Resources; import org.apache.myrmidon.interfaces.service.AntServiceException; @@ -34,7 +33,7 @@ public class VfsManagerFactory { try { - return new DefaultFileSystemManager(); + return new VfsManager(); } catch( Exception e ) { diff --git a/proposal/myrmidon/src/manifest/core-services.xml b/proposal/myrmidon/src/manifest/core-services.xml index b2cfc8883..dd26e6334 100644 --- a/proposal/myrmidon/src/manifest/core-services.xml +++ b/proposal/myrmidon/src/manifest/core-services.xml @@ -1,9 +1,4 @@ - - - - - - + diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java index a48f7a139..1b93bbe03 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractFileSystemTest.java @@ -66,9 +66,9 @@ public abstract class AbstractFileSystemTest } /** - * Returns the URI for the base folder. + * Returns the base folder to run the tests against. */ - protected abstract String getBaseFolderURI() throws Exception; + protected abstract FileObject getBaseFolder() throws Exception; /** * Sets up the test @@ -79,7 +79,10 @@ public abstract class AbstractFileSystemTest m_manager = new DefaultFileSystemManager(); // Locate the base folder - m_baseFolder = m_manager.resolveFile( getBaseFolderURI() ); + m_baseFolder = getBaseFolder(); + + // Make some assumptions absout the name + assertTrue( ! m_baseFolder.getName().getPath().equals( "/" ) ); // Build the expected content of "file1.txt" final String eol = System.getProperty( "line.separator" ); @@ -123,6 +126,66 @@ public abstract class AbstractFileSystemTest assertSame( "file object", m_baseFolder.getParent(), file ); } + /** + * Tests encoding of relative URI. + */ + public void testRelativeUriEncoding() throws Exception + { + // Build base dir + m_manager.setBaseFile( m_baseFolder ); + final String path = m_baseFolder.getName().getPath(); + + // Encode "some file" + FileObject file = m_manager.resolveFile( "%73%6f%6d%65%20%66%69%6c%65" ); + assertEquals( path + "/some file", file.getName().getPath() ); + + // Encode "." + file = m_manager.resolveFile( "%2e" ); + assertEquals( path, file.getName().getPath() ); + + // Encode '%' + file = m_manager.resolveFile( "a%25" ); + assertEquals( path + "/a%", file.getName().getPath() ); + + // Encode / + file = m_manager.resolveFile( "dir%2fchild" ); + assertEquals( path + "/dir/child", file.getName().getPath() ); + + // Encode \ + file = m_manager.resolveFile( "dir%5cchild" ); + assertEquals( path + "/dir/child", file.getName().getPath() ); + + // Use "%" literal + try + { + m_manager.resolveFile( "%" ); + fail(); + } + catch( FileSystemException e ) + { + } + + // Not enough digits in encoded char + try + { + m_manager.resolveFile( "%5" ); + fail(); + } + catch( FileSystemException e ) + { + } + + // Invalid digit in encoded char + try + { + m_manager.resolveFile( "%q" ); + fail(); + } + catch( FileSystemException e ) + { + } + } + /** * Tests the root file name. */ @@ -176,7 +239,7 @@ public abstract class AbstractFileSystemTest final NameScope scope ) throws Exception { - // Make some assumptions about the name explicit + // Make some assumptions about the name assertTrue( !name.getPath().equals( "/" ) ); assertTrue( !name.getPath().endsWith( "/a" ) ); assertTrue( !name.getPath().endsWith( "/a/b" ) ); @@ -329,6 +392,46 @@ public abstract class AbstractFileSystemTest checkDescendentNames( baseName, NameScope.DESCENDENT ); } + /** + * Tests resolution of absolute names. + */ + public void testAbsoluteNames() throws Exception + { + // Test against the base folder + FileName name = m_baseFolder.getName(); + checkAbsoluteNames( name ); + + // Test against the root + name = m_baseFolder.getRoot().getName(); + checkAbsoluteNames( name ); + + // Test against some unknown file + name = name.resolveName( "a/b/unknown" ); + checkAbsoluteNames( name ); + } + + /** + * Tests resolution of absolute names. + */ + private void checkAbsoluteNames( final FileName name ) throws Exception + { + // Root + assertSameName( "/", name, "/" ); + assertSameName( "/", name, "//" ); + assertSameName( "/", name, "/." ); + assertSameName( "/", name, "/some file/.." ); + + // Some absolute names + assertSameName( "/a", name, "/a" ); + assertSameName( "/a", name, "/./a" ); + assertSameName( "/a", name, "/a/." ); + assertSameName( "/a/b", name, "/a/b" ); + + // Some bad names + assertBadName( name, "/..", NameScope.FILE_SYSTEM ); + assertBadName( name, "/a/../..", NameScope.FILE_SYSTEM ); + } + /** * Asserts that a particular relative name is invalid for a particular * scope. @@ -340,7 +443,7 @@ public abstract class AbstractFileSystemTest try { name.resolveName( relName, scope ); - fail(); + fail( "expected failure" ); } catch( FileSystemException e ) { diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractWritableFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractWritableFileSystemTest.java index 8243bb32e..ad57831aa 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractWritableFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/AbstractWritableFileSystemTest.java @@ -16,7 +16,8 @@ import java.util.Set; * * @author Adam Murdoch */ -public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemTest +public abstract class AbstractWritableFileSystemTest + extends AbstractFileSystemTest { public AbstractWritableFileSystemTest( String name ) { @@ -26,14 +27,14 @@ public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemT /** * Returns the URI for the area to do tests in. */ - protected abstract String getWriteFolderURI() throws Exception; + protected abstract FileObject getWriteFolder() throws Exception; /** * Sets up a scratch folder for the test to use. */ protected FileObject createScratchFolder() throws Exception { - FileObject scratchFolder = m_manager.resolveFile( getWriteFolderURI() ); + FileObject scratchFolder = getWriteFolder(); // Make sure the test folder is empty scratchFolder.delete(); diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/FtpFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/FtpFileSystemTest.java index dc12a0009..56a344802 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/FtpFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/FtpFileSystemTest.java @@ -7,12 +7,15 @@ */ package org.apache.aut.vfs; +import org.apache.aut.vfs.provider.ftp.FtpFileSystemProvider; + /** * Tests for FTP file systems. * * @author Adam Murdoch */ -public class FtpFileSystemTest extends AbstractWritableFileSystemTest +public class FtpFileSystemTest + extends AbstractWritableFileSystemTest { public FtpFileSystemTest( String name ) { @@ -22,16 +25,19 @@ public class FtpFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { - return System.getProperty( "test.ftp.uri" ) + "/read-tests"; + final String uri = System.getProperty( "test.ftp.uri" ) + "/read-tests"; + m_manager.addProvider( "ftp", new FtpFileSystemProvider() ); + return m_manager.resolveFile( uri ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() + protected FileObject getWriteFolder() throws Exception { - return System.getProperty( "test.ftp.uri" ) + "/write-tests"; + final String uri = System.getProperty( "test.ftp.uri" ) + "/write-tests"; + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/LocalFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/LocalFileSystemTest.java index ae74afe75..e0218041e 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/LocalFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/LocalFileSystemTest.java @@ -24,21 +24,19 @@ public class LocalFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() - throws Exception + protected FileObject getBaseFolder() throws Exception { final File testDir = getTestResource( "basedir" ); - return testDir.toURL().toString(); + return m_manager.convert( testDir ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() - throws Exception + protected FileObject getWriteFolder() throws Exception { final File testDir = getTestResource( "write-tests" ); - return testDir.toURL().toString(); + return m_manager.convert( testDir ); } /** diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/NestedZipFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/NestedZipFileSystemTest.java new file mode 100644 index 000000000..b5523a688 --- /dev/null +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/NestedZipFileSystemTest.java @@ -0,0 +1,41 @@ +/* + * 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.aut.vfs; + +import org.apache.aut.vfs.provider.zip.ZipFileSystemProvider; + +/** + * Tests for the Zip file system, using a zip file nested inside another zip file. + * + * @author Adam Murdoch + */ +public class NestedZipFileSystemTest + extends AbstractReadOnlyFileSystemTest +{ + public NestedZipFileSystemTest( String name ) + { + super( name ); + } + + /** + * Returns the URI for the base folder. + */ + protected FileObject getBaseFolder() throws Exception + { + m_manager.addProvider( "zip", new ZipFileSystemProvider() ); + + // Locate the base Zip file + final String zipFilePath = getTestResource( "nested.zip" ).getAbsolutePath(); + String uri = "zip:" + zipFilePath + "!/test.zip"; + final FileObject zipFile = m_manager.resolveFile( uri ); + + // Now build the nested file system + final FileObject nestedFS = m_manager.createFileSystem( "zip", zipFile ); + return nestedFS.resolveFile( "/basedir" ); + } +} diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/SmbFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/SmbFileSystemTest.java index 308d92c65..c3ff819e7 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/SmbFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/SmbFileSystemTest.java @@ -7,6 +7,8 @@ */ package org.apache.aut.vfs; +import org.apache.aut.vfs.provider.smb.SmbFileSystemProvider; + /** * Tests for the SMB file system. * @@ -22,16 +24,19 @@ public class SmbFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { - return System.getProperty( "test.smb.uri" ) + "/read-tests"; + final String uri = System.getProperty( "test.smb.uri" ) + "/read-tests"; + m_manager.addProvider( "smb", new SmbFileSystemProvider() ); + return m_manager.resolveFile( uri ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() + protected FileObject getWriteFolder() throws Exception { - return System.getProperty( "test.smb.uri" ) + "/write-tests"; + final String uri = System.getProperty( "test.smb.uri" ) + "/write-tests"; + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/test/org/apache/aut/vfs/ZipFileSystemTest.java b/proposal/myrmidon/src/test/org/apache/aut/vfs/ZipFileSystemTest.java index 8755781c9..4c8b4af38 100644 --- a/proposal/myrmidon/src/test/org/apache/aut/vfs/ZipFileSystemTest.java +++ b/proposal/myrmidon/src/test/org/apache/aut/vfs/ZipFileSystemTest.java @@ -8,6 +8,7 @@ package org.apache.aut.vfs; import java.io.File; +import org.apache.aut.vfs.provider.zip.ZipFileSystemProvider; /** * Tests for the Zip file system. @@ -24,10 +25,11 @@ public class ZipFileSystemTest extends AbstractReadOnlyFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { File zipFile = getTestResource( "test.zip" ); - String uri = "zip:" + zipFile + "!basedir"; - return uri; + String uri = "zip:" + zipFile.getAbsolutePath() + "!basedir"; + m_manager.addProvider( "zip", new ZipFileSystemProvider() ); + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java index a48f7a139..1b93bbe03 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java @@ -66,9 +66,9 @@ public abstract class AbstractFileSystemTest } /** - * Returns the URI for the base folder. + * Returns the base folder to run the tests against. */ - protected abstract String getBaseFolderURI() throws Exception; + protected abstract FileObject getBaseFolder() throws Exception; /** * Sets up the test @@ -79,7 +79,10 @@ public abstract class AbstractFileSystemTest m_manager = new DefaultFileSystemManager(); // Locate the base folder - m_baseFolder = m_manager.resolveFile( getBaseFolderURI() ); + m_baseFolder = getBaseFolder(); + + // Make some assumptions absout the name + assertTrue( ! m_baseFolder.getName().getPath().equals( "/" ) ); // Build the expected content of "file1.txt" final String eol = System.getProperty( "line.separator" ); @@ -123,6 +126,66 @@ public abstract class AbstractFileSystemTest assertSame( "file object", m_baseFolder.getParent(), file ); } + /** + * Tests encoding of relative URI. + */ + public void testRelativeUriEncoding() throws Exception + { + // Build base dir + m_manager.setBaseFile( m_baseFolder ); + final String path = m_baseFolder.getName().getPath(); + + // Encode "some file" + FileObject file = m_manager.resolveFile( "%73%6f%6d%65%20%66%69%6c%65" ); + assertEquals( path + "/some file", file.getName().getPath() ); + + // Encode "." + file = m_manager.resolveFile( "%2e" ); + assertEquals( path, file.getName().getPath() ); + + // Encode '%' + file = m_manager.resolveFile( "a%25" ); + assertEquals( path + "/a%", file.getName().getPath() ); + + // Encode / + file = m_manager.resolveFile( "dir%2fchild" ); + assertEquals( path + "/dir/child", file.getName().getPath() ); + + // Encode \ + file = m_manager.resolveFile( "dir%5cchild" ); + assertEquals( path + "/dir/child", file.getName().getPath() ); + + // Use "%" literal + try + { + m_manager.resolveFile( "%" ); + fail(); + } + catch( FileSystemException e ) + { + } + + // Not enough digits in encoded char + try + { + m_manager.resolveFile( "%5" ); + fail(); + } + catch( FileSystemException e ) + { + } + + // Invalid digit in encoded char + try + { + m_manager.resolveFile( "%q" ); + fail(); + } + catch( FileSystemException e ) + { + } + } + /** * Tests the root file name. */ @@ -176,7 +239,7 @@ public abstract class AbstractFileSystemTest final NameScope scope ) throws Exception { - // Make some assumptions about the name explicit + // Make some assumptions about the name assertTrue( !name.getPath().equals( "/" ) ); assertTrue( !name.getPath().endsWith( "/a" ) ); assertTrue( !name.getPath().endsWith( "/a/b" ) ); @@ -329,6 +392,46 @@ public abstract class AbstractFileSystemTest checkDescendentNames( baseName, NameScope.DESCENDENT ); } + /** + * Tests resolution of absolute names. + */ + public void testAbsoluteNames() throws Exception + { + // Test against the base folder + FileName name = m_baseFolder.getName(); + checkAbsoluteNames( name ); + + // Test against the root + name = m_baseFolder.getRoot().getName(); + checkAbsoluteNames( name ); + + // Test against some unknown file + name = name.resolveName( "a/b/unknown" ); + checkAbsoluteNames( name ); + } + + /** + * Tests resolution of absolute names. + */ + private void checkAbsoluteNames( final FileName name ) throws Exception + { + // Root + assertSameName( "/", name, "/" ); + assertSameName( "/", name, "//" ); + assertSameName( "/", name, "/." ); + assertSameName( "/", name, "/some file/.." ); + + // Some absolute names + assertSameName( "/a", name, "/a" ); + assertSameName( "/a", name, "/./a" ); + assertSameName( "/a", name, "/a/." ); + assertSameName( "/a/b", name, "/a/b" ); + + // Some bad names + assertBadName( name, "/..", NameScope.FILE_SYSTEM ); + assertBadName( name, "/a/../..", NameScope.FILE_SYSTEM ); + } + /** * Asserts that a particular relative name is invalid for a particular * scope. @@ -340,7 +443,7 @@ public abstract class AbstractFileSystemTest try { name.resolveName( relName, scope ); - fail(); + fail( "expected failure" ); } catch( FileSystemException e ) { diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java index 8243bb32e..ad57831aa 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java @@ -16,7 +16,8 @@ import java.util.Set; * * @author Adam Murdoch */ -public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemTest +public abstract class AbstractWritableFileSystemTest + extends AbstractFileSystemTest { public AbstractWritableFileSystemTest( String name ) { @@ -26,14 +27,14 @@ public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemT /** * Returns the URI for the area to do tests in. */ - protected abstract String getWriteFolderURI() throws Exception; + protected abstract FileObject getWriteFolder() throws Exception; /** * Sets up a scratch folder for the test to use. */ protected FileObject createScratchFolder() throws Exception { - FileObject scratchFolder = m_manager.resolveFile( getWriteFolderURI() ); + FileObject scratchFolder = getWriteFolder(); // Make sure the test folder is empty scratchFolder.delete(); diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java index dc12a0009..56a344802 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java @@ -7,12 +7,15 @@ */ package org.apache.aut.vfs; +import org.apache.aut.vfs.provider.ftp.FtpFileSystemProvider; + /** * Tests for FTP file systems. * * @author Adam Murdoch */ -public class FtpFileSystemTest extends AbstractWritableFileSystemTest +public class FtpFileSystemTest + extends AbstractWritableFileSystemTest { public FtpFileSystemTest( String name ) { @@ -22,16 +25,19 @@ public class FtpFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { - return System.getProperty( "test.ftp.uri" ) + "/read-tests"; + final String uri = System.getProperty( "test.ftp.uri" ) + "/read-tests"; + m_manager.addProvider( "ftp", new FtpFileSystemProvider() ); + return m_manager.resolveFile( uri ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() + protected FileObject getWriteFolder() throws Exception { - return System.getProperty( "test.ftp.uri" ) + "/write-tests"; + final String uri = System.getProperty( "test.ftp.uri" ) + "/write-tests"; + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java index ae74afe75..e0218041e 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java @@ -24,21 +24,19 @@ public class LocalFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() - throws Exception + protected FileObject getBaseFolder() throws Exception { final File testDir = getTestResource( "basedir" ); - return testDir.toURL().toString(); + return m_manager.convert( testDir ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() - throws Exception + protected FileObject getWriteFolder() throws Exception { final File testDir = getTestResource( "write-tests" ); - return testDir.toURL().toString(); + return m_manager.convert( testDir ); } /** diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/NestedZipFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/NestedZipFileSystemTest.java new file mode 100644 index 000000000..b5523a688 --- /dev/null +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/NestedZipFileSystemTest.java @@ -0,0 +1,41 @@ +/* + * 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.aut.vfs; + +import org.apache.aut.vfs.provider.zip.ZipFileSystemProvider; + +/** + * Tests for the Zip file system, using a zip file nested inside another zip file. + * + * @author Adam Murdoch + */ +public class NestedZipFileSystemTest + extends AbstractReadOnlyFileSystemTest +{ + public NestedZipFileSystemTest( String name ) + { + super( name ); + } + + /** + * Returns the URI for the base folder. + */ + protected FileObject getBaseFolder() throws Exception + { + m_manager.addProvider( "zip", new ZipFileSystemProvider() ); + + // Locate the base Zip file + final String zipFilePath = getTestResource( "nested.zip" ).getAbsolutePath(); + String uri = "zip:" + zipFilePath + "!/test.zip"; + final FileObject zipFile = m_manager.resolveFile( uri ); + + // Now build the nested file system + final FileObject nestedFS = m_manager.createFileSystem( "zip", zipFile ); + return nestedFS.resolveFile( "/basedir" ); + } +} diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java index 308d92c65..c3ff819e7 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java @@ -7,6 +7,8 @@ */ package org.apache.aut.vfs; +import org.apache.aut.vfs.provider.smb.SmbFileSystemProvider; + /** * Tests for the SMB file system. * @@ -22,16 +24,19 @@ public class SmbFileSystemTest extends AbstractWritableFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { - return System.getProperty( "test.smb.uri" ) + "/read-tests"; + final String uri = System.getProperty( "test.smb.uri" ) + "/read-tests"; + m_manager.addProvider( "smb", new SmbFileSystemProvider() ); + return m_manager.resolveFile( uri ); } /** * Returns the URI for the area to do tests in. */ - protected String getWriteFolderURI() + protected FileObject getWriteFolder() throws Exception { - return System.getProperty( "test.smb.uri" ) + "/write-tests"; + final String uri = System.getProperty( "test.smb.uri" ) + "/write-tests"; + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java index 8755781c9..4c8b4af38 100644 --- a/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java +++ b/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java @@ -8,6 +8,7 @@ package org.apache.aut.vfs; import java.io.File; +import org.apache.aut.vfs.provider.zip.ZipFileSystemProvider; /** * Tests for the Zip file system. @@ -24,10 +25,11 @@ public class ZipFileSystemTest extends AbstractReadOnlyFileSystemTest /** * Returns the URI for the base folder. */ - protected String getBaseFolderURI() + protected FileObject getBaseFolder() throws Exception { File zipFile = getTestResource( "test.zip" ); - String uri = "zip:" + zipFile + "!basedir"; - return uri; + String uri = "zip:" + zipFile.getAbsolutePath() + "!basedir"; + m_manager.addProvider( "zip", new ZipFileSystemProvider() ); + return m_manager.resolveFile( uri ); } } diff --git a/proposal/myrmidon/src/xdocs/todo.xml b/proposal/myrmidon/src/xdocs/todo.xml index cdb2890ce..d77ea4d34 100644 --- a/proposal/myrmidon/src/xdocs/todo.xml +++ b/proposal/myrmidon/src/xdocs/todo.xml @@ -37,15 +37,22 @@

The VFS needs plenty of work: