You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ad...@apache.org on 2002/10/25 05:59:10 UTC
cvs commit: jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test AbstractWritableFileSystemTestCase.java
adammurdoch 2002/10/24 20:59:10
Modified: vfs/src/java/org/apache/commons/vfs FileObject.java
FileSystem.java Resources.properties
vfs/src/java/org/apache/commons/vfs/provider
AbstractFileObject.java AbstractFileSystem.java
vfs/src/java/org/apache/commons/vfs/provider/ftp
FtpFileObject.java
vfs/src/java/org/apache/commons/vfs/tasks
AbstractSyncTask.java MkdirTask.java
vfs/src/test/org/apache/commons/vfs/test
AbstractWritableFileSystemTestCase.java
Added: vfs/src/java/org/apache/commons/vfs FileChangeEvent.java
FileListener.java
Log:
- Added initial support for file listeners:
- Added FileSystem.addListener() and removeListener().
- FileObject:
- Added delete() convenience method.
- Split create( type ) into createFolder() and createFile().
- AbstractFileObject:
- Added detach(), which allows a subclass to force cached state to be
invalidated.
- No longer detaches when the file is created, deleted, or the content
changes. It is now the subclass' responsibility to explicitly detach
if it needs to.
Revision Changes Path
1.9 +31 -11 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileObject.java
Index: FileObject.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileObject.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -r1.8 -r1.9
--- FileObject.java 23 Oct 2002 13:09:45 -0000 1.8
+++ FileObject.java 25 Oct 2002 03:59:09 -0000 1.9
@@ -84,11 +84,11 @@
*
* <h4>Creating and Deleting a File</h4>
*
- * <p>A file is created using either {@link #create}, or by writing to the
- * file using one of the {@link FileContent} methods.
+ * <p>A file is created using either {@link #createFolder}, {@link #create},
+ * or by writing to the file using one of the {@link FileContent} methods.
*
- * <p>A file is deleted using {@link #delete}. Deletion is recursive, so
- * that when a folder is deleted, so are all its child files.
+ * <p>A file is deleted using {@link #delete}. Recursive deletion can be
+ * done using {@link #delete(FileSelector)}.
*
* <h4>Finding Files</h4>
*
@@ -261,8 +261,19 @@
List findFiles( FileSelector selector ) throws FileSystemException;
/**
- * Deletes this file, and all descendents. Does nothing if the file
- * does not exist.
+ * Deletes this file. Does nothing if this file does not exist. Does
+ * not delete any descendents of this file, use {@link #delete(FileSelector)}
+ * for that.
+ *
+ * @throws FileSystemException
+ * If this file is a non-empty folder, or if this file is read-only,
+ * or on error deleteing this file.
+ */
+ void delete() throws FileSystemException;
+
+ /**
+ * Deletes all descendents of this file that match a selector. Does
+ * nothing if this file does not exist.
*
* <p>This method is not transactional. If it fails and throws an
* exception, this file will potentially only be partially deleted.
@@ -276,19 +287,28 @@
void delete( FileSelector selector ) throws FileSystemException;
/**
+ * Creates this folder, if it does not exist. Also creates any ancestor
+ * folders which do not exist. This method does nothing if the folder
+ * already exists.
+ *
+ * @throws FileSystemException
+ * If the folder already exists with the wrong type, or the parent
+ * folder is read-only, or on error creating this folder or one of
+ * its ancestors.
+ */
+ void createFolder() throws FileSystemException;
+
+ /**
* Creates this file, if it does not exist. Also creates any ancestor
* folders which do not exist. This method does nothing if the file
- * already exists with the requested type.
- *
- * @param type
- * The type of file to create.
+ * already exists and is a file.
*
* @throws FileSystemException
* If the file already exists with the wrong type, or the parent
* folder is read-only, or on error creating this file or one of
* its ancestors.
*/
- void create( FileType type ) throws FileSystemException;
+ void createFile() throws FileSystemException;
/**
* Copies another file, and all its descendents, to this file.
1.5 +17 -1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileSystem.java
Index: FileSystem.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileSystem.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- FileSystem.java 23 Oct 2002 11:59:39 -0000 1.4
+++ FileSystem.java 25 Oct 2002 03:59:09 -0000 1.5
@@ -136,4 +136,20 @@
* @return The file. Never returns null.
*/
FileObject resolveFile( String name ) throws FileSystemException;
+
+ /**
+ * Adds a listener on a file in this file system.
+ *
+ * @param file The file to attach the listener to.
+ * @param listener The listener to add.
+ */
+ void addListener( FileObject file, FileListener listener );
+
+ /**
+ * Removes a listener from a file in this file system.
+ *
+ * @param file The file to remove the listener from.
+ * @param listener The listener to remove.
+ */
+ void removeListener( FileObject file, FileListener listener );
}
1.7 +7 -5 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/Resources.properties
Index: Resources.properties
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/Resources.properties,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- Resources.properties 24 Oct 2002 02:11:03 -0000 1.6
+++ Resources.properties 25 Oct 2002 03:59:09 -0000 1.7
@@ -3,10 +3,10 @@
# AbstractFileObject
vfs.provider/delete-not-supported.error=This file type does not support delete.
-vfs.provider/create-folder-not-supported.error=this file type does not support folder creation.
-vfs.provider/get-last-modified-not-supported.error=this file type does not support retriving last modified time.
-vfs.provider/set-last-modified-not-supported.error=this file type does not support setting last modified time.
-vfs.provider/set-attribute-not-supported.error=this file type does not support setting attributes.
+vfs.provider/create-folder-not-supported.error=This file type does not support folder creation.
+vfs.provider/get-last-modified-not-supported.error=This file type does not support retriving last modified time.
+vfs.provider/set-last-modified-not-supported.error=This file type does not support setting last modified time.
+vfs.provider/set-attribute-not-supported.error=This file type does not support setting attributes.
vfs.provider/write-not-supported.error=This file type cannot be written to.
vfs.provider/get-type-no-exist.error=Could not determine the type of file "{0}" because it does not exist.
vfs.provider/get-type.error=Could not determine the type of file "{0}".
@@ -17,7 +17,8 @@
vfs.provider/delete.error=Could not delete "{0}".
vfs.provider/create-mismatched-type.error=Could not create {0} "{1}" because it already exists and is a {2}.
vfs.provider/create-read-only.error=Could not create {0} "{1}" because the file system is read-only.
-vfs.provider/create.error=Could not create {0} "{1}".
+vfs.provider/create-folder.error=Could not create folder "{1}".
+vfs.provider/create-file.error=Could not create file "{1}".
vfs.provider/write-read-only.error=Could not write to "{0}" because it is read-only.
vfs.provider/write-folder.error=Could not write to "{0}" because it is a folder.
vfs.provider/write-in-use.error=Could not write to "{0}" because it is already in use.
@@ -117,3 +118,4 @@
vfs.tasks/sync.src-file-no-exist.warn=Source file "{0}" does not exist.
vfs.tasks/sync.duplicate-source-files.warn=Multiple source files for destination file "{0}".
vfs.tasks/delete.no-source-files.error=No files to delete specified.
+vfs.tasks/mkdir.create-folder.info=Creating directory "{0}".
\ No newline at end of file
1.1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileChangeEvent.java
Index: FileChangeEvent.java
===================================================================
/* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.vfs;
/**
* An event fired when a file is changed.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/10/25 03:59:09 $
*/
public class FileChangeEvent
{
private final FileObject file;
public FileChangeEvent( final FileObject file )
{
this.file = file;
}
/**
* Returns the file that changed.
*/
public FileObject getFile()
{
return file;
}
}
1.1 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileListener.java
Index: FileListener.java
===================================================================
/* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.commons.vfs;
/**
* Listens for changes to a file.
*
* @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
* @version $Revision: 1.1 $ $Date: 2002/10/25 03:59:09 $
*/
public interface FileListener
{
/**
* Called when a file is created.
*/
void fileCreated( FileChangeEvent event );
/**
* Called when a file is deleted.
*/
void fileDeleted( FileChangeEvent event );
}
1.14 +122 -86 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java
Index: AbstractFileObject.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileObject.java,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- AbstractFileObject.java 23 Oct 2002 11:59:40 -0000 1.13
+++ AbstractFileObject.java 25 Oct 2002 03:59:09 -0000 1.14
@@ -66,7 +66,6 @@
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.vfs.Selectors;
import org.apache.commons.vfs.FileContent;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
@@ -75,6 +74,7 @@
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
import org.apache.commons.vfs.NameScope;
+import org.apache.commons.vfs.Selectors;
/**
* A partial file object implementation.
@@ -433,6 +433,7 @@
{
if ( fs.getParentLayer() != null )
{
+ // Return the parent of the parent layer
return fs.getParentLayer().getParent();
}
else
@@ -554,7 +555,7 @@
*/
private void deleteSelf() throws FileSystemException
{
- if ( exists() && !isWriteable() )
+ if ( !isWriteable() )
{
throw new FileSystemException( "vfs.provider/delete-read-only.error", name );
}
@@ -574,7 +575,17 @@
}
// Update cached info
- updateType();
+ handleDelete();
+ }
+
+ /**
+ * Deletes this file.
+ *
+ * @todo This will not fail if this is a non-empty folder.
+ */
+ public void delete() throws FileSystemException
+ {
+ delete( Selectors.SELECT_SELF );
}
/**
@@ -603,6 +614,7 @@
// If the file is a folder, make sure all its children have been deleted
if ( file.type == FileType.FOLDER && file.getChildren().length != 0 )
{
+ // TODO - fail??
// Skip
continue;
}
@@ -613,13 +625,33 @@
}
/**
- * Creates this file, if it does not exist. Also creates any ancestor
+ * Creates this file, if it does not exist.
+ */
+ public void createFile() throws FileSystemException
+ {
+ try
+ {
+ getOutputStream().close();
+ endOutput();
+ }
+ catch ( final RuntimeException re )
+ {
+ throw re;
+ }
+ catch ( final Exception e )
+ {
+ throw new FileSystemException( "vfs.provider/create-file.error", name, e );
+ }
+ }
+
+ /**
+ * Creates this folder, if it does not exist. Also creates any ancestor
* files which do not exist.
*/
- public void create( FileType type ) throws FileSystemException
+ public void createFolder() throws FileSystemException
{
attach();
- if ( this.type == type )
+ if ( this.type == FileType.FOLDER )
{
// Already exists as correct type
return;
@@ -637,35 +669,25 @@
FileObject parent = getParent();
if ( parent != null )
{
- parent.create( FileType.FOLDER );
+ parent.createFolder();
}
// Create the folder
try
{
- if ( type == FileType.FOLDER )
- {
- doCreateFolder();
- children = EMPTY_FILE_ARRAY;
- }
- else if ( type == FileType.FILE )
- {
- OutputStream outStr = doGetOutputStream();
- outStr.close();
- endOutput();
- }
+ doCreateFolder();
}
- catch ( RuntimeException re )
+ catch ( final RuntimeException re )
{
throw re;
}
- catch ( Exception exc )
+ catch ( final Exception exc )
{
- throw new FileSystemException( "vfs.provider/create.error", new Object[]{type, name}, exc );
+ throw new FileSystemException( "vfs.provider/create-folder.error", name, exc );
}
// Update cached info
- updateType();
+ handleCreate( FileType.FOLDER );
}
/**
@@ -713,7 +735,7 @@
}
else
{
- destFile.create( FileType.FOLDER );
+ destFile.createFolder();
}
}
}
@@ -750,19 +772,31 @@
final FileObject destFile )
throws FileSystemException
{
- InputStream instr = null;
- OutputStream outstr = null;
try
{
- instr = srcFile.getContent().getInputStream();
- // Create the output stream via getContent(), to pick up the
- // validation it does
- outstr = destFile.getContent().getOutputStream();
- final byte[] buffer = new byte[ 1024 * 4 ];
- int n = 0;
- while ( -1 != ( n = instr.read( buffer ) ) )
+ final InputStream instr = srcFile.getContent().getInputStream();
+ try
+ {
+ // Create the output stream via getContent(), to pick up the
+ // validation it does
+ final OutputStream outstr = destFile.getContent().getOutputStream();
+ try
+ {
+ final byte[] buffer = new byte[ 1024 * 4 ];
+ int n = 0;
+ while ( -1 != ( n = instr.read( buffer ) ) )
+ {
+ outstr.write( buffer, 0, n );
+ }
+ }
+ finally
+ {
+ outstr.close();
+ }
+ }
+ finally
{
- outstr.write( buffer, 0, n );
+ instr.close();
}
}
catch ( RuntimeException re )
@@ -773,31 +807,6 @@
{
throw new FileSystemException( "vfs.provider/copy-file.error", new Object[]{srcFile, destFile}, exc );
}
- finally
- {
- if ( instr != null )
- {
- try
- {
- instr.close();
- }
- catch ( final Exception exc )
- {
- //ignore
- }
- }
- if ( outstr != null )
- {
- try
- {
- outstr.close();
- }
- catch ( final Exception exc )
- {
- //ignore
- }
- }
- }
}
/**
@@ -842,13 +851,7 @@
}
// Detach from the file
- if ( attached )
- {
- doDetach();
- attached = false;
- type = null;
- children = null;
- }
+ detach();
if ( exc != null )
{
@@ -879,7 +882,7 @@
FileObject parent = getParent();
if ( parent != null )
{
- parent.create( FileType.FOLDER );
+ parent.createFolder();
}
}
@@ -888,10 +891,6 @@
{
return doGetOutputStream();
}
- catch ( FileSystemException exc )
- {
- throw exc;
- }
catch ( RuntimeException re )
{
throw re;
@@ -903,6 +902,21 @@
}
/**
+ * Detaches this file, invaliating all cached info. This will force
+ * a call to {@link #doAttach} next time this file is used.
+ */
+ protected void detach()
+ {
+ if ( attached )
+ {
+ doDetach();
+ attached = false;
+ type = null;
+ children = null;
+ }
+ }
+
+ /**
* Attaches to the file.
*/
private void attach() throws FileSystemException
@@ -919,10 +933,6 @@
attached = true;
type = doGetType();
}
- catch ( FileSystemException exc )
- {
- throw exc;
- }
catch ( RuntimeException re )
{
throw re;
@@ -931,31 +941,56 @@
{
throw new FileSystemException( "vfs.provider/get-type.error", new Object[]{name}, exc );
}
-
}
/**
* Called when the ouput stream for this file is closed.
*/
- public void endOutput() throws Exception
+ protected void endOutput() throws Exception
{
- updateType();
+ boolean newFile = ( type == null );
+
doEndOutput();
+
+ if ( newFile )
+ {
+ // File was created
+ handleCreate( FileType.FILE );
+ }
}
/**
- * Update cached info when this file's type changes.
+ * Called when this file is created. Updates cached info and notifies
+ * the parent and file system.
*/
- private void updateType()
+ private void handleCreate( final FileType newType )
{
+ // Fix up state
+ type = newType;
+ children = EMPTY_FILE_ARRAY;
+
// Notify parent that its child list may no longer be valid
notifyParent();
- // Detach
- doDetach();
- attached = false;
+ // Notify the file system
+ fs.fireFileCreated( this );
+ }
+
+ /**
+ * Called when this file is deleted. Updates cached info and notifies
+ * subclasses, parent and file system.
+ */
+ private void handleDelete()
+ {
+ // Fix up state
type = null;
children = null;
+
+ // Notify parent that its child list may no longer be valid
+ notifyParent();
+
+ // Notify the file system
+ fs.fireFileDeleted( this );
}
/**
@@ -978,6 +1013,7 @@
/**
* Notifies a file that children have been created or deleted.
+ * @todo Indicate whether the child was added or removed, and which child.
*/
private void invalidateChildren()
{
@@ -1014,10 +1050,10 @@
/**
* Traverses a file.
*/
- private void traverse( final DefaultFileSelectorInfo fileInfo,
- final FileSelector selector,
- final boolean depthwise,
- final List selected )
+ private static void traverse( final DefaultFileSelectorInfo fileInfo,
+ final FileSelector selector,
+ final boolean depthwise,
+ final List selected )
throws Exception
{
// Check the file itself
1.11 +72 -2 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java
Index: AbstractFileSystem.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/AbstractFileSystem.java,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- AbstractFileSystem.java 23 Oct 2002 11:59:40 -0000 1.10
+++ AbstractFileSystem.java 25 Oct 2002 03:59:09 -0000 1.11
@@ -57,10 +57,13 @@
import java.util.HashMap;
import java.util.Map;
+import java.util.ArrayList;
import org.apache.commons.vfs.FileName;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileListener;
+import org.apache.commons.vfs.FileChangeEvent;
/**
* A partial {@link org.apache.commons.vfs.FileSystem} implementation.
@@ -79,6 +82,9 @@
/** Map from FileName to FileObject. */
private final Map files = new HashMap();
+ /** Map from FileName to an ArrayList of listeners for that file. */
+ private final Map listenerMap = new HashMap();
+
protected AbstractFileSystem( final FileName rootName,
final FileObject parentLayer )
{
@@ -119,7 +125,7 @@
* Retrieves the attribute with the specified name. The default
* implementation simply throws an exception.
*/
- public Object getAttribute( String attrName ) throws FileSystemException
+ public Object getAttribute( final String attrName ) throws FileSystemException
{
throw new FileSystemException( "vfs.provider/get-attribute-not-supported.error" );
}
@@ -128,7 +134,7 @@
* Sets the attribute with the specified name. The default
* implementation simply throws an exception.
*/
- public void setAttribute( String attrName, Object value )
+ public void setAttribute( final String attrName, final Object value )
throws FileSystemException
{
throw new FileSystemException( "vfs.provider/set-attribute-not-supported.error" );
@@ -177,5 +183,69 @@
files.put( name, file );
}
return file;
+ }
+
+ /**
+ * Adds a listener on a file in this file system.
+ */
+ public void addListener( final FileObject file,
+ final FileListener listener )
+ {
+ ArrayList listeners = (ArrayList)listenerMap.get( file.getName() );
+ if ( listeners == null )
+ {
+ listeners = new ArrayList();
+ listenerMap.put( file.getName(), listeners );
+ }
+ listeners.add( listener );
+ }
+
+ /**
+ * Removes a listener from a file in this file system.
+ */
+ public void removeListener( final FileObject file,
+ final FileListener listener )
+ {
+ final ArrayList listeners = (ArrayList)listenerMap.get( file.getName() );
+ if ( listeners != null )
+ {
+ listeners.remove( listener );
+ }
+ }
+
+ /**
+ * Fires a file create event.
+ */
+ protected void fireFileCreated( final FileObject file )
+ {
+ final FileChangeEvent event = new FileChangeEvent( file );
+ final ArrayList listeners = (ArrayList)listenerMap.get( file.getName() );
+ if ( listeners != null )
+ {
+ final int count = listeners.size();
+ for ( int i = 0; i < count; i++ )
+ {
+ final FileListener listener = (FileListener)listeners.get( i );
+ listener.fileCreated( event );
+ }
+ }
+ }
+
+ /**
+ * Fires a file delete event.
+ */
+ protected void fireFileDeleted( final FileObject file )
+ {
+ final FileChangeEvent event = new FileChangeEvent( file );
+ final ArrayList listeners = (ArrayList)listenerMap.get( file.getName() );
+ if ( listeners != null )
+ {
+ final int count = listeners.size();
+ for ( int i = 0; i < count; i++ )
+ {
+ final FileListener listener = (FileListener)listeners.get( i );
+ listener.fileDeleted( event );
+ }
+ }
}
}
1.8 +4 -0 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java
Index: FtpFileObject.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/ftp/FtpFileObject.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- FtpFileObject.java 23 Oct 2002 11:59:41 -0000 1.7
+++ FtpFileObject.java 25 Oct 2002 03:59:09 -0000 1.8
@@ -218,6 +218,8 @@
{
throw new FileSystemException( "vfs.provider.ftp/delete-file.error", getName() );
}
+ fileInfo = null;
+ children = EMPTY_FTP_FILE_ARRAY;
}
/**
@@ -230,6 +232,7 @@
{
throw new FileSystemException( "vfs.provider.ftp/create-folder.error", getName() );
}
+ detach();
}
/**
@@ -279,5 +282,6 @@
{
throw new FileSystemException( "vfs.provider.ftp/finish-put.error", getName() );
}
+ detach();
}
}
1.4 +2 -2 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/tasks/AbstractSyncTask.java
Index: AbstractSyncTask.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/tasks/AbstractSyncTask.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AbstractSyncTask.java 24 Oct 2002 02:11:03 -0000 1.3
+++ AbstractSyncTask.java 25 Oct 2002 03:59:10 -0000 1.4
@@ -191,7 +191,7 @@
{
// Locate the destination folder, and make sure it exists
final FileObject destFolder = resolveFile( destDirUrl );
- destFolder.create( FileType.FOLDER );
+ destFolder.createFolder();
// Locate the source files, and make sure they exist
final ArrayList srcs = new ArrayList();
1.2 +4 -2 jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/tasks/MkdirTask.java
Index: MkdirTask.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/tasks/MkdirTask.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MkdirTask.java 24 Oct 2002 02:11:03 -0000 1.1
+++ MkdirTask.java 25 Oct 2002 03:59:10 -0000 1.2
@@ -95,7 +95,9 @@
try
{
final FileObject dir = resolveFile( dirName );
- dir.create( FileType.FOLDER );
+ final String message = Messages.getString( "vfs.tasks/mkdir.create-folder.info", dir );
+ log( message );
+ dir.createFolder();
}
catch ( final FileSystemException e )
{
1.4 +150 -20 jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/AbstractWritableFileSystemTestCase.java
Index: AbstractWritableFileSystemTestCase.java
===================================================================
RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/AbstractWritableFileSystemTestCase.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AbstractWritableFileSystemTestCase.java 23 Oct 2002 11:59:39 -0000 1.3
+++ AbstractWritableFileSystemTestCase.java 25 Oct 2002 03:59:10 -0000 1.4
@@ -58,10 +58,14 @@
import java.io.OutputStream;
import java.util.HashSet;
import java.util.Set;
+import java.util.ArrayList;
import org.apache.commons.vfs.Selectors;
import org.apache.commons.vfs.FileObject;
import org.apache.commons.vfs.FileSystemException;
import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileListener;
+import org.apache.commons.vfs.FileChangeEvent;
/**
* File system test that check that a file system can be modified.
@@ -90,7 +94,7 @@
// Make sure the test folder is empty
scratchFolder.delete( Selectors.EXCLUDE_SELF );
- scratchFolder.create( FileType.FOLDER );
+ scratchFolder.createFolder();
return scratchFolder;
}
@@ -105,7 +109,7 @@
// Create direct child of the test folder
FileObject folder = scratchFolder.resolveFile( "dir1" );
assertTrue( !folder.exists() );
- folder.create( FileType.FOLDER );
+ folder.createFolder();
assertTrue( folder.exists() );
assertSame( FileType.FOLDER, folder.getType() );
assertEquals( 0, folder.getChildren().length );
@@ -115,7 +119,7 @@
assertTrue( !folder.exists() );
assertTrue( !folder.getParent().exists() );
assertTrue( !folder.getParent().getParent().exists() );
- folder.create( FileType.FOLDER );
+ folder.createFolder();
assertTrue( folder.exists() );
assertSame( FileType.FOLDER, folder.getType() );
assertEquals( 0, folder.getChildren().length );
@@ -124,7 +128,7 @@
// Test creating a folder that already exists
assertTrue( folder.exists() );
- folder.create( FileType.FOLDER );
+ folder.createFolder();
}
/**
@@ -137,7 +141,7 @@
// Create direct child of the test folder
FileObject file = scratchFolder.resolveFile( "file1.txt" );
assertTrue( !file.exists() );
- file.create( FileType.FILE );
+ file.createFile();
assertTrue( file.exists() );
assertSame( FileType.FILE, file.getType() );
assertEquals( 0, file.getContent().getSize() );
@@ -147,7 +151,7 @@
assertTrue( !file.exists() );
assertTrue( !file.getParent().exists() );
assertTrue( !file.getParent().getParent().exists() );
- file.create( FileType.FILE );
+ file.createFile();
assertTrue( file.exists() );
assertSame( FileType.FILE, file.getType() );
assertEquals( 0, file.getContent().getSize() );
@@ -156,7 +160,7 @@
// Test creating a file that already exists
assertTrue( file.exists() );
- file.create( FileType.FILE );
+ file.createFile();
}
/**
@@ -168,17 +172,17 @@
// Create a test file and folder
FileObject file = scratchFolder.resolveFile( "dir1/file1.txt" );
- file.create( FileType.FILE );
+ file.createFile();
assertEquals( FileType.FILE, file.getType() );
FileObject folder = scratchFolder.resolveFile( "dir1/dir2" );
- folder.create( FileType.FOLDER );
+ folder.createFolder();
assertEquals( FileType.FOLDER, folder.getType() );
// Attempt to create a file that already exists as a folder
try
{
- folder.create( FileType.FILE );
+ folder.createFile();
fail();
}
catch( FileSystemException exc )
@@ -188,7 +192,7 @@
// Attempt to create a folder that already exists as a file
try
{
- file.create( FileType.FOLDER );
+ file.createFolder();
fail();
}
catch( FileSystemException exc )
@@ -199,7 +203,7 @@
FileObject folder2 = file.resolveFile( "some-child" );
try
{
- folder2.create( FileType.FOLDER );
+ folder2.createFolder();
fail();
}
catch( FileSystemException exc )
@@ -214,10 +218,10 @@
{
// Set-up the test structure
FileObject folder = createScratchFolder();
- folder.resolveFile( "file1.txt" ).create( FileType.FILE );
- folder.resolveFile( "emptydir" ).create( FileType.FOLDER );
- folder.resolveFile( "dir1/file1.txt" ).create( FileType.FILE );
- folder.resolveFile( "dir1/dir2/file2.txt" ).create( FileType.FILE );
+ folder.resolveFile( "file1.txt" ).createFile();
+ folder.resolveFile( "emptydir" ).createFolder();
+ folder.resolveFile( "dir1/file1.txt" ).createFile();
+ folder.resolveFile( "dir1/dir2/file2.txt" ).createFile();
// Delete a file
FileObject file = folder.resolveFile( "file1.txt" );
@@ -259,17 +263,17 @@
assertEquals( 0, folder.getChildren().length );
// Create a child folder
- folder.resolveFile( "dir1" ).create( FileType.FOLDER );
+ folder.resolveFile( "dir1" ).createFolder();
names.add( "dir1" );
assertSameFileSet( names, folder.getChildren() );
// Create a child file
- folder.resolveFile( "file1.html" ).create( FileType.FILE );
+ folder.resolveFile( "file1.html" ).createFile();
names.add( "file1.html" );
assertSameFileSet( names, folder.getChildren() );
// Create a descendent
- folder.resolveFile( "dir2/file1.txt" ).create( FileType.FILE );
+ folder.resolveFile( "dir2/file1.txt" ).createFile();
names.add( "dir2" );
assertSameFileSet( names, folder.getChildren() );
@@ -291,11 +295,71 @@
// Recreate the folder
folder.delete( Selectors.SELECT_ALL );
- folder.create( FileType.FOLDER );
+ folder.createFolder();
assertEquals( 0, folder.getChildren().length );
}
/**
+ * Check listeners are notified of changes.
+ */
+ public void testListener() throws Exception
+ {
+ final FileObject baseFile = createScratchFolder();
+
+ FileObject child = baseFile.resolveFile( "newfile.txt" );
+ assertTrue( !child.exists() );
+
+ FileSystem fs = baseFile.getFileSystem();
+ TestListener listener = new TestListener( child );
+ fs.addListener( child, listener );
+
+ // Create as a folder
+ listener.addCreateEvent();
+ child.createFolder();
+ listener.assertFinished();
+
+ // Create the folder again. Should not get an event.
+ child.createFolder();
+
+ // Delete
+ listener.addDeleteEvent();
+ child.delete();
+ listener.assertFinished();
+
+ // Delete again. Should not get an event
+ child.delete();
+
+ // Create as a file
+ listener.addCreateEvent();
+ child.createFile();
+ listener.assertFinished();
+
+ // Create the file again. Should not get an event
+ child.createFile();
+
+ listener.addDeleteEvent();
+ child.delete();
+
+ // Create as a file, by writing to it.
+ listener.addCreateEvent();
+ child.getContent().getOutputStream().close();
+ listener.assertFinished();
+
+ // Recreate the file by writing to it
+ child.getContent().getOutputStream().close();
+
+ // Copy another file over the top
+ final FileObject otherChild = baseFile.resolveFile( "folder1" );
+ otherChild.createFolder();
+ listener.addDeleteEvent();
+ listener.addCreateEvent();
+ child.copyFrom( otherChild, Selectors.SELECT_SELF );
+ listener.assertFinished();
+
+ fs.removeListener( child, listener );
+ }
+
+ /**
* Ensures the names of a set of files match an expected set.
*/
private void assertSameFileSet( Set names, FileObject[] files )
@@ -308,6 +372,72 @@
{
FileObject file = files[ i ];
assertTrue( names.contains( file.getName().getBaseName() ) );
+ }
+ }
+
+ /**
+ * A test listener.
+ */
+ private static class TestListener
+ implements FileListener
+ {
+ private final FileObject file;
+ private final ArrayList events = new ArrayList();
+ private static final Object CREATE = "create";
+ private static final Object DELETE = "delete";
+
+ public TestListener( final FileObject file )
+ {
+ this.file = file;
+ }
+
+ /**
+ * Called when a file is created.
+ */
+ public void fileCreated( final FileChangeEvent event )
+ {
+ assertTrue( events.size() > 0 && events.remove( 0 ) == CREATE );
+ assertSame( file, event.getFile() );
+ try
+ {
+ assertTrue( file.exists() );
+ }
+ catch ( FileSystemException e )
+ {
+ fail();
+ }
+ }
+
+ /**
+ * Called when a file is deleted.
+ */
+ public void fileDeleted( final FileChangeEvent event )
+ {
+ assertTrue( events.size() > 0 && events.remove( 0 ) == DELETE );
+ assertSame( file, event.getFile() );
+ try
+ {
+ assertTrue( !file.exists() );
+ }
+ catch ( FileSystemException e )
+ {
+ fail();
+ }
+ }
+
+ public void addCreateEvent()
+ {
+ events.add( CREATE );
+ }
+
+ public void addDeleteEvent()
+ {
+ events.add( DELETE );
+ }
+
+ public void assertFinished()
+ {
+ assertEquals( "Missing event", 0, events.size() );
}
}
}
--
To unsubscribe, e-mail: <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>