ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adammurd...@apache.org
Subject cvs commit: jakarta-ant/proposal/myrmidon/src/xdocs todo.xml user.xml
Date Sat, 09 Mar 2002 10:31:31 GMT
adammurdoch    02/03/09 02:31:31

  Modified:    proposal/myrmidon build.xml
               proposal/myrmidon/docs todo.html user.html
               proposal/myrmidon/etc/testcases/org/apache/antlib/vfile
                        copy.ant
               proposal/myrmidon/src/java/org/apache/antlib/vfile
                        CopyFilesTask.java DefaultFileSet.java
                        ListFileSetTask.java Resources.properties
               proposal/myrmidon/src/java/org/apache/aut/vfs
                        FileObject.java FileSystemManager.java
               proposal/myrmidon/src/java/org/apache/aut/vfs/impl
                        DefaultFileSystemManager.java Resources.properties
               proposal/myrmidon/src/java/org/apache/aut/vfs/provider
                        AbstractFileObject.java
                        AbstractFileSystemProvider.java
                        FileSystemProvider.java
                        FileSystemProviderContext.java ParsedUri.java
                        Resources.properties UriParser.java
               proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp
                        FtpFileNameParser.java FtpFileSystemProvider.java
               proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local
                        LocalFileNameParser.java
                        LocalFileSystemProvider.java
               proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb
                        SmbFileNameParser.java SmbFileSystemProvider.java
               proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip
                        ParsedZipUri.java ZipFileNameParser.java
                        ZipFileSystemProvider.java
               proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories
                        Resources.properties VfsManagerFactory.java
               proposal/myrmidon/src/manifest core-services.xml
               proposal/myrmidon/src/testcases/org/apache/aut/vfs
                        AbstractFileSystemTest.java
                        AbstractWritableFileSystemTest.java
                        FtpFileSystemTest.java LocalFileSystemTest.java
                        SmbFileSystemTest.java ZipFileSystemTest.java
               proposal/myrmidon/src/xdocs todo.xml user.xml
  Added:       proposal/myrmidon/src/java/org/apache/aut/vfs/impl
                        DefaultProviderContext.java
               proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories
                        VfsManager.java
               proposal/myrmidon/src/testcases/org/apache/aut/vfs
                        NestedZipFileSystemTest.java
  Log:
  VFS Tidy-ups:
  
  * Added FileObject.copy().
  
  * Renamed <v-copy> task attributes file -> srcfile, tofile -> destfile, todir -> destdir.
  
  * Moved provider instantiation out of DefaultFileSystemManager, and into
    myrmidon-aware VfsManager.  Providers are instantiated using the TypeManager.
    The list of providers isn't configurable yet.
  
  * Some support for %nn encoded URI (not quite complete).
  
  * Zip file system now handles zip files from any file system, not just local
    files.  Still read-only at this stage.  Uses a truely dodgy and very temporary
    replication mechanism.
  
  * Zip file system now handles relative paths in URI (e.g. zip:relpath.zip), that are
    resolved against the base dir.
  
  * Fixed bug in resolving names against the root file of a file system.
  
  * Changed behaviour of FileName.resolveName( ".." ) for the root file of
    a file system.
  
  * Added more test cases.
  
  * A bucketload of other minor changes.
  
  Revision  Changes    Path
  1.70      +3 -0      jakarta-ant/proposal/myrmidon/build.xml
  
  Index: build.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/build.xml,v
  retrieving revision 1.69
  retrieving revision 1.70
  diff -u -r1.69 -r1.70
  --- build.xml	9 Mar 2002 01:51:18 -0000	1.69
  +++ build.xml	9 Mar 2002 10:31:29 -0000	1.70
  @@ -557,6 +557,9 @@
           <zip zipfile="${test.vfs.dir}/test.zip">
               <fileset dir="${test.vfs.dir}" includes="basedir/**"/>
           </zip>
  +        <zip zipfile="${test.vfs.dir}/nested.zip">
  +            <fileset dir="${test.vfs.dir}" includes="test.zip"/>
  +        </zip>
   
           <!-- Prepare deployer tests -->
           <property name="test.deployer.dir"
  
  
  
  1.7       +11 -8     jakarta-ant/proposal/myrmidon/docs/todo.html
  
  Index: todo.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/docs/todo.html,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- todo.html	4 Mar 2002 04:24:24 -0000	1.6
  +++ todo.html	9 Mar 2002 10:31:29 -0000	1.7
  @@ -117,15 +117,22 @@
         <blockquote>
                           <p>The VFS needs plenty of work:</p>
                                   <ul>
  -                    <li>Move and copy files/folders.</li>
  +                    <li>Move files/folders.</li>
  +                    <li>Recursive folders copy.</li>
                       <li>Search through a file hierarchy, using Ant-style wildcards.</li>
                       <li>Search through a file hierarchy, using a Selector interface.</li>
                       <li>The in-memory caching mechanism is pretty rudimentary at this stage.
                       It needs work to make it size capped.  In addition, some mechanism needs
                       to be provided to release and refresh cached info.
                       </li>
  +                    <li>Convert files/folders into local files, for handing off
  +                    to external commands, or legacy tasks.</li>
  +                    <li>Refactor the replication mechanism out of ZipFileSystemProvder,
  +                    and make more general pluggable.</li>
                       <li>Capabilities discovery.</li>
                       <li>Attributes and attribute schema.</li>
  +                    <li>Handle file canonicalisation better (for cases like case-insensitive
  +                    file systems, symbolic links, name encoding, etc).</li>
                       <li>File system layering.  That is, the ability for a file system to
                       sit on top of another file system, or a file from another file system
                       (e.g. Zip/Jar/Tar file systems, gzip/encoding file systems, virtual file
  @@ -300,10 +307,6 @@
                           <p>A completely unordered list of items, big and small:</p>
                                   <ul>
                       <li>Search through the code for 'TODO' items and fix them.</li>
  -                    <li>Tidy-up CLIMain so that it calls System.exit() with a non-zero exit code,
  -                    if the build fails.</li>
  -                    <li>Tidy-up the 'build failed' message, so that the stack trace is only
  -                    printed out if the log level is verbose/debug.</li>
                       <li>Allow service factories to be configured from the contents of the
                       <code>ant-services.xml</code> descriptor.</li>
                       <li>Route external process stdout and stderr through the logger.</li>
  @@ -314,11 +317,10 @@
                       <li>Fire ProjectListener events projectStarted() and projectFinished()
                       events on start and finish of referenced projects, adding indicator methods
                       to ProjectEvent.</li>
  -                    <li>Convert PropertyUtil to a non-static PropertyResolver service.</li>
                       <li>Validate project and target names in DefaultProjectBuilder - reject dodgy
  -                    names like "," or "", or "  ".  Probably want to exclude names that start or
  +                    names like "," or "", or "  ".  Probably want to reject names that start or
                       end with white-space (though internal whitespace is probably fine).  We also
  -                    want to reserve certain punctuation characters like . , : ? [ ] { }, etc for
  +                    want to reserve certain punctuation characters like , : ? $ [ ] { } &lt; &gt;, etc for
                       future use.</li>
                       <li>Similarly, validate property names, using the same rules.</li>
                       <li>Detect duplicate type names.</li>
  @@ -330,6 +332,7 @@
                       an antlib.</li>
                       <li>Split up <code>&lt;is-set&gt;</code> condition into is-set and is-true conditions.</li>
                       <li>Allow the <code>&lt;if&gt;</code> task to take any condition implementation.</li>
  +                    <li>Add an else block to the <code>&lt;if&gt;</code> task.</li>
                       <li>Unit tests.</li>
                   </ul>
                       </blockquote>
  
  
  
  1.4       +2 -1      jakarta-ant/proposal/myrmidon/docs/user.html
  
  Index: user.html
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/docs/user.html,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- user.html	2 Mar 2002 01:53:59 -0000	1.3
  +++ user.html	9 Mar 2002 10:31:29 -0000	1.4
  @@ -125,7 +125,8 @@
                         <td bgcolor="#a0ddf0" colspan="" rowspan="" 
         valign="top" align="left">
       <font color="#000000" size="-1" face="arial,helvetica,sanserif">
  -          <a href="http://jcifs.samba.org">jcifs.samba.org</a>
  +          <a href="http://jcifs.samba.org">jcifs.samba.org</a>.
  +        <p>Note: there are problems using the 0.6.1 release.  Try 0.6.0 instead.</p>
           </font>
     </td>
         </tr>
  
  
  
  1.2       +1 -1      jakarta-ant/proposal/myrmidon/etc/testcases/org/apache/antlib/vfile/copy.ant
  
  Index: copy.ant
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/etc/testcases/org/apache/antlib/vfile/copy.ant,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- copy.ant	21 Feb 2002 03:26:23 -0000	1.1
  +++ copy.ant	9 Mar 2002 10:31:30 -0000	1.2
  @@ -1,7 +1,7 @@
   <project version="2.0">
       <target name="copy">
           <v-fileset id="src-files" dir="src"/>
  -        <v-copy todir="dest">
  +        <v-copy destdir="dest">
               <v-fileset-ref id="src-files"/>
           </v-copy>
       </target>
  
  
  
  1.4       +15 -45    jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/CopyFilesTask.java
  
  Index: CopyFilesTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/CopyFilesTask.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CopyFilesTask.java	2 Mar 2002 04:03:36 -0000	1.3
  +++ CopyFilesTask.java	9 Mar 2002 10:31:30 -0000	1.4
  @@ -7,8 +7,6 @@
    */
   package org.apache.antlib.vfile;
   
  -import java.io.InputStream;
  -import java.io.OutputStream;
   import java.util.ArrayList;
   import java.util.Iterator;
   import org.apache.aut.vfs.FileObject;
  @@ -41,7 +39,7 @@
       /**
        * Sets the source file.
        */
  -    public void setFile( final FileObject file )
  +    public void setSrcfile( final FileObject file )
       {
           m_srcFile = file;
       }
  @@ -49,7 +47,7 @@
       /**
        * Sets the destination file.
        */
  -    public void setTofile( final FileObject file )
  +    public void setDestfile( final FileObject file )
       {
           m_destFile = file;
       }
  @@ -57,12 +55,20 @@
       /**
        * Sets the destination directory.
        */
  -    public void setTodir( final FileObject file )
  +    public void setDestdir( final FileObject file )
       {
           m_destDir = file;
       }
   
       /**
  +     * Sets the source directory.
  +     */
  +    public void setSrcdir( final FileObject dir )
  +    {
  +        add( new DefaultFileSet( dir ) );
  +    }
  +
  +    /**
        * Adds a source file set.
        */
       public void add( final FileSet fileset )
  @@ -107,7 +113,8 @@
                       m_destFile = m_destDir.resolveFile( m_srcFile.getName().getBaseName() );
                   }
   
  -                copyFile( m_srcFile, m_destFile );
  +                getLogger().info( "copy " + m_srcFile + " to " + m_destFile );
  +                m_destFile.copy( m_srcFile );
               }
   
               // Copy the contents of the filesets across
  @@ -134,7 +141,8 @@
                       final FileObject destFile = m_destDir.resolveFile( path, NameScope.DESCENDENT );
   
                       // Copy the file across
  -                    copyFile( srcFile, destFile );
  +                    getLogger().info( "copy " + srcFile + " to " + destFile );
  +                    destFile.copy( srcFile );
                   }
               }
           }
  @@ -144,42 +152,4 @@
           }
       }
   
  -    /**
  -     * Copies a file.
  -     */
  -    private void copyFile( final FileObject srcFile, final FileObject destFile )
  -        throws TaskException
  -    {
  -        getLogger().info( "copy " + srcFile + " to " + destFile );
  -
  -        try
  -        {
  -            // TODO - move copy behind FileObject interface
  -            InputStream instr = srcFile.getContent().getInputStream();
  -            try
  -            {
  -                OutputStream outstr = destFile.getContent().getOutputStream();
  -                byte[] buffer = new byte[ 4096 ];
  -                while( true )
  -                {
  -                    int nread = instr.read( buffer );
  -                    if( nread == -1 )
  -                    {
  -                        break;
  -                    }
  -                    outstr.write( buffer, 0, nread );
  -                }
  -                outstr.close();
  -            }
  -            finally
  -            {
  -                instr.close();
  -            }
  -        }
  -        catch( Exception exc )
  -        {
  -            final String message = REZ.getString( "copyfilestask.copy-file.error", srcFile, destFile );
  -            throw new TaskException( message, exc );
  -        }
  -    }
   }
  
  
  
  1.5       +9 -0      jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/DefaultFileSet.java
  
  Index: DefaultFileSet.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/DefaultFileSet.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultFileSet.java	4 Mar 2002 04:23:37 -0000	1.4
  +++ DefaultFileSet.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -36,6 +36,15 @@
       private FileObject m_dir;
       private final AndFileSelector m_selector = new AndFileSelector();
   
  +    public DefaultFileSet()
  +    {
  +    }
  +
  +    public DefaultFileSet( final FileObject dir )
  +    {
  +        m_dir = dir;
  +    }
  +
       /**
        * Sets the root directory.
        */
  
  
  
  1.2       +17 -11    jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/ListFileSetTask.java
  
  Index: ListFileSetTask.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/ListFileSetTask.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ListFileSetTask.java	27 Feb 2002 12:05:36 -0000	1.1
  +++ ListFileSetTask.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -7,6 +7,7 @@
    */
   package org.apache.antlib.vfile;
   
  +import java.util.ArrayList;
   import org.apache.aut.vfs.FileObject;
   import org.apache.myrmidon.api.AbstractTask;
   import org.apache.myrmidon.api.TaskException;
  @@ -15,18 +16,18 @@
    * A debug task, that lists the contents of a {@link FileSet}.
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  - * @version $Revision: 1.1 $ $Date: 2002/02/27 12:05:36 $
  + * @version $Revision: 1.2 $ $Date: 2002/03/09 10:31:30 $
    *
    * @ant:task name="v-list-fileset"
    */
   public class ListFileSetTask
       extends AbstractTask
   {
  -    private FileSet m_fileSet;
  +    private final ArrayList m_fileSets = new ArrayList();
   
  -    public void set( final FileSet fileSet )
  +    public void add( final FileSet fileSet )
       {
  -        m_fileSet = fileSet;
  +        m_fileSets.add( fileSet );
       }
   
       /**
  @@ -35,14 +36,19 @@
       public void execute()
           throws TaskException
       {
  -        FileSetResult result = m_fileSet.getResult( getContext() );
  -        final FileObject[] files = result.getFiles();
  -        final String[] paths = result.getPaths();
  -        for( int i = 0; i < files.length; i++ )
  +        final int count = m_fileSets.size();
  +        for( int i = 0; i < count; i++ )
           {
  -            final FileObject file = files[ i ];
  -            final String path = paths[ i ];
  -            getLogger().info( path + " = " + file );
  +            final FileSet fileSet = (FileSet)m_fileSets.get(i );
  +            FileSetResult result = fileSet.getResult( getContext() );
  +            final FileObject[] files = result.getFiles();
  +            final String[] paths = result.getPaths();
  +            for( int j = 0; j < files.length; j++ )
  +            {
  +                final FileObject file = files[ j ];
  +                final String path = paths[ j ];
  +                getLogger().info( path + " = " + file );
  +            }
           }
       }
   }
  
  
  
  1.4       +0 -1      jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/antlib/vfile/Resources.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Resources.properties	3 Mar 2002 02:28:17 -0000	1.3
  +++ Resources.properties	9 Mar 2002 10:31:30 -0000	1.4
  @@ -6,6 +6,5 @@
   copyfilestask.no-source.error=No source files specified for {0} task.
   copyfilestask.no-destination.error=No destination file or directory specified for {0} task.
   copyfilestask.no-destination.error=No destination directory specified for {0} task.
  -copyfilestask.copy-file.error=Could not copy "{0}" to "{1}".
   
   filteredfilelist.no-selector.error=No filter criteria specified.
  
  
  
  1.3       +20 -0     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/FileObject.java
  
  Index: FileObject.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/FileObject.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FileObject.java	2 Mar 2002 04:07:51 -0000	1.2
  +++ FileObject.java	9 Mar 2002 10:31:30 -0000	1.3
  @@ -182,12 +182,32 @@
       void create( FileType type ) throws FileSystemException;
   
       /**
  +     * Copies the content of another file to this file.
  +     *
  +     * If this file does not exist, it is created.  Its parent folder is also
  +     * created, if necessary.  If this file does exist, its content is replaced.
  +     *
  +     * @param file The file to copy the content from.
  +     *
  +     * @throws FileSystemException
  +     *      If this file is read-only, or is a folder, or if the supplied file
  +     *      is not a file, or on error copying the content.
  +     */
  +    void copy( FileObject file ) throws FileSystemException;
  +
  +    /**
        * Returns this file's content.  The {@link FileContent} returned by this
        * method can be used to read and write the content of the file.
        *
        * <p>This method can be called if the file does not exist, and
        * the returned {@link FileContent} can be used to create the file
        * by writing its content.
  +     *
  +     * @todo Do not throw an exception if this file is a folder.  Instead,
  +     *       throw the exceptions when (if) any methods on the returned object
  +     *       are called.  This is to hand 2 cases: when the folder is deleted
  +     *       and recreated as a file, and to allow attributes of the folder
  +     *       to be set (last modified time, permissions, etc).
        *
        * @return
        *      This file's content.
  
  
  
  1.6       +39 -3     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/FileSystemManager.java
  
  Index: FileSystemManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/FileSystemManager.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- FileSystemManager.java	1 Mar 2002 02:13:35 -0000	1.5
  +++ FileSystemManager.java	9 Mar 2002 10:31:30 -0000	1.6
  @@ -71,7 +71,8 @@
        * @throws FileSystemException
        *          On error parsing the file name.
        */
  -    FileObject resolveFile( String name ) throws FileSystemException;
  +    FileObject resolveFile( String name )
  +        throws FileSystemException;
   
       /**
        * Locates a file by name.  The name is resolved as described
  @@ -90,7 +91,8 @@
        * @throws FileSystemException
        *          On error parsing the file name.
        */
  -    FileObject resolveFile( FileObject baseFile, String name ) throws FileSystemException;
  +    FileObject resolveFile( FileObject baseFile, String name )
  +        throws FileSystemException;
   
       /**
        * Locates a file by name.  See {@link #resolveFile(FileObject, String)}
  @@ -106,5 +108,39 @@
        *          On error parsing the file name.
        *
        */
  -    FileObject resolveFile( File baseFile, String name ) throws FileSystemException;
  +    FileObject resolveFile( File baseFile, String name )
  +        throws FileSystemException;
  +
  +    /**
  +     * Converts a local file into a {@link FileObject}.
  +     *
  +     * @param file
  +     *          The file to convert.
  +     *
  +     * @return
  +     *          The {@link FileObject} that represents the local file.
  +     *
  +     * @throws FileSystemException
  +     *          On error converting the file.
  +     */
  +    FileObject convert( File file )
  +        throws FileSystemException;
  +
  +    /**
  +     * Creates a layered file system.  A layered file system is a file system
  +     * that is created from the contents of another file file, such as a zip
  +     * or tar file.
  +     *
  +     * @param provider
  +     *          The name of the file system provider to use.  This name is
  +     *          the same as the scheme used in URI to identify the provider.
  +     *
  +     * @param file
  +     *          The file to use to create the file system.
  +     *
  +     * @throws FileSystemException
  +     *          On error creating the file system.
  +     */
  +    FileObject createFileSystem( String provider, FileObject file )
  +        throws FileSystemException;
   }
  
  
  
  1.5       +59 -73    jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/impl/DefaultFileSystemManager.java
  
  Index: DefaultFileSystemManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/impl/DefaultFileSystemManager.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DefaultFileSystemManager.java	15 Feb 2002 07:37:19 -0000	1.4
  +++ DefaultFileSystemManager.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -9,14 +9,11 @@
   
   import java.io.File;
   import java.util.HashMap;
  -import java.util.Iterator;
   import java.util.Map;
   import org.apache.aut.vfs.FileObject;
   import org.apache.aut.vfs.FileSystemException;
   import org.apache.aut.vfs.FileSystemManager;
  -import org.apache.aut.vfs.provider.FileSystem;
   import org.apache.aut.vfs.provider.FileSystemProvider;
  -import org.apache.aut.vfs.provider.FileSystemProviderContext;
   import org.apache.aut.vfs.provider.UriParser;
   import org.apache.aut.vfs.provider.local.LocalFileSystemProvider;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
  @@ -25,7 +22,8 @@
   /**
    * A default file system manager implementation.
    *
  - * @author Adam Murdoch
  + * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  + * @version $Revision: 1.5 $ $Date: 2002/03/09 10:31:30 $
    */
   public class DefaultFileSystemManager
       implements FileSystemManager
  @@ -40,69 +38,55 @@
       private final Map m_providers = new HashMap();
   
       /** The provider context. */
  -    private final ProviderContextImpl m_context = new ProviderContextImpl();
  +    private final DefaultProviderContext m_context = new DefaultProviderContext( this );
   
       /** The base file to use for relative URI. */
       private FileObject m_baseFile;
   
  -    /**
  -     * The cached file systems.  This is a mapping from root URI to
  -     * FileSystem object.
  -     */
  -    private final Map m_fileSystems = new HashMap();
  -
  -    public DefaultFileSystemManager() throws Exception
  +    public DefaultFileSystemManager()
       {
           // Create the local provider
           m_localFileProvider = new LocalFileSystemProvider();
           m_providers.put( "file", m_localFileProvider );
  +        m_localFileProvider.setContext( m_context );
  +    }
   
  -        // TODO - make this list configurable
  -        // Create the providers
  -
  -        FileSystemProvider provider = createProvider( "org.apache.aut.vfs.provider.zip.ZipFileSystemProvider" );
  -        if( provider != null )
  -        {
  -            m_providers.put( "zip", provider );
  -            m_providers.put( "jar", provider );
  -        }
  -
  -        provider = createProvider( "org.apache.aut.vfs.provider.smb.SmbFileSystemProvider" );
  -        if( provider != null )
  -        {
  -            m_providers.put( "smb", provider );
  -        }
  -
  -        provider = createProvider( "org.apache.aut.vfs.provider.ftp.FtpFileSystemProvider" );
  -        if( provider != null )
  -        {
  -            m_providers.put( "ftp", provider );
  -        }
  -
  -        // Contextualise the providers
  -        for( Iterator iterator = m_providers.values().iterator(); iterator.hasNext(); )
  -        {
  -            provider = (FileSystemProvider)iterator.next();
  -            provider.setContext( m_context );
  -        }
  +    /**
  +     * Registers a file system provider.
  +     */
  +    public void addProvider( final String urlScheme,
  +                             final FileSystemProvider provider )
  +        throws FileSystemException
  +    {
  +        addProvider( new String[] { urlScheme }, provider );
       }
   
       /**
  -     * Creates a provider instance, returns null if the provider class is
  -     * not found.
  +     * Registers a file system provider.
        */
  -    private FileSystemProvider createProvider( final String className )
  -        throws Exception
  +    public void addProvider( final String[] urlSchemes,
  +                             final FileSystemProvider provider )
  +        throws FileSystemException
       {
  -        try
  +        // Check for duplicates
  +        for( int i = 0; i < urlSchemes.length; i++ )
           {
  -            // TODO - wrap exceptions
  -            return (FileSystemProvider)Class.forName( className ).newInstance();
  +            final String scheme = urlSchemes[i ];
  +            if( m_providers.containsKey( scheme ) )
  +            {
  +                final String message = REZ.getString( "multiple-providers-for-scheme.error", scheme );
  +                throw new FileSystemException( message );
  +            }
           }
  -        catch( ClassNotFoundException e )
  +
  +        // Contextualise
  +        provider.setContext( m_context );
  +
  +        // Add to map
  +        for( int i = 0; i < urlSchemes.length; i++ )
           {
  -            // This is fine, for now
  -            return null;
  +            final String scheme = urlSchemes[ i ];
  +            m_providers.put( scheme, provider );
           }
       }
   
  @@ -152,7 +136,7 @@
       public FileObject resolveFile( final File baseFile, final String uri )
           throws FileSystemException
       {
  -        final FileObject baseFileObj = m_localFileProvider.findFileByLocalName( baseFile );
  +        final FileObject baseFileObj = m_localFileProvider.findLocalFile( baseFile );
           return resolveFile( baseFileObj, uri );
       }
   
  @@ -170,14 +154,17 @@
               final FileSystemProvider provider = (FileSystemProvider)m_providers.get( scheme );
               if( provider != null )
               {
  -                return provider.findFile( uri );
  +                return provider.findFile( baseFile, uri );
               }
           }
   
  +        // Decode the URI (remove %nn encodings)
  +        final String decodedUri = UriParser.decode( uri );
  +
           // Handle absolute file names
  -        if( m_localFileProvider.isAbsoluteLocalName( uri ) )
  +        if( m_localFileProvider.isAbsoluteLocalName( decodedUri ) )
           {
  -            return m_localFileProvider.findLocalFile( uri );
  +            return m_localFileProvider.findLocalFile( decodedUri );
           }
   
           // Assume a bad scheme
  @@ -193,32 +180,31 @@
               final String message = REZ.getString( "find-rel-file.error", uri );
               throw new FileSystemException( message );
           }
  -        return baseFile.resolveFile( uri );
  +        return baseFile.resolveFile( decodedUri );
       }
   
       /**
  -     * A provider context implementation.
  +     * Converts a local file into a {@link FileObject}.
        */
  -    private final class ProviderContextImpl
  -        implements FileSystemProviderContext
  +    public FileObject convert( final File file )
  +        throws FileSystemException
       {
  -        /**
  -         * Locates a cached file system by root URI.
  -         */
  -        public FileSystem getFileSystem( final String rootURI )
  -        {
  -            // TODO - need to have a per-fs uri comparator
  -            return (FileSystem)m_fileSystems.get( rootURI );
  -        }
  +        return m_localFileProvider.findLocalFile( file );
  +    }
   
  -        /**
  -         * Registers a file system for caching.
  -         */
  -        public void putFileSystem( final String rootURI, final FileSystem fs )
  -            throws FileSystemException
  +    /**
  +     * Creates a layered file system.
  +     */
  +    public FileObject createFileSystem( final String scheme,
  +                                        final FileObject file )
  +        throws FileSystemException
  +    {
  +        FileSystemProvider provider = (FileSystemProvider)m_providers.get( scheme );
  +        if( provider == null )
           {
  -            // TODO - should really check that there's not one already cached
  -            m_fileSystems.put( rootURI, fs );
  +            final String message = REZ.getString( "unknown-provider.error", scheme );
  +            throw new FileSystemException( message );
           }
  +        return provider.createFileSystem( scheme, file );
       }
   }
  
  
  
  1.3       +2 -0      jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/impl/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/impl/Resources.properties,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Resources.properties	13 Feb 2002 02:30:02 -0000	1.2
  +++ Resources.properties	9 Mar 2002 10:31:30 -0000	1.3
  @@ -1,3 +1,5 @@
   # DefaultFileSystemManager
   unknown-scheme.error=Unknown scheme "{0}" in URI "{1}".
   find-rel-file.error=Could not find file with URI "{0}" because it is a relative path, and no base URI was provided.
  +multiple-providers-for-scheme.error=Multiple file system providers registered for URL scheme "{0}".
  +unknown-provider.error=Unknown file system provider "{0}".
  \ No newline at end of file
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/impl/DefaultProviderContext.java
  
  Index: DefaultProviderContext.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.aut.vfs.impl;
  
  import java.util.HashMap;
  import java.util.Map;
  import org.apache.aut.vfs.FileObject;
  import org.apache.aut.vfs.FileSystemException;
  import org.apache.aut.vfs.provider.FileSystem;
  import org.apache.aut.vfs.provider.FileSystemProviderContext;
  
  /**
   * A provider context implementation.
   *
   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 10:31:30 $
   */
  final class DefaultProviderContext
      implements FileSystemProviderContext
  {
      private final DefaultFileSystemManager m_manager;
  
      /**
       * The cached file systems.  This is a mapping from root URI to
       * FileSystem object.
       */
      private final Map m_fileSystems = new HashMap();
  
      public DefaultProviderContext( final DefaultFileSystemManager manager )
      {
          m_manager = manager;
      }
  
      /**
       * Locate a file by name.
       */
      public FileObject resolveFile( final FileObject baseFile, final String name )
          throws FileSystemException
      {
          return m_manager.resolveFile( baseFile, name );
      }
  
      /**
       * Locates a cached file system by root URI.
       */
      public FileSystem getFileSystem( final String rootURI )
      {
          // TODO - need to have a per-fs uri comparator
          return (FileSystem)m_fileSystems.get( rootURI );
      }
  
      /**
       * Registers a file system for caching.
       */
      public void putFileSystem( final String rootURI, final FileSystem fs )
          throws FileSystemException
      {
          // TODO - should really check that there's not one already cached
          m_fileSystems.put( rootURI, fs );
      }
  }
  
  
  
  1.6       +39 -4     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/AbstractFileObject.java
  
  Index: AbstractFileObject.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/AbstractFileObject.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractFileObject.java	14 Feb 2002 10:53:53 -0000	1.5
  +++ AbstractFileObject.java	9 Mar 2002 10:31:30 -0000	1.6
  @@ -21,6 +21,7 @@
   import org.apache.aut.vfs.NameScope;
   import org.apache.avalon.excalibur.i18n.ResourceManager;
   import org.apache.avalon.excalibur.i18n.Resources;
  +import org.apache.avalon.excalibur.io.IOUtil;
   
   /**
    * A partial file object implementation.
  @@ -349,7 +350,7 @@
           }
   
           // Update cached info
  -        updateType( null );
  +        updateType();
       }
   
       /**
  @@ -463,7 +464,41 @@
           }
   
           // Update cached info
  -        updateType( type );
  +        updateType();
  +    }
  +
  +    /**
  +     * Copies the content of another file to this file.
  +     */
  +    public void copy( final FileObject file ) throws FileSystemException
  +    {
  +        try
  +        {
  +            final InputStream instr = file.getContent().getInputStream();
  +            try
  +            {
  +                // Create the output strea via getContent(), to pick up the
  +                // validation it does
  +                final OutputStream outstr = getContent().getOutputStream();
  +                try
  +                {
  +                    IOUtil.copy( instr, outstr );
  +                }
  +                finally
  +                {
  +                    IOUtil.shutdownStream( outstr );
  +                }
  +            }
  +            finally
  +            {
  +                IOUtil.shutdownStream( instr );
  +            }
  +        }
  +        catch( final Exception exc )
  +        {
  +            final String message = REZ.getString( "copy-file.error", file.getName(), m_name );
  +            throw new FileSystemException( message, exc );
  +        }
       }
   
       /**
  @@ -598,14 +633,14 @@
        */
       public void endOutput() throws Exception
       {
  -        updateType( FileType.FILE );
  +        updateType();
           doEndOutput();
       }
   
       /**
        * Update cached info when this file's type changes.
        */
  -    private void updateType( FileType type )
  +    private void updateType()
       {
           // Notify parent that its child list may no longer be valid
           notifyParent();
  
  
  
  1.5       +62 -14    jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/AbstractFileSystemProvider.java
  
  Index: AbstractFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/AbstractFileSystemProvider.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractFileSystemProvider.java	9 Feb 2002 22:51:30 -0000	1.4
  +++ AbstractFileSystemProvider.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -23,13 +23,21 @@
       private final static Resources REZ =
           ResourceManager.getPackageResources( AbstractFileSystemProvider.class );
   
  -    protected FileSystemProviderContext m_context;
  +    private FileSystemProviderContext m_context;
  +
  +    /**
  +     * Returns the context for this provider.
  +     */
  +    protected FileSystemProviderContext getContext()
  +    {
  +        return m_context;
  +    }
   
       /**
        * Sets the context for this file system provider.  This method is called
        * before any of the other provider methods.
        */
  -    public void setContext( FileSystemProviderContext context )
  +    public void setContext( final FileSystemProviderContext context )
       {
           m_context = context;
       }
  @@ -40,13 +48,14 @@
        * @param uri
        *          The absolute URI of the file to find.
        */
  -    public FileObject findFile( String uri ) throws FileSystemException
  +    public FileObject findFile( final FileObject baseFile,
  +                                final String uri ) throws FileSystemException
       {
           // Parse the URI
  -        ParsedUri parsedURI = null;
  +        ParsedUri parsedUri = null;
           try
           {
  -            parsedURI = parseURI( uri );
  +            parsedUri = parseUri( baseFile, uri );
           }
           catch( FileSystemException exc )
           {
  @@ -54,31 +63,70 @@
               throw new FileSystemException( message, exc );
           }
   
  +        // Locate the file
  +        return findFile( parsedUri );
  +
  +    }
  +
  +    /**
  +     * Locates a file from its parsed URI.
  +     */
  +    private FileObject findFile( final ParsedUri parsedUri )
  +        throws FileSystemException
  +    {
           // Check in the cache for the file system
  -        FileSystem fs = m_context.getFileSystem( parsedURI.getRootURI() );
  +        final String rootUri = parsedUri.getRootUri();
  +        FileSystem fs = m_context.getFileSystem( rootUri );
           if( fs == null )
           {
  -            // Need to create the file system
  -            fs = createFileSystem( parsedURI );
  -            m_context.putFileSystem( parsedURI.getRootURI(), fs );
  +            // Need to create the file system, and cache it
  +            fs = createFileSystem( parsedUri );
  +            m_context.putFileSystem( rootUri, fs );
           }
   
           // Locate the file
  -        return fs.findFile( parsedURI.getPath() );
  +        return fs.findFile( parsedUri.getPath() );
  +    }
  +
  +    /**
  +     * Creates a layered file system.
  +     */
  +    public FileObject createFileSystem( final String scheme, final FileObject file )
  +        throws FileSystemException
  +    {
  +        // TODO - this is a pretty shonky model for layered FS; need to revise
  +
  +        // Build the URI
  +        final ParsedUri uri = buildUri( scheme, file );
  +
  +        // Locate the file
  +        return findFile( uri );
       }
   
       /**
        * Parses a URI into its components.  The returned value is used to
  -     * locate the file system in the cache (using the root prefix), and is
  -     * passed to {@link #createFileSystem} to create the file system.
  +     * locate the file system in the cache (using the root prefix).
        *
        * <p>The provider can annotate this object with any additional
        * information it requires to create a file system from the URI.
        */
  -    protected abstract ParsedUri parseURI( String uri ) throws FileSystemException;
  +    protected abstract ParsedUri parseUri( final FileObject baseFile, final String uri )
  +        throws FileSystemException;
  +
  +    /**
  +     * Builds the URI for the root of a layered file system.
  +     */
  +    protected ParsedUri buildUri( final String scheme,
  +                                  final FileObject file )
  +        throws FileSystemException
  +    {
  +        final String message = REZ.getString( "not-layered-fs.error" );
  +        throw new FileSystemException( message );
  +    }
   
       /**
        * Creates the filesystem.
        */
  -    protected abstract org.apache.aut.vfs.provider.FileSystem createFileSystem( ParsedUri uri ) throws FileSystemException;
  +    protected abstract FileSystem createFileSystem( final ParsedUri uri )
  +        throws FileSystemException;
   }
  
  
  
  1.2       +14 -1     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/FileSystemProvider.java
  
  Index: FileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/FileSystemProvider.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FileSystemProvider.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ FileSystemProvider.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -12,6 +12,11 @@
   
   /**
    * A file system provider, or factory.
  + *
  + * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  + * @version $Revision: 1.2 $ $Date: 2002/03/09 10:31:30 $
  + *
  + * @ant:role shorthand="file-system"
    */
   public interface FileSystemProvider
   {
  @@ -24,8 +29,16 @@
       /**
        * Locates a file object, by absolute URI.
        *
  +     * @param baseFile
  +     *          The base file to use for resolving the individual parts of
  +     *          a compound URI.
        * @param uri
        *          The absolute URI of the file to find.
        */
  -    FileObject findFile( String uri ) throws FileSystemException;
  +    FileObject findFile( FileObject baseFile, String uri ) throws FileSystemException;
  +
  +    /**
  +     * Creates a layered file system.
  +     */
  +    FileObject createFileSystem( String scheme, FileObject file ) throws FileSystemException;
   }
  
  
  
  1.2       +12 -1     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/FileSystemProviderContext.java
  
  Index: FileSystemProviderContext.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/FileSystemProviderContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FileSystemProviderContext.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ FileSystemProviderContext.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -7,16 +7,27 @@
    */
   package org.apache.aut.vfs.provider;
   
  +import org.apache.aut.vfs.FileObject;
   import org.apache.aut.vfs.FileSystemException;
  +import org.apache.aut.vfs.FileSystemManager;
   
   /**
    * Used for a file system provider to access the services it needs, such
    * as the file system cache or other file system providers.
    *
  - * @author Adam Murdoch
  + * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  + * @version $Revision: 1.2 $ $Date: 2002/03/09 10:31:30 $
    */
   public interface FileSystemProviderContext
   {
  +    /**
  +     * Locate a file by name.  See
  +     * {@link FileSystemManager#resolveFile(FileObject, String)} for a
  +     * description of how this works.
  +     */
  +    FileObject resolveFile( FileObject baseFile, String name )
  +        throws FileSystemException;
  +
       /**
        * Locates a cached file system by root URI.
        */
  
  
  
  1.2       +2 -2      jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ParsedUri.java
  
  Index: ParsedUri.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ParsedUri.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParsedUri.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ ParsedUri.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -34,13 +34,13 @@
       }
   
       /** Returns the root URI, used to identify the file system. */
  -    public String getRootURI()
  +    public String getRootUri()
       {
           return m_rootURI;
       }
   
       /** Sets the root URI. */
  -    public void setRootURI( String rootPrefix )
  +    public void setRootUri( String rootPrefix )
       {
           m_rootURI = rootPrefix;
       }
  
  
  
  1.4       +4 -0      jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/Resources.properties,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Resources.properties	2 Mar 2002 04:07:51 -0000	1.3
  +++ Resources.properties	9 Mar 2002 10:31:30 -0000	1.4
  @@ -17,6 +17,7 @@
   write-folder.error=Could not write to "{0}" because it is a folder.
   write-in-use.error=Could not write to "{0}" because it is already in use.
   write.error=Could not write to "{0}".
  +copy-file.error=Could not copy "{0}" to "{1}".
   
   # DefaultFileContent
   get-size-no-exist.error=Could not determine the size of file "{0}" because it does not exist.
  @@ -30,6 +31,7 @@
   
   # AbstractFileSystemProvider
   invalid-absolute-uri.error=Invalid absolute URI "{0}".
  +not-layered-fs.error=File system is not a layered file system.
   
   # UriParser
   missing-double-slashes.error=Expecting // to follow the scheme in URI "{0}".
  @@ -38,3 +40,5 @@
   missing-hostname-path-sep.error=Expecting / to follow the hostname in URI "{0}".
   invalid-childname.error=Invalid file base-name "{0}".
   invalid-descendent-name.error=Invalid descendent file name "{0}".
  +invalid-escape-sequence.error=Invalid URI escape sequence "{0}".
  +invalid-relative-path.error=Invalid relative file name.
  \ No newline at end of file
  
  
  
  1.5       +154 -19   jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/UriParser.java
  
  Index: UriParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/UriParser.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- UriParser.java	2 Mar 2002 04:07:51 -0000	1.4
  +++ UriParser.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -84,14 +84,41 @@
        * Parses an absolute URI, splitting it into its components.  This
        * implementation assumes a "generic URI", as defined by RFC 2396.  See
        * {@link #parseGenericUri} for more info.
  -     *
  -     * <p>Sub-classes should override this method.
        */
       public ParsedUri parseUri( final String uriStr ) throws FileSystemException
       {
  -        final ParsedUri retval = new ParsedUri();
  -        parseGenericUri( uriStr, retval );
  -        return retval;
  +        // Parse the URI
  +        final ParsedUri uri = new ParsedUri();
  +        parseGenericUri( uriStr, uri );
  +
  +        // Build the root URI
  +        final StringBuffer rootUri = new StringBuffer();
  +        appendRootUri( uri, rootUri );
  +        uri.setRootUri( rootUri.toString() );
  +
  +        return uri;
  +    }
  +
  +    /**
  +     * Assembles a generic URI, appending to the supplied StringBuffer.
  +     */
  +    protected void appendRootUri( final ParsedUri uri, final StringBuffer rootUri )
  +    {
  +        rootUri.append( uri.getScheme() );
  +        rootUri.append( "://" );
  +        final String userInfo = uri.getUserInfo();
  +        if( userInfo != null && userInfo.length() != 0 )
  +        {
  +            rootUri.append( userInfo );
  +            rootUri.append( "@" );
  +        }
  +        rootUri.append( uri.getHostName() );
  +        final String port = uri.getPort();
  +        if( port != null && port.length() > 0 )
  +        {
  +            rootUri.append( ":" );
  +            rootUri.append( port );
  +        }
       }
   
       /**
  @@ -119,7 +146,8 @@
           // Extract the scheme and authority parts
           extractToPath( uriStr, name, uri );
   
  -        // Normalise the file name
  +        // Decode and normalise the file name
  +        decode( name, 0, name.length() );
           normalisePath( name );
           uri.setPath( name.toString() );
   
  @@ -128,7 +156,7 @@
           rootUri.append( uri.getScheme() );
           rootUri.append( "://" );
           rootUri.append( uri.getHostName() );
  -        uri.setRootURI( rootUri.toString() );
  +        uri.setRootUri( rootUri.toString() );
       }
   
       /**
  @@ -404,9 +432,9 @@
           if( scope == NameScope.CHILD )
           {
               final int baseLen = baseFile.length();
  -            if( ! resolvedPath.startsWith( baseFile )
  +            if( !resolvedPath.startsWith( baseFile )
                   || resolvedPath.length() == baseLen
  -                || resolvedPath.charAt( baseLen ) != m_separatorChar
  +                || ( baseLen > 1 && resolvedPath.charAt( baseLen ) != m_separatorChar )
                   || resolvedPath.indexOf( m_separatorChar, baseLen + 1 ) != -1 )
               {
                   final String message = REZ.getString( "invalid-childname.error", path );
  @@ -416,9 +444,9 @@
           else if( scope == NameScope.DESCENDENT )
           {
               final int baseLen = baseFile.length();
  -            if( ! resolvedPath.startsWith( baseFile )
  +            if( !resolvedPath.startsWith( baseFile )
                   || resolvedPath.length() == baseLen
  -                || resolvedPath.charAt( baseLen ) != m_separatorChar )
  +                || ( baseLen > 1 && resolvedPath.charAt( baseLen ) != m_separatorChar ) )
               {
                   final String message = REZ.getString( "invalid-descendent-name.error", path );
                   throw new FileSystemException( message );
  @@ -463,7 +491,8 @@
        * <li>Removes trailing separator.
        * </ul>
        */
  -    public void normalisePath( final StringBuffer path ) throws FileSystemException
  +    public void normalisePath( final StringBuffer path )
  +        throws FileSystemException
       {
           if( path.length() == 0 )
           {
  @@ -515,14 +544,20 @@
                   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 @@
        * @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 )
           {
  @@ -641,5 +677,104 @@
   
           // 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;
  +            }
  +        }
       }
   }
  
  
  
  1.3       +20 -4     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java
  
  Index: FtpFileNameParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileNameParser.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FtpFileNameParser.java	6 Feb 2002 13:33:42 -0000	1.2
  +++ FtpFileNameParser.java	9 Mar 2002 10:31:30 -0000	1.3
  @@ -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 @@
       /**
        * 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( ':' );
  @@ -45,6 +56,11 @@
                   uri.setPassword( password );
               }
           }
  +
  +        // Now build the root URI
  +        final StringBuffer rootUri = new StringBuffer();
  +        appendRootUri( uri, rootUri );
  +        uri.setRootUri( rootUri.toString() );
   
           return uri;
       }
  
  
  
  1.2       +12 -7     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java
  
  Index: FtpFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/ftp/FtpFileSystemProvider.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FtpFileSystemProvider.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ FtpFileSystemProvider.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -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();
  
  
  
  1.5       +10 -9     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java
  
  Index: LocalFileNameParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileNameParser.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LocalFileNameParser.java	2 Mar 2002 04:07:51 -0000	1.4
  +++ LocalFileNameParser.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -16,7 +16,7 @@
    * A name parser.
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  - * @version $Revision: 1.4 $ $Date: 2002/03/02 04:07:51 $
  + * @version $Revision: 1.5 $ $Date: 2002/03/09 10:31:30 $
    */
   abstract class LocalFileNameParser
       extends UriParser
  @@ -50,21 +50,22 @@
        *
        * @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 @@
           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;
       }
  
  
  
  1.5       +14 -9     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java
  
  Index: LocalFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/local/LocalFileSystemProvider.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- LocalFileSystemProvider.java	2 Mar 2002 04:07:51 -0000	1.4
  +++ LocalFileSystemProvider.java	9 Mar 2002 10:31:30 -0000	1.5
  @@ -21,7 +21,7 @@
    * A file system provider, which uses direct file access.
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  - * @version $Revision: 1.4 $ $Date: 2002/03/02 04:07:51 $
  + * @version $Revision: 1.5 $ $Date: 2002/03/09 10:31:30 $
    */
   public class LocalFileSystemProvider extends AbstractFileSystemProvider
       implements FileSystemProvider
  @@ -51,20 +51,22 @@
       /**
        * 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 @@
        * <p>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 );
       }
   }
  
  
  
  1.4       +18 -15    jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java
  
  Index: SmbFileNameParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileNameParser.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SmbFileNameParser.java	9 Feb 2002 02:51:50 -0000	1.3
  +++ SmbFileNameParser.java	9 Mar 2002 10:31:30 -0000	1.4
  @@ -27,19 +27,27 @@
       /**
        * 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 @@
           }
           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;
       }
  
  
  
  1.2       +12 -7     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java
  
  Index: SmbFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/smb/SmbFileSystemProvider.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SmbFileSystemProvider.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ SmbFileSystemProvider.java	9 Mar 2002 10:31:30 -0000	1.2
  @@ -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 @@
    * 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 );
       }
   }
  
  
  
  1.2       +15 -3     jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java
  
  Index: ParsedZipUri.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ParsedZipUri.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ParsedZipUri.java	2 Feb 2002 03:29:08 -0000	1.1
  +++ ParsedZipUri.java	9 Mar 2002 10:31:31 -0000	1.2
  @@ -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 @@
    */
   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;
       }
  
  
  
  1.2       +43 -33    jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java
  
  Index: ZipFileNameParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileNameParser.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ZipFileNameParser.java	2 Feb 2002 03:29:09 -0000	1.1
  +++ ZipFileNameParser.java	9 Mar 2002 10:31:31 -0000	1.2
  @@ -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 @@
    *
    * @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 <name>!<abspath>
  -        // 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 );
       }
   }
  
  
  
  1.2       +66 -12    jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java
  
  Index: ZipFileSystemProvider.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/aut/vfs/provider/zip/ZipFileSystemProvider.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ZipFileSystemProvider.java	2 Feb 2002 03:29:09 -0000	1.1
  +++ ZipFileSystemProvider.java	9 Mar 2002 10:31:31 -0000	1.2
  @@ -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 @@
    * 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 );
       }
  +
   }
  
  
  
  1.2       +2 -1      jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties
  
  Index: Resources.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/Resources.properties,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Resources.properties	25 Feb 2002 10:42:44 -0000	1.1
  +++ Resources.properties	9 Mar 2002 10:31:31 -0000	1.2
  @@ -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
  
  
  
  1.2       +2 -3      jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java
  
  Index: VfsManagerFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManagerFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- VfsManagerFactory.java	25 Feb 2002 10:42:44 -0000	1.1
  +++ VfsManagerFactory.java	9 Mar 2002 10:31:31 -0000	1.2
  @@ -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;
  @@ -18,7 +17,7 @@
    * A factory that creates the {@link FileSystemManager} service.
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
  - * @version $Revision: 1.1 $ $Date: 2002/02/25 10:42:44 $
  + * @version $Revision: 1.2 $ $Date: 2002/03/09 10:31:31 $
    */
   public class VfsManagerFactory
       implements ServiceFactory
  @@ -34,7 +33,7 @@
       {
           try
           {
  -            return new DefaultFileSystemManager();
  +            return new VfsManager();
           }
           catch( Exception e )
           {
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/java/org/apache/myrmidon/framework/factories/VfsManager.java
  
  Index: VfsManager.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.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 <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   * @version $Revision: 1.1 $ $Date: 2002/03/09 10:31:31 $
   */
  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 );
      }
  
  }
  
  
  
  1.4       +1 -6      jakarta-ant/proposal/myrmidon/src/manifest/core-services.xml
  
  Index: core-services.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/manifest/core-services.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- core-services.xml	25 Feb 2002 10:42:44 -0000	1.3
  +++ core-services.xml	9 Mar 2002 10:31:31 -0000	1.4
  @@ -1,9 +1,4 @@
   <services version="1.0">
       <exec-manager factory="org.apache.myrmidon.framework.factories.ExecManagerFactory"/>
  -    <file-system-manager factory="org.apache.myrmidon.framework.factories.VfsManagerFactory">
  -        <provider scheme="zip" classname="org.apache.aut.vfs.provider.zip.ZipFileSystemProvider"/>
  -        <provider scheme="jar" classname="org.apache.aut.vfs.provider.zip.ZipFileSystemProvider"/>
  -        <provider scheme="smb" classname="org.apache.aut.vfs.provider.smb.SmbFileSystemProvider"/>
  -        <provider scheme="ftp" classname="org.apache.aut.vfs.provider.ftp.FtpFileSystemProvider"/>
  -    </file-system-manager>
  +    <file-system-manager factory="org.apache.myrmidon.framework.factories.VfsManagerFactory"/>
   </services>
  
  
  
  1.5       +108 -5    jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java
  
  Index: AbstractFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractFileSystemTest.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- AbstractFileSystemTest.java	2 Mar 2002 04:07:51 -0000	1.4
  +++ AbstractFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.5
  @@ -66,9 +66,9 @@
       }
   
       /**
  -     * 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 @@
           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" );
  @@ -124,6 +127,66 @@
       }
   
       /**
  +     * 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.
        */
       public void testRootFileName() throws Exception
  @@ -176,7 +239,7 @@
                                          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" ) );
  @@ -330,6 +393,46 @@
       }
   
       /**
  +     * 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 @@
           try
           {
               name.resolveName( relName, scope );
  -            fail();
  +            fail( "expected failure" );
           }
           catch( FileSystemException e )
           {
  
  
  
  1.4       +4 -3      jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java
  
  Index: AbstractWritableFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/AbstractWritableFileSystemTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractWritableFileSystemTest.java	1 Mar 2002 08:54:34 -0000	1.3
  +++ AbstractWritableFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.4
  @@ -16,7 +16,8 @@
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
    */
  -public abstract class AbstractWritableFileSystemTest extends AbstractFileSystemTest
  +public abstract class AbstractWritableFileSystemTest
  +    extends AbstractFileSystemTest
   {
       public AbstractWritableFileSystemTest( String name )
       {
  @@ -26,14 +27,14 @@
       /**
        * 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();
  
  
  
  1.3       +11 -5     jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java
  
  Index: FtpFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/FtpFileSystemTest.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- FtpFileSystemTest.java	3 Feb 2002 03:25:37 -0000	1.2
  +++ FtpFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.3
  @@ -7,12 +7,15 @@
    */
   package org.apache.aut.vfs;
   
  +import org.apache.aut.vfs.provider.ftp.FtpFileSystemProvider;
  +
   /**
    * Tests for FTP file systems.
    *
    * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
    */
  -public class FtpFileSystemTest extends AbstractWritableFileSystemTest
  +public class FtpFileSystemTest
  +    extends AbstractWritableFileSystemTest
   {
       public FtpFileSystemTest( String name )
       {
  @@ -22,16 +25,19 @@
       /**
        * 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 );
       }
   }
  
  
  
  1.4       +4 -6      jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java
  
  Index: LocalFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/LocalFileSystemTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- LocalFileSystemTest.java	10 Feb 2002 02:34:13 -0000	1.3
  +++ LocalFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.4
  @@ -24,21 +24,19 @@
       /**
        * 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 );
       }
   
       /**
  
  
  
  1.3       +9 -4      jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java
  
  Index: SmbFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/SmbFileSystemTest.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SmbFileSystemTest.java	3 Feb 2002 03:25:37 -0000	1.2
  +++ SmbFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.3
  @@ -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 @@
       /**
        * 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 );
       }
   }
  
  
  
  1.4       +5 -3      jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java
  
  Index: ZipFileSystemTest.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/ZipFileSystemTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ZipFileSystemTest.java	10 Feb 2002 02:34:13 -0000	1.3
  +++ ZipFileSystemTest.java	9 Mar 2002 10:31:31 -0000	1.4
  @@ -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 @@
       /**
        * 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 );
       }
   }
  
  
  
  1.1                  jakarta-ant/proposal/myrmidon/src/testcases/org/apache/aut/vfs/NestedZipFileSystemTest.java
  
  Index: NestedZipFileSystemTest.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.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 <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
   */
  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" );
      }
  }
  
  
  
  1.7       +11 -8     jakarta-ant/proposal/myrmidon/src/xdocs/todo.xml
  
  Index: todo.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/xdocs/todo.xml,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- todo.xml	4 Mar 2002 04:24:24 -0000	1.6
  +++ todo.xml	9 Mar 2002 10:31:31 -0000	1.7
  @@ -37,15 +37,22 @@
                   <p>The VFS needs plenty of work:</p>
   
                   <ul>
  -                    <li>Move and copy files/folders.</li>
  +                    <li>Move files/folders.</li>
  +                    <li>Recursive folders copy.</li>
                       <li>Search through a file hierarchy, using Ant-style wildcards.</li>
                       <li>Search through a file hierarchy, using a Selector interface.</li>
                       <li>The in-memory caching mechanism is pretty rudimentary at this stage.
                       It needs work to make it size capped.  In addition, some mechanism needs
                       to be provided to release and refresh cached info.
                       </li>
  +                    <li>Convert files/folders into local files, for handing off
  +                    to external commands, or legacy tasks.</li>
  +                    <li>Refactor the replication mechanism out of ZipFileSystemProvder,
  +                    and make more general pluggable.</li>
                       <li>Capabilities discovery.</li>
                       <li>Attributes and attribute schema.</li>
  +                    <li>Handle file canonicalisation better (for cases like case-insensitive
  +                    file systems, symbolic links, name encoding, etc).</li>
                       <li>File system layering.  That is, the ability for a file system to
                       sit on top of another file system, or a file from another file system
                       (e.g. Zip/Jar/Tar file systems, gzip/encoding file systems, virtual file
  @@ -192,10 +199,6 @@
   
                   <ul>
                       <li>Search through the code for 'TODO' items and fix them.</li>
  -                    <li>Tidy-up CLIMain so that it calls System.exit() with a non-zero exit code,
  -                    if the build fails.</li>
  -                    <li>Tidy-up the 'build failed' message, so that the stack trace is only
  -                    printed out if the log level is verbose/debug.</li>
                       <li>Allow service factories to be configured from the contents of the
                       <code>ant-services.xml</code> descriptor.</li>
                       <li>Route external process stdout and stderr through the logger.</li>
  @@ -206,11 +209,10 @@
                       <li>Fire ProjectListener events projectStarted() and projectFinished()
                       events on start and finish of referenced projects, adding indicator methods
                       to ProjectEvent.</li>
  -                    <li>Convert PropertyUtil to a non-static PropertyResolver service.</li>
                       <li>Validate project and target names in DefaultProjectBuilder - reject dodgy
  -                    names like "," or "", or "  ".  Probably want to exclude names that start or
  +                    names like "," or "", or "  ".  Probably want to reject names that start or
                       end with white-space (though internal whitespace is probably fine).  We also
  -                    want to reserve certain punctuation characters like . , : ? [ ] { }, etc for
  +                    want to reserve certain punctuation characters like , : ? $ [ ] { } &lt; &gt;, etc for
                       future use.</li>
                       <li>Similarly, validate property names, using the same rules.</li>
                       <li>Detect duplicate type names.</li>
  @@ -222,6 +224,7 @@
                       an antlib.</li>
                       <li>Split up <code>&lt;is-set&gt;</code> condition into is-set and is-true conditions.</li>
                       <li>Allow the <code>&lt;if&gt;</code> task to take any condition implementation.</li>
  +                    <li>Add an else block to the <code>&lt;if&gt;</code> task.</li>
                       <li>Unit tests.</li>
                   </ul>
   
  
  
  
  1.5       +2 -1      jakarta-ant/proposal/myrmidon/src/xdocs/user.xml
  
  Index: user.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/myrmidon/src/xdocs/user.xml,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- user.xml	2 Mar 2002 01:35:52 -0000	1.4
  +++ user.xml	9 Mar 2002 10:31:31 -0000	1.5
  @@ -32,7 +32,8 @@
       <tr>
           <td>SMB VFS support (Samba, Windows shares)</td>
           <td>jcifs.jar</td>
  -        <td><a href="http://jcifs.samba.org">jcifs.samba.org</a></td>
  +        <td><a href="http://jcifs.samba.org">jcifs.samba.org</a>.
  +        <p>Note: there are problems using the 0.6.1 release.  Try 0.6.0 instead.</p></td>
       </tr>
       <tr>
           <td>FTP VFS support</td>
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message