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 [EMAIL PROTECTED] FileSet}.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 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 [EMAIL PROTECTED] 
#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 [EMAIL PROTECTED] FileObject}.
  +     *
  +     * @param file
  +     *          The file to convert.
  +     *
  +     * @return
  +     *          The [EMAIL PROTECTED] 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:[EMAIL PROTECTED]">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 [EMAIL PROTECTED] 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:[EMAIL PROTECTED]">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 [EMAIL PROTECTED] #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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">Adam Murdoch</a>
  + * @version $Revision: 1.2 $ $Date: 2002/03/09 10:31:30 $
    */
   public interface FileSystemProviderContext
   {
  +    /**
  +     * Locate a file by name.  See
  +     * [EMAIL PROTECTED] 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
        * [EMAIL PROTECTED] #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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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 [EMAIL PROTECTED] FileSystemManager} service.
    *
    * @author <a href="mailto:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]">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:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to