You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@synapse.apache.org by ra...@apache.org on 2010/09/23 08:04:34 UTC

svn commit: r1000332 [12/27] - in /synapse/branches/commons-vfs-2-synapse-2.0: ./ core/ core/src/ core/src/main/ core/src/main/java/ core/src/main/java/org/ core/src/main/java/org/apache/ core/src/main/java/org/apache/commons/ core/src/main/java/org/ap...

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileObject.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileObject.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileObject.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileObject.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.compressed;
+
+import org.apache.commons.vfs.Capability;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.provider.AbstractFileObject;
+
+/**
+ * A compressed file.<br>
+ * Such a file do only have one child (the compressed filename with stripped last extension)
+ *
+ * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
+ * @version $Revision: 804644 $ $Date: 2009-08-16 13:32:15 +0530 (Sun, 16 Aug 2009) $
+ */
+public abstract class CompressedFileFileObject
+    extends AbstractFileObject
+    implements FileObject
+{
+    private final FileObject container;
+    private String[] children;
+
+    protected CompressedFileFileObject(FileName name, FileObject container, CompressedFileFileSystem fs)
+    {
+        super(name, fs);
+        this.container = container;
+
+        // todo, add getBaseName(String) to FileName
+        String basename = container.getName().getBaseName();
+        int pos = basename.lastIndexOf('.');
+        basename = basename.substring(0, pos);
+
+        children = new String[]
+        {
+            basename
+        };
+    }
+
+    /**
+     * Determines if this file can be written to.
+     *
+     * @return <code>true</code> if this file is writeable, <code>false</code> if not.
+     * @throws FileSystemException if an error occurs.
+     */
+    public boolean isWriteable() throws FileSystemException
+    {
+        return getFileSystem().hasCapability(Capability.WRITE_CONTENT);
+    }
+
+    /**
+     * Returns the file's type.
+     */
+    protected FileType doGetType() throws FileSystemException
+    {
+        if (getName().getPath().endsWith("/"))
+        {
+            return FileType.FOLDER;
+        }
+        else
+        {
+            return FileType.FILE;
+        }
+    }
+
+    /**
+     * Lists the children of the file.
+     */
+    protected String[] doListChildren()
+    {
+        return children;
+    }
+
+    /**
+     * Returns the size of the file content (in bytes).  Is only called if
+     * {@link #doGetType} returns {@link FileType#FILE}.
+     */
+    protected long doGetContentSize()
+    {
+        return -1;
+    }
+
+    /**
+     * Returns the last modified time of this file.
+     */
+    protected long doGetLastModifiedTime() throws Exception
+    {
+        return container.getContent().getLastModifiedTime();
+    }
+
+    protected FileObject getContainer()
+    {
+        return container;
+    }
+
+    public void createFile() throws FileSystemException
+    {
+        container.createFile();
+        injectType(FileType.FILE);
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileProvider.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileProvider.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileProvider.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileProvider.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.compressed;
+
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.provider.AbstractLayeredFileProvider;
+import org.apache.commons.vfs.provider.FileProvider;
+import org.apache.commons.vfs.provider.LayeredFileName;
+
+import java.util.Collection;
+
+/**
+ * A file system provider for compressed files.  Provides read-only file
+ * systems.
+ *
+ * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
+ * @version $Revision: 804644 $ $Date: 2009-08-16 13:32:15 +0530 (Sun, 16 Aug 2009) $
+ */
+public abstract class CompressedFileFileProvider
+    extends AbstractLayeredFileProvider
+    implements FileProvider
+{
+    public CompressedFileFileProvider()
+    {
+        super();
+    }
+
+    /**
+     * Parses an absolute URI.
+     *
+     * @param uri The URI to parse.
+     */
+    /*
+    public FileName parseUri(final String uri)
+        throws FileSystemException
+    {
+        return ZipFileName.parseUri(uri);
+    }
+    */
+
+    /**
+     * Creates a layered file system.  This method is called if the file system
+     * is not cached.
+     *
+     * @param scheme The URI scheme.
+     * @param file   The file to create the file system on top of.
+     * @return The file system.
+     */
+    protected FileSystem doCreateFileSystem(final String scheme,
+                                            final FileObject file,
+                                            final FileSystemOptions fileSystemOptions)
+        throws FileSystemException
+    {
+        final FileName name =
+            new LayeredFileName(scheme, file.getName(), FileName.ROOT_PATH, FileType.FOLDER);
+        return createFileSystem(name, file, fileSystemOptions);
+    }
+
+    protected abstract FileSystem createFileSystem(final FileName name, final FileObject file,
+                                                   final FileSystemOptions fileSystemOptions)
+        throws FileSystemException;
+
+    public abstract Collection getCapabilities();
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileSystem.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileSystem.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileSystem.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/CompressedFileFileSystem.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.compressed;
+
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.provider.AbstractFileSystem;
+
+import java.util.Collection;
+
+/**
+ * A read-only file system for compressed files.
+ *
+ * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
+ * @version $Revision: 480428 $ $Date: 2006-11-29 11:45:24 +0530 (Wed, 29 Nov 2006) $
+ */
+public abstract class CompressedFileFileSystem
+    extends AbstractFileSystem
+    implements FileSystem
+{
+    protected CompressedFileFileSystem(final FileName rootName,
+                                       final FileObject parentLayer,
+                                       final FileSystemOptions fileSystemOptions)
+        throws FileSystemException
+    {
+        super(rootName, parentLayer, fileSystemOptions);
+    }
+
+    public void init() throws FileSystemException
+    {
+        super.init();
+
+    }
+
+    /**
+     * Returns the capabilities of this file system.
+     */
+    protected abstract void addCapabilities(final Collection caps);
+
+    /**
+     * Creates a file object.
+     */
+    protected abstract FileObject createFile(final FileName name) throws FileSystemException;
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/package.html
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/package.html?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/package.html (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/compressed/package.html Thu Sep 23 06:04:21 2010
@@ -0,0 +1,19 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<body>
+<p>The compressed file provider</p>
+</body>
\ No newline at end of file

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FTPClientWrapper.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FTPClientWrapper.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FTPClientWrapper.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FTPClientWrapper.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,306 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.net.ftp.FTPReply;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.UserAuthenticationData;
+import org.apache.commons.vfs.provider.GenericFileName;
+import org.apache.commons.vfs.util.UserAuthenticatorUtils;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * A wrapper to the FTPClient to allow automatic reconnect on connection loss.<br />
+ * I decided to not to use eg. noop() to determine the state of the connection to avoid
+ * unnecesary server round-trips.
+ * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
+ */
+class FTPClientWrapper implements FtpClient
+{
+    private final GenericFileName root;
+    private final FileSystemOptions fileSystemOptions;
+
+    private FTPClient ftpClient;
+
+    FTPClientWrapper(final GenericFileName root, final FileSystemOptions fileSystemOptions) throws FileSystemException
+    {
+        this.root = root;
+        this.fileSystemOptions = fileSystemOptions;
+        getFtpClient(); // fail-fast
+    }
+
+    public GenericFileName getRoot()
+    {
+        return root;
+    }
+
+    public FileSystemOptions getFileSystemOptions()
+    {
+        return fileSystemOptions;
+    }
+
+    private FTPClient createClient() throws FileSystemException
+    {
+        final GenericFileName rootName = getRoot();
+
+        UserAuthenticationData authData = null;
+        try
+        {
+            authData = UserAuthenticatorUtils.authenticate(fileSystemOptions, FtpFileProvider.AUTHENTICATOR_TYPES);
+
+            return FtpClientFactory.createConnection(rootName.getHostName(),
+                rootName.getPort(),
+                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.USERNAME,
+                        UserAuthenticatorUtils.toChar(rootName.getUserName())),
+                UserAuthenticatorUtils.getData(authData, UserAuthenticationData.PASSWORD,
+                        UserAuthenticatorUtils.toChar(rootName.getPassword())),
+                rootName.getPath(),
+                getFileSystemOptions());
+        }
+        finally
+        {
+            UserAuthenticatorUtils.cleanup(authData);
+        }
+    }
+
+    private FTPClient getFtpClient() throws FileSystemException
+    {
+        if (ftpClient == null)
+        {
+            ftpClient = createClient();
+        }
+
+        return ftpClient;
+    }
+
+    public boolean isConnected() throws FileSystemException
+    {
+        return ftpClient != null && ftpClient.isConnected();
+    }
+
+    public void disconnect() throws IOException
+    {
+        try
+        {
+            getFtpClient().disconnect();
+        }
+        finally
+        {
+            ftpClient = null;
+        }
+    }
+
+    public FTPFile[] listFiles(String relPath) throws IOException
+    {
+        try
+        {
+            // VFS-210: return getFtpClient().listFiles(relPath);
+            FTPFile[] files = listFilesInDirectory(relPath);
+            return files;
+        }
+        catch (IOException e)
+        {
+            disconnect();
+
+            FTPFile[] files = listFilesInDirectory(relPath);
+            return files;
+        }
+    }
+
+    private FTPFile[] listFilesInDirectory(String relPath) throws IOException
+    {
+		FTPFile[] files;
+
+		// VFS-307: no check if we can simply list the files, this might fail if there are spaces in the path
+		files = getFtpClient().listFiles(relPath);
+		if (FTPReply.isPositiveCompletion(getFtpClient().getReplyCode()))
+		{
+			return files;
+		}
+
+		// VFS-307: now try the hard way by cd'ing into the directory, list and cd back
+		// if VFS is required to fallback here the user might experience a real bad FTP performance
+		// as then every list requires 4 ftp commands.
+        String workingDirectory = null;
+        if (relPath != null)
+        {
+            workingDirectory = getFtpClient().printWorkingDirectory();
+            if (!getFtpClient().changeWorkingDirectory(relPath))
+            {
+                return null;
+            }
+        }
+
+        files = getFtpClient().listFiles();
+
+        if (relPath != null && !getFtpClient().changeWorkingDirectory(workingDirectory))
+        {
+            throw new FileSystemException("vfs.provider.ftp.wrapper/change-work-directory-back.error",
+                    workingDirectory);
+        }
+        return files;
+    }
+
+    public boolean removeDirectory(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().removeDirectory(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().removeDirectory(relPath);
+        }
+    }
+
+    public boolean deleteFile(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().deleteFile(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().deleteFile(relPath);
+        }
+    }
+
+    public boolean rename(String oldName, String newName) throws IOException
+    {
+        try
+        {
+            return getFtpClient().rename(oldName, newName);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().rename(oldName, newName);
+        }
+    }
+
+    public boolean makeDirectory(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().makeDirectory(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().makeDirectory(relPath);
+        }
+    }
+
+    public boolean completePendingCommand() throws IOException
+    {
+        if (ftpClient != null)
+        {
+            return getFtpClient().completePendingCommand();
+        }
+
+        return true;
+    }
+
+    public InputStream retrieveFileStream(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().retrieveFileStream(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().retrieveFileStream(relPath);
+        }
+    }
+
+    public InputStream retrieveFileStream(String relPath, long restartOffset) throws IOException
+    {
+        try
+        {
+            FTPClient client = getFtpClient();
+            client.setRestartOffset(restartOffset);
+            return client.retrieveFileStream(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+
+            FTPClient client = getFtpClient();
+            client.setRestartOffset(restartOffset);
+            return client.retrieveFileStream(relPath);
+        }
+    }
+
+    public OutputStream appendFileStream(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().appendFileStream(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().appendFileStream(relPath);
+        }
+    }
+
+    public OutputStream storeFileStream(String relPath) throws IOException
+    {
+        try
+        {
+            return getFtpClient().storeFileStream(relPath);
+        }
+        catch (IOException e)
+        {
+            disconnect();
+            return getFtpClient().storeFileStream(relPath);
+        }
+    }
+
+    public boolean abort() throws IOException
+    {
+        try
+        {
+            // imario@apache.org: 2005-02-14
+            // it should be better to really "abort" the transfer, but
+            // currently I didnt manage to make it work - so lets "abort" the hard way.
+            // return getFtpClient().abort();
+
+            disconnect();
+            return true;
+        }
+        catch (IOException e)
+        {
+            disconnect();
+        }
+        return true;
+    }
+
+    public String getReplyString() throws IOException
+    {
+        return getFtpClient().getReplyString();
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClient.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClient.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClient.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClient.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.vfs.FileSystemException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * What VFS expects from an ftp client to provide.
+ * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
+ */
+public interface FtpClient
+{
+    boolean isConnected() throws FileSystemException;
+
+    void disconnect() throws IOException;
+
+    FTPFile[] listFiles(String relPath) throws IOException;
+
+    boolean removeDirectory(String relPath) throws IOException;
+
+    boolean deleteFile(String relPath) throws IOException;
+
+    boolean rename(String oldName, String newName) throws IOException;
+
+    boolean makeDirectory(String relPath) throws IOException;
+
+    boolean completePendingCommand() throws IOException;
+
+    InputStream retrieveFileStream(String relPath) throws IOException;
+
+    InputStream retrieveFileStream(String relPath, long restartOffset) throws IOException;
+
+    OutputStream appendFileStream(String relPath) throws IOException;
+
+    OutputStream storeFileStream(String relPath) throws IOException;
+
+    boolean abort() throws IOException;
+
+    String getReplyString() throws IOException;
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClientFactory.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClientFactory.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClientFactory.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpClientFactory.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,201 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.net.ftp.FTP;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPClientConfig;
+import org.apache.commons.net.ftp.FTPReply;
+import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.util.UserAuthenticatorUtils;
+
+import java.io.IOException;
+
+/**
+ * Create a FtpClient instance.
+ *
+ * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
+ * @version $Revision: 833482 $ $Date: 2009-11-06 23:08:44 +0530 (Fri, 06 Nov 2009) $
+ */
+public final class FtpClientFactory
+{
+    private static final int BUFSZ = 40;
+    private FtpClientFactory()
+    {
+    }
+
+    /**
+     * Creates a new connection to the server.
+     * @param hostname The host name of the server.
+     * @param port The port to connect to.
+     * @param username The name of the user for authentication.
+     * @param password The user's password.
+     * @param workingDirectory The base directory.
+     * @param fileSystemOptions The FileSystemOptions.
+     * @return An FTPClient.
+     * @throws FileSystemException if an error occurs while connecting.
+     */
+    public static FTPClient createConnection(String hostname, int port, char[] username, char[] password,
+                                             String workingDirectory, FileSystemOptions fileSystemOptions)
+            throws FileSystemException
+    {
+        // Determine the username and password to use
+        if (username == null)
+        {
+            username = "anonymous".toCharArray();
+        }
+
+        if (password == null)
+        {
+            password = "anonymous".toCharArray();
+        }
+
+        try
+        {
+            final FTPClient client = new FTPClient();
+
+            String key = FtpFileSystemConfigBuilder.getInstance().getEntryParser(fileSystemOptions);
+            if (key != null)
+            {
+                FTPClientConfig config = new FTPClientConfig(key);
+
+                String serverLanguageCode =
+                        FtpFileSystemConfigBuilder.getInstance().getServerLanguageCode(fileSystemOptions);
+                if (serverLanguageCode != null)
+                {
+                    config.setServerLanguageCode(serverLanguageCode);
+                }
+                String defaultDateFormat =
+                        FtpFileSystemConfigBuilder.getInstance().getDefaultDateFormat(fileSystemOptions);
+                if (defaultDateFormat != null)
+                {
+                    config.setDefaultDateFormatStr(defaultDateFormat);
+                }
+                String recentDateFormat =
+                        FtpFileSystemConfigBuilder.getInstance().getRecentDateFormat(fileSystemOptions);
+                if (recentDateFormat != null)
+                {
+                    config.setRecentDateFormatStr(recentDateFormat);
+                }
+                String serverTimeZoneId =
+                        FtpFileSystemConfigBuilder.getInstance().getServerTimeZoneId(fileSystemOptions);
+                if (serverTimeZoneId != null)
+                {
+                    config.setServerTimeZoneId(serverTimeZoneId);
+                }
+                String[] shortMonthNames =
+                        FtpFileSystemConfigBuilder.getInstance().getShortMonthNames(fileSystemOptions);
+                if (shortMonthNames != null)
+                {
+                    StringBuffer shortMonthNamesStr = new StringBuffer(BUFSZ);
+                    for (int i = 0; i < shortMonthNames.length; i++)
+                    {
+                        if (shortMonthNamesStr.length() > 0)
+                        {
+                            shortMonthNamesStr.append("|");
+                        }
+                        shortMonthNamesStr.append(shortMonthNames[i]);
+                    }
+                    config.setShortMonthNames(shortMonthNamesStr.toString());
+                }
+
+                client.configure(config);
+            }
+
+            FTPFileEntryParserFactory myFactory =
+                    FtpFileSystemConfigBuilder.getInstance().getEntryParserFactory(fileSystemOptions);
+            if (myFactory != null)
+            {
+                client.setParserFactory(myFactory);
+            }
+
+            try
+            {
+                client.connect(hostname, port);
+
+                int reply = client.getReplyCode();
+                if (!FTPReply.isPositiveCompletion(reply))
+                {
+                    throw new FileSystemException("vfs.provider.ftp/connect-rejected.error", hostname);
+                }
+
+                // Login
+                if (!client.login(
+                    UserAuthenticatorUtils.toString(username),
+                    UserAuthenticatorUtils.toString(password)))
+                {
+                    throw new FileSystemException("vfs.provider.ftp/login.error",
+                            new Object[]{hostname, UserAuthenticatorUtils.toString(username)}, null);
+                }
+
+                // Set binary mode
+                if (!client.setFileType(FTP.BINARY_FILE_TYPE))
+                {
+                    throw new FileSystemException("vfs.provider.ftp/set-binary.error", hostname);
+                }
+
+                // Set dataTimeout value
+                Integer dataTimeout = FtpFileSystemConfigBuilder.getInstance().getDataTimeout(fileSystemOptions);
+                if (dataTimeout != null)
+                {
+                    client.setDataTimeout(dataTimeout.intValue());
+                }
+
+                Integer socketTimeout = FtpFileSystemConfigBuilder.getInstance().getSoTimeout(fileSystemOptions);
+                if (socketTimeout != null)
+                {
+                    client.setSoTimeout(socketTimeout.intValue());
+                }
+
+                // Change to root by default
+                // All file operations a relative to the filesystem-root
+                // String root = getRoot().getName().getPath();
+
+                Boolean userDirIsRoot = FtpFileSystemConfigBuilder.getInstance().getUserDirIsRoot(fileSystemOptions);
+                if (workingDirectory != null && (userDirIsRoot == null || !userDirIsRoot.booleanValue()))
+                {
+                    if (!client.changeWorkingDirectory(workingDirectory))
+                    {
+                        throw new FileSystemException("vfs.provider.ftp/change-work-directory.error", workingDirectory);
+                    }
+                }
+
+                Boolean passiveMode = FtpFileSystemConfigBuilder.getInstance().getPassiveMode(fileSystemOptions);
+                if (passiveMode != null && passiveMode.booleanValue())
+                {
+                    client.enterLocalPassiveMode();
+                }
+            }
+            catch (final IOException e)
+            {
+                if (client.isConnected())
+                {
+                    client.disconnect();
+                }
+                throw e;
+            }
+
+            return client;
+        }
+        catch (final Exception exc)
+        {
+            throw new FileSystemException("vfs.provider.ftp/connect.error", new Object[]{hostname}, exc);
+        }
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileNameParser.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileNameParser.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileNameParser.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileNameParser.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.vfs.provider.*;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileType;
+
+
+/**
+ * Implementation for ftp. set default port to 21
+ *
+ * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
+ */
+public class FtpFileNameParser extends HostFileNameParser {
+    private static final FtpFileNameParser INSTANCE = new FtpFileNameParser();
+
+    private static final int PORT = 21;
+
+    public FtpFileNameParser() {
+        super(PORT);
+    }
+
+    public static FileNameParser getInstance() {
+        return INSTANCE;
+    }
+
+    public FileName parseUri(final VfsComponentContext context, FileName base, final String fileName)
+            throws FileSystemException {
+        // FTP URIs are generic URIs as per RFC 2396
+        final StringBuffer name = new StringBuffer();
+
+        // Extract the scheme and authority parts
+        final Authority auth = extractToPath(fileName, name);
+
+        // Extract the queuString
+        String queuString = UriParser.extractQueryString(name);
+        if(queuString == null && base instanceof URLFileName){
+            queuString = ((URLFileName) base).getQueryString();
+        }
+
+        // Decode and normalise the file name
+        UriParser.canonicalizePath(name, 0, name.length(), this);
+        UriParser.fixSeparators(name);
+        FileType fileType = UriParser.normalisePath(name);
+        final String path = name.toString();
+
+        return new URLFileName(
+                auth.getScheme(),
+                auth.getHostName(),
+                auth.getPort(),
+                getDefaultPort(),
+                auth.getUserName(),
+                auth.getPassword(),
+                path,
+                fileType,
+                queuString);
+
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,752 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.net.ftp.FTPFile;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileNotFolderException;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.RandomAccessContent;
+import org.apache.commons.vfs.provider.AbstractFileObject;
+import org.apache.commons.vfs.provider.UriParser;
+import org.apache.commons.vfs.util.FileObjectUtils;
+import org.apache.commons.vfs.util.Messages;
+import org.apache.commons.vfs.util.MonitorInputStream;
+import org.apache.commons.vfs.util.MonitorOutputStream;
+import org.apache.commons.vfs.util.RandomAccessMode;
+
+/**
+ * An FTP file.
+ *
+ * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
+ * @version $Revision: 895278 $ $Date: 2010-01-03 01:32:29 +0530 (Sun, 03 Jan 2010) $
+ */
+public class FtpFileObject
+    extends AbstractFileObject
+{
+    private static final Map EMPTY_FTP_FILE_MAP = Collections.unmodifiableMap(new TreeMap());
+    private static final FTPFile UNKNOWN = new FTPFile();
+
+    private Log log = LogFactory.getLog(FtpFileObject.class);
+    private final FtpFileSystem ftpFs;
+    private final String relPath;
+
+    // Cached info
+    private FTPFile fileInfo;
+    private Map children;
+    private FileObject linkDestination;
+
+    private boolean inRefresh;
+
+    protected FtpFileObject(final FileName name,
+                            final FtpFileSystem fileSystem,
+                            final FileName rootName)
+        throws FileSystemException
+    {
+        super(name, fileSystem);
+        ftpFs = fileSystem;
+        String relPath = UriParser.decode(rootName.getRelativeName(name));
+        if (".".equals(relPath))
+        {
+            // do not use the "." as path against the ftp-server
+            // e.g. the uu.net ftp-server do a recursive listing then
+            // this.relPath = UriParser.decode(rootName.getPath());
+            // this.relPath = ".";
+            this.relPath = null;
+        }
+        else
+        {
+            this.relPath = relPath;
+        }
+    }
+
+    /**
+     * Called by child file objects, to locate their ftp file info.
+     *
+     * @param name  the filename in its native form ie. without uri stuff (%nn)
+     * @param flush recreate children cache
+     */
+    private FTPFile getChildFile(final String name, final boolean flush) throws IOException
+    {
+        /* If we should flush cached children, clear our children map unless
+                 * we're in the middle of a refresh in which case we've just recently
+                 * refreshed our children. No need to do it again when our children are
+                 * refresh()ed, calling getChildFile() for themselves from within
+                 * getInfo(). See getChildren(). */
+        if (flush && !inRefresh)
+        {
+            children = null;
+        }
+
+        // List the children of this file
+        doGetChildren();
+
+        // VFS-210
+        if (children == null)
+        {
+            return null;
+        }
+
+        // Look for the requested child
+        FTPFile ftpFile = (FTPFile) children.get(name);
+        return ftpFile;
+    }
+
+    /**
+     * Fetches the children of this file, if not already cached.
+     */
+    private void doGetChildren() throws IOException
+    {
+        if (children != null)
+        {
+            return;
+        }
+
+        final FtpClient client = ftpFs.getClient();
+        try
+        {
+            final String path = fileInfo != null && fileInfo.isSymbolicLink()
+                ? getFileSystem().getFileSystemManager().
+                    resolveName(getParent().getName(), fileInfo.getLink()).getPath()
+                : relPath;
+            final FTPFile[] tmpChildren = client.listFiles(path);
+            if (tmpChildren == null || tmpChildren.length == 0)
+            {
+                children = EMPTY_FTP_FILE_MAP;
+            }
+            else
+            {
+                children = new TreeMap();
+
+                // Remove '.' and '..' elements
+                for (int i = 0; i < tmpChildren.length; i++)
+                {
+                    final FTPFile child = tmpChildren[i];
+                    if (child == null)
+                    {
+                        if (log.isDebugEnabled())
+                        {
+                            log.debug(Messages.getString("vfs.provider.ftp/invalid-directory-entry.debug",
+                                new Object[]
+                                    {
+                                        new Integer(i), relPath
+                                    }));
+                        }
+                        continue;
+                    }
+                    if (!".".equals(child.getName())
+                        && !"..".equals(child.getName()))
+                    {
+                        children.put(child.getName(), child);
+                    }
+                }
+            }
+        }
+        finally
+        {
+            ftpFs.putClient(client);
+        }
+    }
+
+    /**
+     * Attaches this file object to its file resource.
+     */
+    protected void doAttach()
+        throws IOException
+    {
+        // Get the parent folder to find the info for this file
+        // VFS-210 getInfo(false);
+    }
+
+    /**
+     * Fetches the info for this file.
+     */
+    private void getInfo(boolean flush) throws IOException
+    {
+        final FtpFileObject parent = (FtpFileObject) FileObjectUtils.getAbstractFileObject(getParent());
+        FTPFile newFileInfo;
+        if (parent != null)
+        {
+            newFileInfo = parent.getChildFile(UriParser.decode(getName().getBaseName()), flush);
+        }
+        else
+        {
+            // Assume the root is a directory and exists
+            newFileInfo = new FTPFile();
+            newFileInfo.setType(FTPFile.DIRECTORY_TYPE);
+        }
+
+        if (newFileInfo == null)
+        {
+            this.fileInfo = UNKNOWN;
+        }
+        else
+        {
+            this.fileInfo = newFileInfo;
+        }
+    }
+
+    /**
+     * @throws FileSystemException if an error occurs.
+     */
+    public void refresh() throws FileSystemException
+    {
+        if (!inRefresh)
+        {
+            try
+            {
+                inRefresh = true;
+                super.refresh();
+
+                synchronized (getFileSystem())
+                {
+                    this.fileInfo = null;
+                }
+
+                /* VFS-210
+                try
+                {
+                    // this will tell the parent to recreate its children collection
+                    getInfo(true);
+                }
+                catch (IOException e)
+                {
+                    throw new FileSystemException(e);
+                }
+                */
+            }
+            finally
+            {
+                inRefresh = false;
+            }
+        }
+    }
+
+    /**
+     * Detaches this file object from its file resource.
+     */
+    protected void doDetach()
+    {
+        synchronized (getFileSystem())
+        {
+            this.fileInfo = null;
+            children = null;
+        }
+    }
+
+    /**
+     * Called when the children of this file change.
+     */
+    protected void onChildrenChanged(FileName child, FileType newType)
+    {
+        if (children != null && newType.equals(FileType.IMAGINARY))
+        {
+            try
+            {
+                children.remove(UriParser.decode(child.getBaseName()));
+            }
+            catch (FileSystemException e)
+            {
+                throw new RuntimeException(e.getMessage());
+            }
+        }
+        else
+        {
+            // if child was added we have to rescan the children
+            // TODO - get rid of this
+            children = null;
+        }
+    }
+
+    /**
+     * Called when the type or content of this file changes.
+     */
+    protected void onChange() throws IOException
+    {
+        children = null;
+
+        if (getType().equals(FileType.IMAGINARY))
+        {
+            // file is deleted, avoid server lookup
+            synchronized (getFileSystem())
+            {
+                this.fileInfo = UNKNOWN;
+            }
+            return;
+        }
+
+        getInfo(true);
+    }
+
+    /**
+     * Determines the type of the file, returns null if the file does not
+     * exist.
+     */
+    protected FileType doGetType()
+        throws Exception
+    {
+        // VFS-210
+        synchronized (getFileSystem())
+        {
+            if (this.fileInfo == null)
+            {
+                getInfo(false);
+            }
+
+            if (this.fileInfo == UNKNOWN)
+            {
+                return FileType.IMAGINARY;
+            }
+            else if (this.fileInfo.isDirectory())
+            {
+                return FileType.FOLDER;
+            }
+            else if (this.fileInfo.isFile())
+            {
+                return FileType.FILE;
+            }
+            else if (this.fileInfo.isSymbolicLink())
+            {
+                return getLinkDestination().getType();
+            }
+        }
+
+        throw new FileSystemException("vfs.provider.ftp/get-type.error", getName());
+    }
+
+    private FileObject getLinkDestination() throws FileSystemException
+    {
+        if (linkDestination == null)
+        {
+            final String path;
+            synchronized (getFileSystem())
+            {
+                path = this.fileInfo.getLink();
+            }
+            FileName relativeTo = getName().getParent();
+            if (relativeTo == null)
+            {
+                relativeTo = getName();
+            }
+            FileName linkDestinationName = getFileSystem().getFileSystemManager().resolveName(relativeTo, path);
+            linkDestination = getFileSystem().resolveFile(linkDestinationName);
+        }
+
+        return linkDestination;
+    }
+
+    protected FileObject[] doListChildrenResolved() throws Exception
+    {
+        synchronized (getFileSystem())
+        {
+            if (this.fileInfo != null && this.fileInfo.isSymbolicLink())
+            {
+                return getLinkDestination().getChildren();
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the file's list of children.
+     *
+     * @return The list of children
+     * @throws FileSystemException If there was a problem listing children
+     * @see AbstractFileObject#getChildren()
+     * @since 1.0
+     */
+    public FileObject[] getChildren() throws FileSystemException
+    {
+        try
+        {
+            if (doGetType() != FileType.FOLDER)
+            {
+                throw new FileNotFolderException(getName());
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new FileNotFolderException(getName(), ex);
+        }
+
+
+        try
+        {
+            /* Wrap our parent implementation, noting that we're refreshing so
+             * that we don't refresh() ourselves and each of our parents for
+             * each children. Note that refresh() will list children. Meaning,
+             * if if this file has C children, P parents, there will be (C * P)
+             * listings made with (C * (P + 1)) refreshes, when there should
+             * really only be 1 listing and C refreshes. */
+
+            this.inRefresh = true;
+            return super.getChildren();
+        }
+        finally
+        {
+            this.inRefresh = false;
+        }
+    }
+
+    /**
+     * Lists the children of the file.
+     */
+    protected String[] doListChildren()
+        throws Exception
+    {
+        // List the children of this file
+        doGetChildren();
+
+        // VFS-210
+        if (children == null)
+        {
+            return null;
+        }
+
+        // TODO - get rid of this children stuff
+        final String[] childNames = new String[children.size()];
+        int childNum = -1;
+        Iterator iterChildren = children.values().iterator();
+        while (iterChildren.hasNext())
+        {
+            childNum++;
+            final FTPFile child = (FTPFile) iterChildren.next();
+            childNames[childNum] = child.getName();
+        }
+
+        return UriParser.encode(childNames);
+    }
+
+    /**
+     * Deletes the file.
+     */
+    protected void doDelete() throws Exception
+    {
+        synchronized (getFileSystem())
+        {
+            final boolean ok;
+            final FtpClient ftpClient = ftpFs.getClient();
+            try
+            {
+                if (this.fileInfo.isDirectory())
+                {
+                    ok = ftpClient.removeDirectory(relPath);
+                }
+                else
+                {
+                    ok = ftpClient.deleteFile(relPath);
+                }
+            }
+            finally
+            {
+                ftpFs.putClient(ftpClient);
+            }
+
+            if (!ok)
+            {
+                throw new FileSystemException("vfs.provider.ftp/delete-file.error", getName());
+            }
+            this.fileInfo = null;
+            children = EMPTY_FTP_FILE_MAP;
+        }
+    }
+
+    /**
+     * Renames the file
+     */
+    protected void doRename(FileObject newfile) throws Exception
+    {
+        synchronized (getFileSystem())
+        {
+            final boolean ok;
+            final FtpClient ftpClient = ftpFs.getClient();
+            try
+            {
+                String oldName = getName().getPath();
+                String newName = newfile.getName().getPath();
+                ok = ftpClient.rename(oldName, newName);
+            }
+            finally
+            {
+                ftpFs.putClient(ftpClient);
+            }
+
+            if (!ok)
+            {
+                throw new FileSystemException("vfs.provider.ftp/rename-file.error",
+                        new Object[]{getName().toString(), newfile});
+            }
+            this.fileInfo = null;
+            children = EMPTY_FTP_FILE_MAP;
+        }
+    }
+
+    /**
+     * Creates this file as a folder.
+     */
+    protected void doCreateFolder()
+        throws Exception
+    {
+        final boolean ok;
+        final FtpClient client = ftpFs.getClient();
+        try
+        {
+            ok = client.makeDirectory(relPath);
+        }
+        finally
+        {
+            ftpFs.putClient(client);
+        }
+
+        if (!ok)
+        {
+            throw new FileSystemException("vfs.provider.ftp/create-folder.error", getName());
+        }
+    }
+
+    /**
+     * Returns the size of the file content (in bytes).
+     */
+    protected long doGetContentSize() throws Exception
+    {
+        synchronized (getFileSystem())
+        {
+            if (this.fileInfo.isSymbolicLink())
+            {
+                return getLinkDestination().getContent().getSize();
+            }
+            else
+            {
+                return this.fileInfo.getSize();
+            }
+        }
+    }
+
+    /**
+     * get the last modified time on an ftp file
+     *
+     * @see org.apache.commons.vfs.provider.AbstractFileObject#doGetLastModifiedTime()
+     */
+    protected long doGetLastModifiedTime() throws Exception
+    {
+        synchronized (getFileSystem())
+        {
+            if (this.fileInfo.isSymbolicLink())
+            {
+                return getLinkDestination().getContent().getLastModifiedTime();
+            }
+            else
+            {
+                Calendar timestamp = this.fileInfo.getTimestamp();
+                if (timestamp == null)
+                {
+                    return 0L;
+                }
+                else
+                {
+                    return (timestamp.getTime().getTime());
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates an input stream to read the file content from.
+     */
+    protected InputStream doGetInputStream() throws Exception
+    {
+        final FtpClient client = ftpFs.getClient();
+        try
+        {
+            final InputStream instr = client.retrieveFileStream(relPath);
+            // VFS-210
+            if (instr == null)
+            {
+                throw new FileNotFoundException(getName().toString());
+            }
+            return new FtpInputStream(client, instr);
+        }
+        catch (Exception e)
+        {
+            ftpFs.putClient(client);
+            throw e;
+        }
+    }
+
+    protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception
+    {
+        return new FtpRandomAccessContent(this, mode);
+    }
+
+    /**
+     * Creates an output stream to write the file content to.
+     */
+    protected OutputStream doGetOutputStream(boolean bAppend)
+        throws Exception
+    {
+        final FtpClient client = ftpFs.getClient();
+        try
+        {
+            OutputStream out = null;
+            if (bAppend)
+            {
+                out = client.appendFileStream(relPath);
+            }
+            else
+            {
+                out = client.storeFileStream(relPath);
+            }
+
+            if (out == null)
+            {
+                throw new FileSystemException("vfs.provider.ftp/output-error.debug", new Object[]
+                    {
+                        this.getName(),
+                        client.getReplyString()
+                    });
+            }
+
+            return new FtpOutputStream(client, out);
+        }
+        catch (Exception e)
+        {
+            ftpFs.putClient(client);
+            throw e;
+        }
+    }
+
+    String getRelPath()
+    {
+        return relPath;
+    }
+
+    FtpInputStream getInputStream(long filePointer) throws IOException
+    {
+        final FtpClient client = ftpFs.getClient();
+        try
+        {
+            final InputStream instr = client.retrieveFileStream(relPath, filePointer);
+            if (instr == null)
+            {
+                throw new FileSystemException("vfs.provider.ftp/input-error.debug", new Object[]
+                    {
+                        this.getName(),
+                        client.getReplyString()
+                    });
+            }
+            return new FtpInputStream(client, instr);
+        }
+        catch (IOException e)
+        {
+            ftpFs.putClient(client);
+            throw e;
+        }
+    }
+
+    /**
+     * An InputStream that monitors for end-of-file.
+     */
+    class FtpInputStream
+        extends MonitorInputStream
+    {
+        private final FtpClient client;
+
+        public FtpInputStream(final FtpClient client, final InputStream in)
+        {
+            super(in);
+            this.client = client;
+        }
+
+        void abort() throws IOException
+        {
+            client.abort();
+            close();
+        }
+
+        /**
+         * Called after the stream has been closed.
+         */
+        protected void onClose() throws IOException
+        {
+            final boolean ok;
+            try
+            {
+                ok = client.completePendingCommand();
+            }
+            finally
+            {
+                ftpFs.putClient(client);
+            }
+
+            if (!ok)
+            {
+                throw new FileSystemException("vfs.provider.ftp/finish-get.error", getName());
+            }
+        }
+    }
+
+    /**
+     * An OutputStream that monitors for end-of-file.
+     */
+    private class FtpOutputStream
+        extends MonitorOutputStream
+    {
+        private final FtpClient client;
+
+        public FtpOutputStream(final FtpClient client, final OutputStream outstr)
+        {
+            super(outstr);
+            this.client = client;
+        }
+
+        /**
+         * Called after this stream is closed.
+         */
+        protected void onClose() throws IOException
+        {
+            final boolean ok;
+            try
+            {
+                ok = client.completePendingCommand();
+            }
+            finally
+            {
+                ftpFs.putClient(client);
+            }
+
+            if (!ok)
+            {
+                throw new FileSystemException("vfs.provider.ftp/finish-put.error", getName());
+            }
+        }
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileProvider.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileProvider.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileProvider.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileProvider.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.vfs.Capability;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileSystemConfigBuilder;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.UserAuthenticationData;
+import org.apache.commons.vfs.provider.AbstractOriginatingFileProvider;
+import org.apache.commons.vfs.provider.GenericFileName;
+import org.apache.commons.vfs.provider.URLFileName;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.StringTokenizer;
+
+/**
+ * A provider for FTP file systems.
+ *
+ * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
+ * @version $Revision: 804644 $ $Date: 2009-08-16 13:32:15 +0530 (Sun, 16 Aug 2009) $
+ */
+public class FtpFileProvider
+        extends AbstractOriginatingFileProvider {
+    /**
+     * File Entry Parser.
+     */
+    public static final String ATTR_FILE_ENTRY_PARSER = "FEP";
+
+    /**
+     * Passive mode
+     */
+    public static final String PASSIVE_MODE = "vfs.passive";
+
+    /**
+     * Authenticator types.
+     */
+    public static final UserAuthenticationData.Type[] AUTHENTICATOR_TYPES = new UserAuthenticationData.Type[]
+            {
+                    UserAuthenticationData.USERNAME, UserAuthenticationData.PASSWORD
+            };
+
+    static final Collection capabilities = Collections.unmodifiableCollection(Arrays.asList(new Capability[]
+            {
+                    Capability.CREATE,
+                    Capability.DELETE,
+                    Capability.RENAME,
+                    Capability.GET_TYPE,
+                    Capability.LIST_CHILDREN,
+                    Capability.READ_CONTENT,
+                    Capability.GET_LAST_MODIFIED,
+                    Capability.URI,
+                    Capability.WRITE_CONTENT,
+                    Capability.APPEND_CONTENT,
+                    Capability.RANDOM_ACCESS_READ,
+            }));
+
+    public FtpFileProvider() {
+        super();
+        setFileNameParser(FtpFileNameParser.getInstance());
+    }
+
+    /**
+     * Creates the filesystem.
+     */
+    protected FileSystem doCreateFileSystem(final FileName name, final FileSystemOptions fileSystemOptions)
+            throws FileSystemException {
+        // Create the file system
+        //final GenericFileName rootName = (GenericFileName) name;
+        final URLFileName rootName = (URLFileName) name;
+
+
+        //FTPClientWrapper ftpClient = new FTPClientWrapper(rootName, fileSystemOptions);
+
+        String queryString = rootName.getQueryString();
+        FileSystemOptions opts = fileSystemOptions;
+        if (opts == null) {
+            opts = new FileSystemOptions();
+        }
+        if (queryString != null) {
+            FtpFileSystemConfigBuilder cfgBuilder = FtpFileSystemConfigBuilder.getInstance();
+            StringTokenizer st = new StringTokenizer(queryString, "?&!=");
+            while (st.hasMoreTokens()) {
+                if (PASSIVE_MODE.equalsIgnoreCase(st.nextToken()) &&
+                        st.hasMoreTokens() && "true".equalsIgnoreCase(st.nextToken())) {
+                    cfgBuilder.setPassiveMode(opts, true);
+                }
+            }
+        }
+        /*
+        FTPClient ftpClient = FtpClientFactory.createConnection(rootName.getHostName(),
+            rootName.getPort(),
+            rootName.getUserName(),
+            rootName.getPassword(),
+            rootName.getPath(),
+            fileSystemOptions);
+        */
+        FTPClientWrapper ftpClient = new FTPClientWrapper(rootName, opts);
+        return new FtpFileSystem(rootName, ftpClient, fileSystemOptions);
+    }
+
+    public FileSystemConfigBuilder getConfigBuilder() {
+        return FtpFileSystemConfigBuilder.getInstance();
+    }
+
+    public Collection getCapabilities() {
+        return capabilities;
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystem.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.VfsLog;
+import org.apache.commons.vfs.provider.AbstractFileSystem;
+import org.apache.commons.vfs.provider.GenericFileName;
+
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+ * An FTP file system.
+ *
+ * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
+ * @version $Revision: 993534 $ $Date: 2010-09-08 02:43:19 +0530 (Wed, 08 Sep 2010) $
+ */
+public class FtpFileSystem extends AbstractFileSystem
+{
+    private static final Log LOG = LogFactory.getLog(FtpFileSystem.class);
+
+//    private final String hostname;
+//    private final int port;
+//    private final String username;
+//    private final String password;
+
+    // An idle client
+    private FtpClient idleClient;
+
+    public FtpFileSystem(final GenericFileName rootName, final FtpClient ftpClient, final FileSystemOptions fileSystemOptions)
+    {
+        super(rootName, null, fileSystemOptions);
+        // hostname = rootName.getHostName();
+        // port = rootName.getPort();
+
+        idleClient = ftpClient;
+    }
+
+    protected void doCloseCommunicationLink()
+    {
+        // Clean up the connection
+        if (idleClient != null)
+        {
+            closeConnection(idleClient);
+            idleClient = null;
+        }
+    }
+
+    /**
+     * Adds the capabilities of this file system.
+     */
+    protected void addCapabilities(final Collection caps)
+    {
+        caps.addAll(FtpFileProvider.capabilities);
+    }
+
+    /**
+     * Cleans up the connection to the server.
+     */
+    private void closeConnection(final FtpClient client)
+    {
+        try
+        {
+            // Clean up
+            if (client.isConnected())
+            {
+                client.disconnect();
+            }
+        }
+        catch (final IOException e)
+        {
+            // getLogger().warn("vfs.provider.ftp/close-connection.error", e);
+            VfsLog.warn(getLogger(), LOG, "vfs.provider.ftp/close-connection.error", e);
+        }
+    }
+
+    /**
+     * Creates an FTP client to use.
+     * @return An FTPCleint.
+     * @throws FileSystemException if an error occurs.
+     */
+    public FtpClient getClient() throws FileSystemException
+    {
+        synchronized (this)
+            {
+                if (idleClient == null || !idleClient.isConnected())
+                {
+                    idleClient = null;
+
+                    return new FTPClientWrapper((GenericFileName) getRoot().getName(), getFileSystemOptions());
+                }
+                else
+                {
+                    final FtpClient client = idleClient;
+                    idleClient = null;
+                    return client;
+                }
+            }
+    }
+
+    /**
+     * Returns an FTP client after use.
+     * @param client The FTPClient.
+     */
+    public void putClient(final FtpClient client)
+    {
+        synchronized (this)
+            {
+                if (idleClient == null)
+                {
+                    // Hang on to client for later
+                    idleClient = client;
+                }
+                else
+                {
+                    // Close the client
+                    closeConnection(client);
+                }
+            }
+    }
+
+    /**
+     * Creates a file object.
+     */
+    protected FileObject createFile(final FileName name)
+        throws FileSystemException
+    {
+        return new FtpFileObject(name, this, getRootName());
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystemConfigBuilder.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystemConfigBuilder.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystemConfigBuilder.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpFileSystemConfigBuilder.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,309 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.net.ftp.parser.FTPFileEntryParserFactory;
+import org.apache.commons.vfs.FileSystemConfigBuilder;
+import org.apache.commons.vfs.FileSystemOptions;
+
+/**
+ * The config BUILDER for various ftp configuration options.
+ *
+ * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
+ * @version $Revision: 895278 $ $Date: 2010-01-03 01:32:29 +0530 (Sun, 03 Jan 2010) $
+ */
+public final class FtpFileSystemConfigBuilder extends FileSystemConfigBuilder
+{
+    private static final FtpFileSystemConfigBuilder BUILDER = new FtpFileSystemConfigBuilder();
+
+    private static final String FACTORY_KEY = FTPFileEntryParserFactory.class.getName() + ".KEY";
+    private static final String PASSIVE_MODE = FtpFileSystemConfigBuilder.class.getName() + ".PASSIVE";
+    private static final String USER_DIR_IS_ROOT = FtpFileSystemConfigBuilder.class.getName() + ".USER_DIR_IS_ROOT";
+    private static final String DATA_TIMEOUT = FtpFileSystemConfigBuilder.class.getName() + ".DATA_TIMEOUT";
+    private static final String SO_TIMEOUT = FtpFileSystemConfigBuilder.class.getName() + ".SO_TIMEOUT";
+
+    private static final String SERVER_LANGUAGE_CODE =
+            FtpFileSystemConfigBuilder.class.getName() + ".SERVER_LANGUAGE_CODE";
+    private static final String DEFAULT_DATE_FORMAT =
+            FtpFileSystemConfigBuilder.class.getName() + ".DEFAULT_DATE_FORMAT";
+    private static final String RECENT_DATE_FORMAT =
+            FtpFileSystemConfigBuilder.class.getName() + ".RECENT_DATE_FORMAT";
+    private static final String SERVER_TIME_ZONE_ID =
+            FtpFileSystemConfigBuilder.class.getName() + ".SERVER_TIME_ZONE_ID";
+    private static final String SHORT_MONTH_NAMES =
+            FtpFileSystemConfigBuilder.class.getName() + ".SHORT_MONTH_NAMES";
+
+    private FtpFileSystemConfigBuilder()
+    {
+        super("ftp.");
+    }
+
+    public static FtpFileSystemConfigBuilder getInstance()
+    {
+        return BUILDER;
+    }
+
+    /**
+     * FTPFileEntryParserFactory which will be used for ftp-entry parsing.
+     *
+     * @param opts The FileSystemOptions.
+     * @param factory instance of your factory
+     */
+    public void setEntryParserFactory(FileSystemOptions opts, FTPFileEntryParserFactory factory)
+    {
+        setParam(opts, FTPFileEntryParserFactory.class.getName(), factory);
+    }
+
+    /**
+     * @param opts The FlleSystemOptions.
+     * @see #setEntryParserFactory
+     * @return An FTPFileEntryParserFactory.
+     */
+    public FTPFileEntryParserFactory getEntryParserFactory(FileSystemOptions opts)
+    {
+        return (FTPFileEntryParserFactory) getParam(opts, FTPFileEntryParserFactory.class.getName());
+    }
+
+    /**
+     * set the FQCN of your FileEntryParser used to parse the directory listing from your server.<br />
+     * <br />
+     * <i>If you do not use the default commons-net FTPFileEntryParserFactory e.g. by using
+     * {@link #setEntryParserFactory}
+     * this is the "key" parameter passed as argument into your custom factory</i>
+     *
+     * @param opts The FileSystemOptions.
+     * @param key The key.
+     */
+    public void setEntryParser(FileSystemOptions opts, String key)
+    {
+        setParam(opts, FACTORY_KEY, key);
+    }
+
+    /**
+     * @param opts The FileSystemOptions.
+     * @see #setEntryParser
+     * @return the key to the EntryParser.
+     */
+    public String getEntryParser(FileSystemOptions opts)
+    {
+        return getString(opts, FACTORY_KEY);
+    }
+
+    protected Class getConfigClass()
+    {
+        return FtpFileSystem.class;
+    }
+
+    /**
+     * enter into passive mode.
+     *
+     * @param opts The FileSystemOptions.
+     * @param passiveMode true if passive mode should be used.
+     */
+    public void setPassiveMode(FileSystemOptions opts, boolean passiveMode)
+    {
+        setParam(opts, PASSIVE_MODE, passiveMode ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /**
+     * @param opts The FileSystemOptions.
+     * @return true if passive mode is set.
+     * @see #setPassiveMode
+     */
+    public Boolean getPassiveMode(FileSystemOptions opts)
+    {
+        return getBoolean(opts, PASSIVE_MODE);
+    }
+
+    /**
+     * use user directory as root (do not change to fs root).
+     *
+     * @param opts The FileSystemOptions.
+     * @param userDirIsRoot true if the user directory should be treated as the root.
+     */
+    public void setUserDirIsRoot(FileSystemOptions opts, boolean userDirIsRoot)
+    {
+        setParam(opts, USER_DIR_IS_ROOT, userDirIsRoot ? Boolean.TRUE : Boolean.FALSE);
+    }
+
+    /**
+     * @param opts The FileSystemOptions.
+     * @return true if the user directory is treated as the root.
+     * @see #setUserDirIsRoot
+     */
+    public Boolean getUserDirIsRoot(FileSystemOptions opts)
+    {
+        return getBoolean(opts, USER_DIR_IS_ROOT);
+    }
+
+    /**
+     * @param opts The FileSystemOptions.
+     * @return The timeout as an Integer.
+     * @see #setDataTimeout
+     */
+    public Integer getDataTimeout(FileSystemOptions opts)
+    {
+        return getInteger(opts, DATA_TIMEOUT);
+    }
+
+    /**
+     * set the data timeout for the ftp client.<br />
+     * If you set the dataTimeout to <code>null</code> no dataTimeout will be set on the
+     * ftp client.
+     *
+     * @param opts The FileSystemOptions.
+     * @param dataTimeout The timeout value.
+     */
+    public void setDataTimeout(FileSystemOptions opts, Integer dataTimeout)
+    {
+        setParam(opts, DATA_TIMEOUT, dataTimeout);
+    }
+
+    /**
+     * @param opts The FileSystem options.
+     * @return The timeout value.
+     * @see #getDataTimeout
+     */
+    public Integer getSoTimeout(FileSystemOptions opts)
+    {
+        return (Integer) getParam(opts, SO_TIMEOUT);
+    }
+
+    /**
+     * set the socket timeout for the ftp client.<br />
+     * If you set the socketTimeout to <code>null</code> no socketTimeout will be set on the
+     * ftp client.
+     *
+     * @param opts The FileSystem options.
+     * @param soTimeout The timeout value.
+     */
+    public void setSoTimeout(FileSystemOptions opts, Integer soTimeout)
+    {
+        setParam(opts, SO_TIMEOUT, soTimeout);
+    }
+
+    /**
+     * get the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
+     * for details and examples.
+     * @param opts The FilesystemOptions.
+     * @return The language code of the server.
+     */
+    public String getServerLanguageCode(FileSystemOptions opts)
+    {
+        return getString(opts, SERVER_LANGUAGE_CODE);
+    }
+
+    /**
+     * set the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
+     * for details and examples.
+     * @param opts The FileSystemOptions.
+     * @param serverLanguageCode The servers language code.
+     */
+    public void setServerLanguageCode(FileSystemOptions opts, String serverLanguageCode)
+    {
+        setParam(opts, SERVER_LANGUAGE_CODE, serverLanguageCode);
+    }
+
+    /**
+     * get the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
+     * for details and examples.
+     * @param opts The FileSystemOptions
+     * @return The default date format.
+     */
+    public String getDefaultDateFormat(FileSystemOptions opts)
+    {
+        return getString(opts, DEFAULT_DATE_FORMAT);
+    }
+
+    /**
+     * set the language code used by the server. see {@link org.apache.commons.net.ftp.FTPClientConfig}
+     * for details and examples.
+     * @param opts The FileSystemOptions.
+     * @param defaultDateFormat The default date format.
+     */
+    public void setDefaultDateFormat(FileSystemOptions opts, String defaultDateFormat)
+    {
+        setParam(opts, DEFAULT_DATE_FORMAT, defaultDateFormat);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @return The recent date format.
+     */
+    public String getRecentDateFormat(FileSystemOptions opts)
+    {
+        return getString(opts, RECENT_DATE_FORMAT);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @param recentDateFormat The recent date format.
+     */
+    public void setRecentDateFormat(FileSystemOptions opts, String recentDateFormat)
+    {
+        setParam(opts, RECENT_DATE_FORMAT, recentDateFormat);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @return The server timezone id.
+     */
+    public String getServerTimeZoneId(FileSystemOptions opts)
+    {
+        return getString(opts, SERVER_TIME_ZONE_ID);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @param serverTimeZoneId The server timezone id.
+     */
+    public void setServerTimeZoneId(FileSystemOptions opts, String serverTimeZoneId)
+    {
+        setParam(opts, SERVER_TIME_ZONE_ID, serverTimeZoneId);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @return An array of short month names.
+     */
+    public String[] getShortMonthNames(FileSystemOptions opts)
+    {
+        return (String[]) getParam(opts, SHORT_MONTH_NAMES);
+    }
+
+    /**
+     * see {@link org.apache.commons.net.ftp.FTPClientConfig} for details and examples.
+     * @param opts The FileSystemOptions.
+     * @param shortMonthNames an array of short month name Strings.
+     */
+    public void setShortMonthNames(FileSystemOptions opts, String[] shortMonthNames)
+    {
+        String[] clone = null;
+        if (shortMonthNames != null)
+        {
+            clone = new String[shortMonthNames.length];
+            System.arraycopy(shortMonthNames, 0, clone, 0, shortMonthNames.length);
+        }
+
+        setParam(opts, SHORT_MONTH_NAMES, clone);
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpRandomAccessContent.java
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpRandomAccessContent.java?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpRandomAccessContent.java (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/FtpRandomAccessContent.java Thu Sep 23 06:04:21 2010
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs.provider.ftp;
+
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.provider.AbstractRandomAccessStreamContent;
+import org.apache.commons.vfs.util.RandomAccessMode;
+
+import java.io.DataInputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
+
+/**
+ * @author <a href="http://commons.apache.org/vfs/team-list.html">Commons VFS team</a>
+ */
+class FtpRandomAccessContent extends AbstractRandomAccessStreamContent
+{
+    protected long filePointer;
+
+    private final FtpFileObject fileObject;
+    private DataInputStream dis;
+    private FtpFileObject.FtpInputStream mis;
+
+    FtpRandomAccessContent(final FtpFileObject fileObject, RandomAccessMode mode)
+    {
+        super(mode);
+
+        this.fileObject = fileObject;
+        // fileSystem = (FtpFileSystem) this.fileObject.getFileSystem();
+    }
+
+    public long getFilePointer() throws IOException
+    {
+        return filePointer;
+    }
+
+    public void seek(long pos) throws IOException
+    {
+        if (pos == filePointer)
+        {
+            // no change
+            return;
+        }
+
+        if (pos < 0)
+        {
+            throw new FileSystemException("vfs.provider/random-access-invalid-position.error",
+                new Object[]
+                {
+                    new Long(pos)
+                });
+        }
+        if (dis != null)
+        {
+            close();
+        }
+
+        filePointer = pos;
+    }
+
+    protected DataInputStream getDataInputStream() throws IOException
+    {
+        if (dis != null)
+        {
+            return dis;
+        }
+
+        // FtpClient client = fileSystem.getClient();
+        mis = fileObject.getInputStream(filePointer);
+        dis = new DataInputStream(new FilterInputStream(mis)
+        {
+            public int read() throws IOException
+            {
+                int ret = super.read();
+                if (ret > -1)
+                {
+                    filePointer++;
+                }
+                return ret;
+            }
+
+            public int read(byte[] b) throws IOException
+            {
+                int ret = super.read(b);
+                if (ret > -1)
+                {
+                    filePointer += ret;
+                }
+                return ret;
+            }
+
+            public int read(byte[] b, int off, int len) throws IOException
+            {
+                int ret = super.read(b, off, len);
+                if (ret > -1)
+                {
+                    filePointer += ret;
+                }
+                return ret;
+            }
+
+            public void close() throws IOException
+            {
+                FtpRandomAccessContent.this.close();
+            }
+        });
+
+        return dis;
+    }
+
+
+    public void close() throws IOException
+    {
+        if (dis != null)
+        {
+            mis.abort();
+
+            // this is to avoid recursive close
+            DataInputStream oldDis = dis;
+            dis = null;
+            oldDis.close();
+            mis = null;
+        }
+    }
+
+    public long length() throws IOException
+    {
+        return fileObject.getContent().getSize();
+    }
+}

Added: synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/package.html
URL: http://svn.apache.org/viewvc/synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/package.html?rev=1000332&view=auto
==============================================================================
--- synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/package.html (added)
+++ synapse/branches/commons-vfs-2-synapse-2.0/core/src/main/java/org/apache/commons/vfs/provider/ftp/package.html Thu Sep 23 06:04:21 2010
@@ -0,0 +1,19 @@
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+   
+         http://www.apache.org/licenses/LICENSE-2.0
+   
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<body>
+<p>The FTP File Provider.</p>
+</body>
\ No newline at end of file