commons-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ima...@apache.org
Subject cvs commit: jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test ProviderWriteTests.java
Date Mon, 11 Oct 2004 19:27:53 GMT
imario      2004/10/11 12:27:53

  Modified:    vfs/src/java/org/apache/commons/vfs/provider
                        AbstractFileObject.java AbstractFileSystem.java
                        DelegateFileObject.java
               vfs/src/java/org/apache/commons/vfs FileListener.java
               vfs      project.xml
               vfs/src/test/org/apache/commons/vfs/test
                        ProviderWriteTests.java
  Added:       vfs/src/java/org/apache/commons/vfs/events
                        AbstractFileChangeEvent.java ChangedEvent.java
                        CreateEvent.java DeleteEventAbstractFile.java
               vfs/src/java/org/apache/commons/vfs/impl
                        DefaultFileMonitor.java
               vfs/src/java/org/apache/commons/vfs FileMonitor.java
  Log:
  FileMonitor
  Submitted by: Christopher Ottley <xknight -at- users.sourceforge.net>
  
  Moved into another package
  Moved into DefaultFileMonitor and introduced new interface FileMonitor
  
  Revision  Changes    Path
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/events/AbstractFileChangeEvent.java
  
  Index: AbstractFileChangeEvent.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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.events;
  
  import org.apache.commons.vfs.FileChangeEvent;
  import org.apache.commons.vfs.FileListener;
  import org.apache.commons.vfs.FileObject;
  
  /**
   * A change event that knows how to notify a listener.
   */
  public abstract class AbstractFileChangeEvent extends FileChangeEvent
  {
      public AbstractFileChangeEvent(final FileObject file)
      {
          super(file);
      }
  
      public abstract void notify(final FileListener listener) throws Exception;
  }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/events/ChangedEvent.java
  
  Index: ChangedEvent.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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.events;
  
  import org.apache.commons.vfs.FileListener;
  import org.apache.commons.vfs.FileObject;
  
  /**
   * File changed event.
   */
  public class ChangedEvent extends AbstractFileChangeEvent
  {
      public ChangedEvent(final FileObject file)
      {
          super(file);
      }
  
      public void notify(final FileListener listener) throws Exception
      {
          listener.fileChanged(this);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/events/CreateEvent.java
  
  Index: CreateEvent.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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.events;
  
  import org.apache.commons.vfs.FileListener;
  import org.apache.commons.vfs.FileObject;
  
  /**
   * File creation event.
   */
  public class CreateEvent extends AbstractFileChangeEvent
  {
      public CreateEvent(final FileObject file)
      {
          super(file);
      }
  
      public void notify(final FileListener listener) throws Exception
      {
          listener.fileCreated(this);
      }
  }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/events/DeleteEventAbstractFile.java
  
  Index: DeleteEventAbstractFile.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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.events;
  
  import org.apache.commons.vfs.FileListener;
  import org.apache.commons.vfs.FileObject;
  
  /**
   * File deletion event.
   */
  public class DeleteEventAbstractFile extends AbstractFileChangeEvent
  {
      public DeleteEventAbstractFile(final FileObject file)
      {
          super(file);
      }
  
      public void notify(final FileListener listener) throws Exception
      {
          listener.fileDeleted(this);
      }
  }
  
  
  
  1.51      +10 -0     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.50
  retrieving revision 1.51
  diff -u -r1.50 -r1.51
  --- AbstractFileObject.java	7 Jul 2004 20:01:35 -0000	1.50
  +++ AbstractFileObject.java	11 Oct 2004 19:27:53 -0000	1.51
  @@ -1273,6 +1273,16 @@
       }
   
       /**
  +     * Called when this file is changed.<br />
  +     * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
  +     */
  +    protected void handleChanged() throws Exception
  +    {
  +        // Notify the file system
  +        fs.fireFileChanged(this);
  +    }
  +
  +    /**
        * Notifies the file that its children have changed.
        *
        * @todo Indicate whether the child was added or removed, and which child.
  
  
  
  1.32      +35 -52    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.31
  retrieving revision 1.32
  diff -u -r1.31 -r1.32
  --- AbstractFileSystem.java	26 Aug 2004 16:36:41 -0000	1.31
  +++ AbstractFileSystem.java	11 Oct 2004 19:27:53 -0000	1.32
  @@ -18,7 +18,6 @@
   import org.apache.commons.logging.Log;
   import org.apache.commons.logging.LogFactory;
   import org.apache.commons.vfs.Capability;
  -import org.apache.commons.vfs.FileChangeEvent;
   import org.apache.commons.vfs.FileListener;
   import org.apache.commons.vfs.FileName;
   import org.apache.commons.vfs.FileObject;
  @@ -29,6 +28,10 @@
   import org.apache.commons.vfs.FileSystemOptions;
   import org.apache.commons.vfs.FilesCache;
   import org.apache.commons.vfs.VfsLog;
  +import org.apache.commons.vfs.events.AbstractFileChangeEvent;
  +import org.apache.commons.vfs.events.ChangedEvent;
  +import org.apache.commons.vfs.events.CreateEvent;
  +import org.apache.commons.vfs.events.DeleteEventAbstractFile;
   import org.apache.commons.vfs.util.Messages;
   
   import java.io.File;
  @@ -250,13 +253,26 @@
        */
       public synchronized FileObject resolveFile(final FileName name) throws FileSystemException
       {
  +        return resolveFile(name, true);
  +    }
  +
  +    public synchronized FileObject resolveFile(final FileName name, final boolean useCache)
throws FileSystemException
  +    {
           if (!rootName.getRootURI().equals(name.getRootURI()))
           {
               throw new FileSystemException("vfs.provider/mismatched-fs-for-name.error",
new Object[]{name, rootName});
           }
   
           // imario@apache.org ==> use getFileFromCache
  -        FileObject file = getFileFromCache(name);
  +        FileObject file;
  +        if (useCache)
  +        {
  +            file = getFileFromCache(name);
  +        }
  +        else
  +        {
  +            file = null;
  +        }
           // FileObject file = (FileObject) files.get(name);
           if (file == null)
           {
  @@ -273,7 +289,10 @@
               }
   
               // imario@apache.org ==> use putFileToCache
  -            putFileToCache(file);
  +            if (useCache)
  +            {
  +                putFileToCache(file);
  +            }
               // files.put(name, file);
           }
           return file;
  @@ -393,7 +412,7 @@
       /**
        * Fires a file create event.
        */
  -    protected void fireFileCreated(final FileObject file)
  +    public void fireFileCreated(final FileObject file)
       {
           fireEvent(new CreateEvent(file));
       }
  @@ -401,9 +420,18 @@
       /**
        * Fires a file delete event.
        */
  -    protected void fireFileDeleted(final FileObject file)
  +    public void fireFileDeleted(final FileObject file)
       {
  -        fireEvent(new DeleteEvent(file));
  +        fireEvent(new DeleteEventAbstractFile(file));
  +    }
  +
  +    /**
  +     * Fires a file changed event. <br />
  +     * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
  +     */
  +    public void fireFileChanged(final FileObject file)
  +    {
  +        fireEvent(new ChangedEvent(file));
       }
   
       /**
  @@ -422,7 +450,7 @@
       /**
        * Fires an event.
        */
  -    private void fireEvent(final ChangeEvent event)
  +    private void fireEvent(final AbstractFileChangeEvent event)
       {
           synchronized (listenerMap)
           {
  @@ -468,50 +496,5 @@
       FileSystemKey getCacheKey()
       {
           return this.cacheKey;
  -    }
  -
  -    /**
  -     * A change event that knows how to notify a listener.
  -     */
  -    private abstract static class ChangeEvent extends FileChangeEvent
  -    {
  -        public ChangeEvent(final FileObject file)
  -        {
  -            super(file);
  -        }
  -
  -        public abstract void notify(final FileListener listener) throws Exception;
  -    }
  -
  -    /**
  -     * File creation event.
  -     */
  -    private static class CreateEvent extends ChangeEvent
  -    {
  -        public CreateEvent(final FileObject file)
  -        {
  -            super(file);
  -        }
  -
  -        public void notify(final FileListener listener) throws Exception
  -        {
  -            listener.fileCreated(this);
  -        }
  -    }
  -
  -    /**
  -     * File deletion event.
  -     */
  -    private static class DeleteEvent extends ChangeEvent
  -    {
  -        public DeleteEvent(final FileObject file)
  -        {
  -            super(file);
  -        }
  -
  -        public void notify(final FileListener listener) throws Exception
  -        {
  -            listener.fileDeleted(this);
  -        }
       }
   }
  
  
  
  1.14      +14 -1     jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/DelegateFileObject.java
  
  Index: DelegateFileObject.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/provider/DelegateFileObject.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- DelegateFileObject.java	10 May 2004 20:09:43 -0000	1.13
  +++ DelegateFileObject.java	11 Oct 2004 19:27:53 -0000	1.14
  @@ -310,4 +310,17 @@
               handleDelete();
           }
       }
  +
  +    /**
  +     * Called when a file is changed.
  +     * <p/>
  +     * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
  +     */
  +    public void fileChanged(FileChangeEvent event) throws Exception
  +    {
  +        if (!ignoreEvent)
  +        {
  +            handleChanged();
  +        }
  +    }
   }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/impl/DefaultFileMonitor.java
  
  Index: DefaultFileMonitor.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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.impl;
  
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.commons.vfs.FileListener;
  import org.apache.commons.vfs.FileMonitor;
  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.AbstractFileSystem;
  
  import java.util.HashMap;
  import java.util.Map;
  import java.util.Stack;
  
  
  /**
   * Implementation Documentation
   * ============================
   *
   * The FileMonitor is a Thread based polling file system monitor with a 1 second delay.
   *
   * Design:
   *   There is a Map of monitors known as FileMonitorAgents. With the thread running,
   *   each FileMonitorAgent object is asked to "check" on the file it is responsible for.
   *   To do this check, the cache is cleared. If the file existed before the refresh and
   *   it no longer exists, a delete event is fired. If the file existed before the refresh
   *   and it still exists, check the last modified timestamp to see if that has changed.
   *   If it has, fire a change event (BUG no change event, fires a create event instead).
   *   With each file delete, the FileMonitorAgent of the parent is asked to re-build its
   *   list of children, so that they can be accurately checked when there are new children.
   *   New files are detected during each "check" as each file does a check for new children.
   *   If new children are found, create events are fired recursively if recursive descent
is
   *   enabled.
   *
   * Example usage:
  
   try {
   FileSystemManager fsManager = VFS.getManager();
   FileObject listendir = fsManager.resolveFile("/home/username/monitored/");
  
   DefaultFileMonitor fm = new DefaultFileMonitor(new CustomFileListener());
   fm.setRecursive(true);
   fm.addFile(listendir);
   fm.start();
   }
   catch (FileSystemException fse)
   {
   fse.printStackTrace();
   }
  
   *
   * where CustomFileSystemListener is a class that implements the FileListener interface.
   */
  
  
  /**
   * A polling FileMonitor implementation.
   *
   * @author <a href="mailto:xknight@users.sourceforge.net">Christopher Ottley</a>
   * @version $Revision: 1.1 $ $Date: 2004/10/11 19:27:53 $
   */
  public class DefaultFileMonitor implements Runnable, FileMonitor
  {
      private final static Log log = LogFactory.getLog(DefaultFileMonitor.class);
  
      /**
       * Map from FileName to FileObject being monitored.
       */
      private final Map monitorMap = new HashMap();
  
      /**
       * The low priority thread used for checking the files being monitored.
       */
      private Thread monitorThread;
  
      /**
       * File objects to be removed from the monitor map.
       */
      private Stack deleteStack = new Stack();
  
      /**
       * File objects to be added to the monitor map.
       */
      private Stack addStack = new Stack();
  
      /**
       * A flag used to determine if the monitor thread should be running.
       */
      private boolean shouldRun = true;
  
      /**
       * A flag used to determine if adding files to be monitored should be recursive.
       */
      private boolean recursive = false;
  
      /**
       * Set the delay between checks
       */
      private long delay = 1000;
  
      /**
       * A listener object that if set, is notified on file creation and deletion.
       */
      private final FileListener listener;
  
      public DefaultFileMonitor(final FileListener listener)
      {
          this.listener = listener;
      }
  
      /**
       * Access method to get the recursive setting when adding files for monitoring.
       */
      public boolean isRecursive()
      {
          return this.recursive;
      }
  
      /**
       * Access method to set the recursive setting when adding files for monitoring.
       */
      public void setRecursive(final boolean newRecursive)
      {
          this.recursive = newRecursive;
      }
  
      /**
       * Access method to get the current FileListener object notified when there
       * are changes with the files added.
       */
      FileListener getFileListener()
      {
          return this.listener;
      }
  
      /**
       * Adds a file to be monitored.
       */
      public void addFile(final FileObject file)
      {
          synchronized (this.monitorMap)
          {
              if (this.monitorMap.get(file.getName()) == null)
              {
                  this.monitorMap.put(file.getName(), new FileMonitorAgent(this, file));
  
                  try
                  {
                      if (this.listener != null)
                      {
                          file.getFileSystem().addListener(file, this.listener);
                      }
  
                      if (file.getType().hasChildren() && this.recursive)
                      {
                          // Traverse the children
                          final FileObject[] children = file.getChildren();
                          for (int i = 0; i < children.length; i++)
                          {
                              this.addFile(children[i]); // Add depth first
                          }
                      }
  
                  }
                  catch (FileSystemException fse)
                  {
                      log.error(fse.getLocalizedMessage(), fse);
                  }
  
              }
          }
      }
  
      /**
       * Removes a file from being monitored.
       */
      public void removeFile(final FileObject file)
      {
          synchronized (this.monitorMap)
          {
              FileName fn = file.getName();
              if (this.monitorMap.get(fn) != null)
              {
                  FileObject parent;
                  try
                  {
                      parent = file.getParent();
                  }
                  catch (FileSystemException fse)
                  {
                      parent = null;
                  }
  
                  this.monitorMap.remove(fn);
  
                  if (parent != null)
                  { // Not the root
                      FileMonitorAgent parentAgent =
                          (FileMonitorAgent) this.monitorMap.get(parent.getName());
                      if (parentAgent != null)
                      {
                          parentAgent.resetChildrenList();
                      }
                  }
              }
          }
      }
  
      /**
       * Queues a file for removal from being monitored.
       */
      protected void queueRemoveFile(final FileObject file)
      {
          this.deleteStack.push(file);
      }
  
      /**
       * Get the delay between runs
       */
      public long getDelay()
      {
          return delay;
      }
  
      /**
       * Set the delay between runs
       */
      public void setDelay(long delay)
      {
          this.delay = delay;
      }
  
      /**
       * Queues a file for addition to be monitored.
       */
      protected void queueAddFile(final FileObject file)
      {
          this.addStack.push(file);
      }
  
      /**
       * Starts monitoring the files that have been added.
       */
      public void start()
      {
          if (this.monitorThread == null)
          {
              this.monitorThread = new Thread(this);
              this.monitorThread.setDaemon(true);
              this.monitorThread.setPriority(Thread.MIN_PRIORITY);
          }
          this.monitorThread.start();
      }
  
      /**
       * Stops monitoring the files that have been added.
       */
      public void stop()
      {
          this.shouldRun = false;
      }
  
      /**
       * Asks the agent for each file being monitored to check its file for changes.
       */
      public void run()
      {
          mainloop: while (!Thread.currentThread().isInterrupted() && this.shouldRun)
          {
              while (!this.deleteStack.empty())
              {
                  this.removeFile((FileObject) this.deleteStack.pop());
              }
  
              // For each entry in the map
              Object fileNames[];
              synchronized (this.monitorMap)
              {
                  fileNames = this.monitorMap.keySet().toArray();
              }
              for (int iterFileNames = 0; iterFileNames < fileNames.length; iterFileNames++)
              {
                  FileName fileName = (FileName) fileNames[iterFileNames];
                  FileMonitorAgent agent;
                  synchronized (this.monitorMap)
                  {
                      agent = (FileMonitorAgent) this.monitorMap.get(fileName);
                  }
                  if (agent != null)
                  {
                      agent.check();
                  }
  
                  if (Thread.currentThread().isInterrupted() || !this.shouldRun)
                  {
                      continue mainloop;
                  }
              }
  
              while (!this.addStack.empty())
              {
                  this.addFile((FileObject) this.addStack.pop());
              }
  
              try
              {
                  Thread.sleep(getDelay());
              }
              catch (InterruptedException e)
              {
                  continue;
              }
          }
  
          this.shouldRun = true;
      }
  
      /**
       * File monitor agent.
       */
      private static class FileMonitorAgent
      {
  
          private FileObject file;
          private boolean exists;
          private long timestamp;
          private DefaultFileMonitor fm;
          private Map children = null;
  
          private FileMonitorAgent(DefaultFileMonitor fm, FileObject file)
          {
              this.fm = fm;
              this.file = file;
  
              this.refresh();
              this.resetChildrenList();
  
              try
              {
                  this.exists = this.file.exists();
              }
              catch (FileSystemException fse)
              {
                  this.exists = false;
              }
  
              try
              {
                  this.timestamp = this.file.getContent().getLastModifiedTime();
              }
              catch (FileSystemException fse)
              {
                  this.timestamp = -1;
              }
  
          }
  
          private void resetChildrenList()
          {
              try
              {
                  if (this.file.getType() == FileType.FOLDER)
                  {
                      this.children = new HashMap();
                      FileObject[] childrenList = this.file.getChildren();
                      for (int i = 0; i < childrenList.length; i++)
                      {
                          this.children.put(childrenList[i].getName(), new Object()); // null?
                      }
                  }
              }
              catch (FileSystemException fse)
              {
                  this.children = null;
              }
          }
  
  
          /**
           * Clear the cache and re-request the file object
           */
          private void refresh()
          {
              try
              {
                  // TODO: Activate *THE RIGHT WAY* as soon as VFS is completely thread-safe
                  this.file = ((AbstractFileSystem) this.file.getFileSystem()).resolveFile(this.file.getName(),
false);
                  // FileSystemManager fsManager = this.file.getFileSystem().getFileSystemManager();
                  // this.file = fsManager.resolveFile(this.file.getName().getPath());
  
                  // *THE RIGHT WAY*
                  // close the file - this will detach and reattach its resources (for this
thread) on the
                  // next access
                  // this.file.close();
              }
              catch (FileSystemException fse)
              {
                  log.error(fse.getLocalizedMessage(), fse);
              }
          }
  
  
          /**
           * Recursively fires create events for all children if recursive descent is
           * enabled. Otherwise the create event is only fired for the initial
           * FileObject.
           */
          private void fireAllCreate(FileObject child)
          {
              // Add listener so that it can be triggered
              if (this.fm.getFileListener() != null)
              {
                  child.getFileSystem().addListener(child, this.fm.getFileListener());
              }
  
              ((AbstractFileSystem) child.getFileSystem()).fireFileCreated(child);
  
              // Remove it because a listener is added in the queueAddFile
              if (this.fm.getFileListener() != null)
              {
                  child.getFileSystem().removeListener(child, this.fm.getFileListener());
              }
  
              this.fm.queueAddFile(child); // Add
  
              try
              {
  
                  if (this.fm.isRecursive())
                  {
                      if (child.getType() == FileType.FOLDER)
                      {
                          FileObject[] newChildren = child.getChildren();
                          for (int i = 0; i < newChildren.length; i++)
                          {
                              fireAllCreate(newChildren[i]);
                          }
                      }
                  }
  
              }
              catch (FileSystemException fse)
              {
                  log.error(fse.getLocalizedMessage(), fse);
              }
          }
  
          /**
           * Only checks for new children. If children are removed, they'll
           * eventually be checked.
           */
          private void checkForNewChildren()
          {
              try
              {
                  if (this.file.getType() == FileType.FOLDER)
                  {
                      FileObject[] newChildren = this.file.getChildren();
                      if (this.children != null)
                      {
                          // See which new children are not listed in the current children
map.
                          Map newChildrenMap = new HashMap();
                          Stack missingChildren = new Stack();
  
                          for (int i = 0; i < newChildren.length; i++)
                          {
                              newChildrenMap.put(newChildren[i].getName(), new Object());
// null ?
                              // If the child's not there
                              if (!this.children.containsKey(newChildren[i].getName()))
                              {
                                  missingChildren.push(newChildren[i]);
                              }
                          }
  
                          this.children = newChildrenMap;
  
                          // If there were missing children
                          if (!missingChildren.empty())
                          {
  
                              while (!missingChildren.empty())
                              {
                                  FileObject child = (FileObject) missingChildren.pop();
                                  this.fireAllCreate(child);
                              }
                          }
  
                      }
                      else
                      {
                          // First set of children - Break out the cigars
                          if (newChildren.length > 0)
                          {
                              this.children = new HashMap();
                          }
                          for (int i = 0; i < newChildren.length; i++)
                          {
                              this.children.put(newChildren[i].getName(), new Object()); //
null?
                              this.fireAllCreate(newChildren[i]);
                          }
                      }
                  }
              }
              catch (FileSystemException fse)
              {
                  log.error(fse.getLocalizedMessage(), fse);
              }
          }
  
          private void check()
          {
              this.refresh();
  
              try
              {
                  // If the file existed and now doesn't
                  if (this.exists && !this.file.exists())
                  {
                      this.exists = this.file.exists();
                      this.timestamp = -1;
  
                      // Fire delete event
  
                      ((AbstractFileSystem) this.file.getFileSystem()).fireFileDeleted(this.file);
  
                      // Remove listener in case file is re-created. Don't want to fire twice.
                      if (this.fm.getFileListener() != null)
                      {
                          this.file.getFileSystem().removeListener(this.file,
                              this.fm.getFileListener());
                      }
  
                      // Remove from map
                      this.fm.queueRemoveFile(this.file);
                  }
                  else if (this.exists && this.file.exists())
                  {
  
                      // Check the timestamp to see if it has been modified
                      if (this.timestamp != this.file.getContent().getLastModifiedTime())
                      {
                          this.timestamp = this.file.getContent().getLastModifiedTime();
                          // Fire change event
  
                          // Don't fire if it's a folder because new file children
                          // and deleted files in a folder have their own event triggered.
                          if (this.file.getType() != FileType.FOLDER)
                          {
                              ((AbstractFileSystem) this.file.getFileSystem()).fireFileChanged(this.file);
                          }
                      }
  
                  }
  
                  this.checkForNewChildren();
  
              }
              catch (FileSystemException fse)
              {
                  log.error(fse.getLocalizedMessage(), fse);
              }
          }
  
      }
  
  }
  
  
  
  
  1.7       +7 -1      jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileListener.java
  
  Index: FileListener.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileListener.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- FileListener.java	10 May 2004 20:09:45 -0000	1.6
  +++ FileListener.java	11 Oct 2004 19:27:53 -0000	1.7
  @@ -32,4 +32,10 @@
        * Called when a file is deleted.
        */
       void fileDeleted(FileChangeEvent event) throws Exception;
  +
  +    /**
  +     * Called when a file is changed.<br />
  +     * This will only happen if you monitor the file using {@link FileMonitor}.
  +     */
  +    void fileChanged(FileChangeEvent event) throws Exception;
   }
  
  
  
  1.1                  jakarta-commons-sandbox/vfs/src/java/org/apache/commons/vfs/FileMonitor.java
  
  Index: FileMonitor.java
  ===================================================================
  /*
   * Copyright 2002, 2003,2004 The Apache Software Foundation.
   *
   * Licensed 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;
  
  /**
   * FileMonitor interface
   *
   * @author <a href="mailto:imario@apache.org">Mario Ivankovits</a>
   * @version $Revision: 1.1 $ $Date: 2004/10/11 19:27:53 $
   */
  public interface FileMonitor
  {
      /**
       * Adds a file to be monitored.
       */
      public void addFile(final FileObject file);
  
      /**
       * Removes a file from being monitored.
       */
      public void removeFile(final FileObject file);
  }
  
  
  
  1.43      +4 -0      jakarta-commons-sandbox/vfs/project.xml
  
  Index: project.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/project.xml,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- project.xml	10 Sep 2004 17:26:57 -0000	1.42
  +++ project.xml	11 Oct 2004 19:27:53 -0000	1.43
  @@ -44,6 +44,10 @@
               <name>Anthony Goubard</name>
               <email>adagoubard -at- chello.nl</email>
           </contributor>
  +        <contributor>
  +            <name>Christopher Ottley</name>
  +            <email>xknight -at- users.sourceforge.net</email>
  +        </contributor>
       </contributors>
   
       <dependencies>
  
  
  
  1.19      +17 -2     jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/ProviderWriteTests.java
  
  Index: ProviderWriteTests.java
  ===================================================================
  RCS file: /home/cvs/jakarta-commons-sandbox/vfs/src/test/org/apache/commons/vfs/test/ProviderWriteTests.java,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- ProviderWriteTests.java	3 Jun 2004 17:14:16 -0000	1.18
  +++ ProviderWriteTests.java	11 Oct 2004 19:27:53 -0000	1.19
  @@ -537,13 +537,13 @@
       /**
        * A test listener.
        */
  -    private static class TestListener
  -        implements FileListener
  +    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";
  +        private static final Object CHANGED = "changed";
   
           public TestListener(final FileObject file)
           {
  @@ -575,6 +575,21 @@
           {
               assertTrue("Unexpected delete event", events.size() > 0);
               assertSame("Expecting a delete event", DELETE, events.remove(0));
  +            assertSame(file, event.getFile());
  +            try
  +            {
  +                assertTrue(!file.exists());
  +            }
  +            catch (FileSystemException e)
  +            {
  +                fail();
  +            }
  +        }
  +
  +        public void fileChanged(FileChangeEvent event) throws Exception
  +        {
  +            assertTrue("Unexpected changed event", events.size() > 0);
  +            assertSame("Expecting a changed event", CHANGED, events.remove(0));
               assertSame(file, event.getFile());
               try
               {
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org


Mime
View raw message