added test cases for directorymonitor.
[utils] / support / src / main / java / org / wamblee / io / DirectoryMonitor.java
index 74723337f92af2744b2fd6dbfebf0d2b64785e2a..0f84183c1b4478cdb32aad51dcc49b4145eeebc8 100644 (file)
@@ -12,7 +12,7 @@
  * 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.wamblee.io;
 
@@ -21,65 +21,90 @@ import java.io.FileFilter;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 /**
- * Monitors a directory for changes. 
- *
+ * Monitors a directory for changes.
+ * 
  * @author Erik Brakkee
  */
 public class DirectoryMonitor {
-    
-    private static final Log LOG = LogFactory.getLog(DirectoryMonitor.class);
-    
-    public static interface Listener { 
-        void fileChanged(File aFile); 
-        void fileCreated(File aFile); 
-        void fileDeleted(File aFile);
-    };
-    
-    private File _directory;
-    private FileFilter _filter; 
-    private Listener _listener;
-    private Map<File,Date> _contents; 
-    
-    public DirectoryMonitor(File aDirectory, FileFilter aFilefilter, Listener aListener) {
-        _directory = aDirectory;
-        if ( !_directory.isDirectory()) { 
-            throw new IllegalArgumentException("Directory '" + _directory + "' does not exist");
-        }
-        _filter = aFilefilter; 
-        _listener = aListener;
-        _contents = new HashMap<File,Date>();
-    }
-    
-    public void poll() {
-        LOG.debug("Polling " + _directory);
-        Map<File,Date> newContents = new HashMap<File,Date>();
-        File[] files = _directory.listFiles(_filter);
-        for (File file: files) { 
-            if ( _contents.containsKey(file)) { 
-                Date oldDate = _contents.get(file);
-                if (file.lastModified() != oldDate.getTime()) { 
-                    _listener.fileChanged(file);
-                } else { 
-                    // No change. 
-                }
-                _contents.remove(file);
-                newContents.put(file, new Date(file.lastModified()));
-            } else { 
-                _listener.fileCreated(file);
-                newContents.put(file, new Date(file.lastModified()));
-            }
-        }
-        for (File file: _contents.keySet()) { 
-            _listener.fileDeleted(file);
-        }
-        _contents = newContents;
-    }
+
+       private static final Log LOG = LogFactory.getLog(DirectoryMonitor.class);
+
+       public static interface Listener {
+               
+               void fileChanged(File aFile);
+
+               void fileCreated(File aFile);
+
+               void fileDeleted(File aFile);
+       };
+
+       private File _directory;
+       private FileFilter _filter;
+       private Listener _listener;
+       private Map<File, Date> _contents;
+
+       public DirectoryMonitor(File aDirectory, FileFilter aFilefilter,
+                       Listener aListener) {
+               _directory = aDirectory;
+               if (!_directory.isDirectory()) {
+                       throw new IllegalArgumentException("Directory '" + _directory
+                                       + "' does not exist");
+               }
+               _filter = aFilefilter;
+               _listener = aListener;
+               _contents = new HashMap<File, Date>();
+       }
+
+       /**
+        * Polls the directory for changes and notifies the listener of any changes. 
+        * In case of any exceptions thrown by the listener while handling the changes, 
+        * the next call to this method will invoked the listeners again for the same changes. 
+        */
+       public void poll() {
+               LOG.debug("Polling " + _directory);
+               Map<File, Date> newContents = new HashMap<File, Date>();
+               File[] files = _directory.listFiles(_filter);
+
+               // Check deleted files. 
+               Set<File> deletedFiles = new HashSet<File>(_contents.keySet());
+               for (File file : files) {
+                       if (file.isFile()) {
+                               if (_contents.containsKey(file)) {
+                                       deletedFiles.remove(file);
+                               }
+                       }
+               }
+               for (File file : deletedFiles) {
+                       _listener.fileDeleted(file);
+               }
+               
+               for (File file : files) {
+                       if (file.isFile()) {
+                               if (_contents.containsKey(file)) {
+                                       Date oldDate = _contents.get(file);
+                                       if (file.lastModified() != oldDate.getTime()) {
+                                               _listener.fileChanged(file);
+                                       } else {
+                                               // No change.
+                                       }
+                                       newContents.put(file, new Date(file.lastModified()));
+                               } else {
+                                       _listener.fileCreated(file);
+                                       newContents.put(file, new Date(file.lastModified()));
+                               }
+                       }
+               }
+               
+               _contents = newContents;
+       }
 
 }