(no commit message)
[utils] / support / general / src / main / java / org / wamblee / io / DirectoryMonitor.java
diff --git a/support/general/src/main/java/org/wamblee/io/DirectoryMonitor.java b/support/general/src/main/java/org/wamblee/io/DirectoryMonitor.java
new file mode 100644 (file)
index 0000000..0f84183
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2006 the original author or authors.
+ * 
+ * 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.wamblee.io;
+
+import java.io.File;
+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.
+ * 
+ * @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>();
+       }
+
+       /**
+        * 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;
+       }
+
+}