You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by db...@apache.org on 2005/11/17 10:39:36 UTC

svn commit: r345214 - in /geronimo/gbuild/trunk/gbuild-agent/src: main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java

Author: dblevins
Date: Thu Nov 17 01:39:33 2005
New Revision: 345214

URL: http://svn.apache.org/viewcvs?rev=345214&view=rev
Log:
Rewrote the DirectoryMonitor to be far simpler. The previous version i hacked on didn't work.  Added test case that tests the various state transitions.

Added:
    geronimo/gbuild/trunk/gbuild-agent/src/test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java
Modified:
    geronimo/gbuild/trunk/gbuild-agent/src/main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java

Modified: geronimo/gbuild/trunk/gbuild-agent/src/main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/gbuild-agent/src/main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java?rev=345214&r1=345213&r2=345214&view=diff
==============================================================================
--- geronimo/gbuild/trunk/gbuild-agent/src/main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java (original)
+++ geronimo/gbuild/trunk/gbuild-agent/src/main/java/org/apache/geronimo/gbuild/agent/DirectoryMonitor.java Thu Nov 17 01:39:33 2005
@@ -17,13 +17,14 @@
 package org.apache.geronimo.gbuild.agent;
 
 import org.codehaus.plexus.logging.AbstractLogEnabled;
+import org.codehaus.plexus.logging.Logger;
 
 import java.io.File;
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Map;
+import java.util.Iterator;
 
 /**
  * @version $Rev$ $Date$
@@ -52,7 +53,7 @@
     private Listener listener;
     private Map files = new HashMap();
 
-    public DirectoryMonitor(File directory, Listener listener, int pollIntervalMillis) {
+    public DirectoryMonitor(File directory, Listener listener, int pollIntervalMillis, Logger logger) {
         assert listener == null: "No point in scanning without a listener.";
         assert directory.isDirectory(): "File specified is not a directory. " + directory.getAbsolutePath();
         assert directory.canRead(): "Directory specified cannot be read. " + directory.getAbsolutePath();
@@ -61,6 +62,7 @@
         this.directory = directory;
         this.listener = listener;
         this.pollIntervalMillis = pollIntervalMillis;
+        enableLogging(logger);
     }
 
     public int getPollIntervalMillis() {
@@ -83,9 +85,11 @@
         this.run = false;
     }
 
+
     public void run() {
         run = true;
         initialize();
+        getLogger().debug("Scanner running.  Polling every "+pollIntervalMillis+ " milliseconds.");
         while (run) {
             try {
                 scanDirectory();
@@ -101,9 +105,11 @@
     }
 
     public void initialize() {
+        getLogger().debug("Doing initial scan of "+directory.getAbsolutePath());
         File parent = directory;
         File[] children = parent.listFiles();
-        for (int i = 0; i < children.length; i++) {
+
+        for (int i = 0; children != null && i < children.length; i++) {
             File child = children[i];
 
             if (!child.canRead()) {
@@ -112,110 +118,82 @@
 
             FileInfo now = newInfo(child);
             now.setChanging(false);
-            updateInfo(now);
         }
     }
 
     private FileInfo newInfo(File child) {
-        return child.isDirectory() ? new DirectoryInfo(child) : new FileInfo(child);
+        FileInfo fileInfo = child.isDirectory() ? new DirectoryInfo(child) : new FileInfo(child);
+        files.put(fileInfo.getPath(), fileInfo);
+        return fileInfo;
     }
 
     /**
      * Looks for changes to the immediate contents of the directory we're watching.
      */
-    private void scanDirectory() {
+    public void scanDirectory() {
         File parent = directory;
         File[] children = parent.listFiles();
 
-        HashSet oldList = new HashSet(files.keySet());
-
-        for (int i = 0; i < children.length; i++) {
+        HashSet missingFilesList = new HashSet(files.keySet());
 
+        for (int i = 0; children != null && i < children.length; i++) {
             File child = children[i];
 
+            missingFilesList.remove(child.getAbsolutePath());
+
             if (!child.canRead()) {
+                getLogger().debug("not readable "+ child.getName());
                 continue;
             }
 
-            FileInfo newStatus = newInfo(child);
             FileInfo oldStatus = oldInfo(child);
+            FileInfo newStatus = newInfo(child);
 
-            if ( oldStatus == null ) {
+            newStatus.diff(oldStatus);
 
-                getLogger().debug("File Discovered: " + newStatus);
+            if ( oldStatus == null ) {
 
                 // Brand new, but assume it's changing and
                 // wait a bit to make sure it's not still changing
-                newStatus.setNewFile(true);
-                newStatus.setChanging(true);
-                updateInfo(newStatus);
-
-            } else if ( !newStatus.isSame(oldStatus) ) {
+                getLogger().debug("File Discovered: " + newStatus);
 
-                getLogger().debug("File Changing: " + newStatus);
+            } else if ( newStatus.isChanging() ) {
 
                 // The two records are different -- record the latest as a file that's changing
                 // and later when it stops changing we'll do the add or update as appropriate.
-                newStatus.setChanging(true);
-                newStatus.setNewFile(oldStatus.isNewFile());
-                updateInfo(newStatus);
-
-                oldList.remove(oldStatus.getPath());
+                getLogger().debug("File Changing: " + newStatus);
 
-            } else if ( oldStatus.isChanging() ){
+            } else if (oldStatus.isNewFile()){
 
                 // Used to be changing, now in (hopefully) its final state
-                oldStatus.setChanging(false);
-
-                if (oldStatus.isNewFile()) {
+                getLogger().info("New File: " + newStatus);
+                newStatus.setNewFile(!listener.fileAdded(child));
 
-                    getLogger().debug("New File: " + newStatus);
-                    oldStatus.setNewFile(!listener.fileAdded(child));
-
-                } else {
-
-                    getLogger().debug("Updated File: " + newStatus);
-                    listener.fileUpdated(child);
+            } else if ( oldStatus.isChanging() ){
 
-                }
+                getLogger().info("Updated File: " + newStatus);
+                listener.fileUpdated(child);
 
-                oldList.remove(oldStatus.getPath());
+                missingFilesList.remove(oldStatus.getPath());
 
             }// else it's just totally unchanged and we ignore it this pass
         }
 
         // Look for any files we used to know about but didn't find in this pass
-        for (Iterator it = oldList.iterator(); it.hasNext();) {
-            String path = (String) it.next();
-
-            getLogger().debug("File removed: " + path);
-
-            FileInfo info = oldInfo(path);
-
-            if (info.isNewFile() || listener.fileRemoved(new File(path))) {
-                removeInfo(path);
+        for (Iterator iterator = missingFilesList.iterator(); iterator.hasNext();) {
+            String path = (String) iterator.next();
+            getLogger().info("File removed: " + path);
+            if (listener.fileRemoved(new File(path))){
+                files.remove(path);
             }
         }
     }
 
-    private void removeInfo(String path) {
-        files.remove(path);
-    }
-
-    private void updateInfo(FileInfo newStatus) {
-        files.put(newStatus.getPath(), newStatus);
-    }
-
     private FileInfo oldInfo(File file) {
-        return oldInfo(file.getAbsolutePath());
-    }
-
-    private FileInfo oldInfo(String path) {
-        return (FileInfo) files.get(path);
+        return (FileInfo) files.get(file.getAbsolutePath());
     }
 
     private static class DirectoryInfo extends FileInfo {
-
         /**
          * We don't pay attention to the size of the directory or files in the
          * directory, only the highest last modified time of anything in the
@@ -262,7 +240,7 @@
             this.path = path;
             this.size = size;
             this.modified = modified;
-            this.newFile = false;
+            this.newFile = true;
             this.changing = true;
         }
 
@@ -312,6 +290,13 @@
 
         public String toString() {
             return path;
+        }
+
+        public void diff(FileInfo old) {
+            if (old != null){
+                this.changing = !isSame(old);
+                this.newFile = old.newFile;
+            }
         }
     }
 

Added: geronimo/gbuild/trunk/gbuild-agent/src/test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java
URL: http://svn.apache.org/viewcvs/geronimo/gbuild/trunk/gbuild-agent/src/test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java?rev=345214&view=auto
==============================================================================
--- geronimo/gbuild/trunk/gbuild-agent/src/test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java (added)
+++ geronimo/gbuild/trunk/gbuild-agent/src/test/java/org/apache/geronimo/gbuild/agent/DirectoryMonitorTest.java Thu Nov 17 01:39:33 2005
@@ -0,0 +1,223 @@
+package org.apache.geronimo.gbuild.agent;
+/**
+ * @version $Rev$ $Date$
+ */
+
+import junit.framework.TestCase;
+import org.codehaus.plexus.logging.Logger;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+public class DirectoryMonitorTest extends TestCase {
+
+    public void testScanDirectory() throws Exception {
+        Status status = new Status();
+
+        File dir = File.createTempFile("abc","xyz").getParentFile();
+        dir = new File(dir, "dirscan"+(System.currentTimeMillis()%100000));
+        assertTrue("mkdir "+dir.getAbsolutePath(), dir.mkdir());
+        dir.deleteOnExit();
+
+        DirectoryMonitor monitor = new DirectoryMonitor(dir, status, 0, new TestLogger());
+        monitor.initialize();
+
+        assertNull("file",status.file);
+
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Discovered
+        File aaa = new File(dir, "aaa");
+        writeToFile(aaa);
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // New
+        monitor.scanDirectory();
+        assertEquals("state",Status.ADDED, status.state);
+        assertEquals("file",aaa.getName(), status.file.getName());
+        status.reset();
+
+        // Nothing different
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Updated (Write, scan, scan)
+        writeToFile(aaa);
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        monitor.scanDirectory();
+        assertEquals("state",Status.UPDATED, status.state);
+        assertEquals("file",aaa.getName(), status.file.getName());
+        status.reset();
+
+        // Nothing different
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Nothing different
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Remove
+        assertTrue("delete", aaa.delete());
+        assertTrue("deleted", !aaa.exists());
+        monitor.scanDirectory();
+        assertEquals("state",Status.REMOVED, status.state);
+        assertEquals("file",aaa.getName(), status.file.getName());
+        status.reset();
+
+        // Nothing different
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Nothing different
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // Added again
+        writeToFile(aaa);
+        monitor.scanDirectory();
+        assertNull("state",status.state);
+        assertNull("file",status.file);
+
+        // New
+        monitor.scanDirectory();
+        assertEquals("state",Status.ADDED, status.state);
+        assertEquals("file",aaa.getName(), status.file.getName());
+        status.reset();
+    }
+
+    private void writeToFile(File aaa) throws IOException {
+        FileOutputStream out = new FileOutputStream(aaa, true);
+        out.write(1);
+        out.write(1);
+        out.write(1);
+        out.close();
+    }
+
+
+    public static class Status implements DirectoryMonitor.Listener {
+
+        public static final String REMOVED = "REMOVED";
+        public static final String UPDATED = "UPDATED";
+        public static final String ADDED = "ADDED";
+
+        public File file;
+        public String state;
+
+        public boolean fileAdded(File file) {
+            state = ADDED;
+            this.file = file;
+            return true;
+        }
+
+        public boolean fileRemoved(File file) {
+            state = REMOVED;
+            this.file = file;
+            return true;
+        }
+
+        public void fileUpdated(File file) {
+            state = UPDATED;
+            this.file = file;
+        }
+
+        public void reset() {
+            state = null;
+            file = null;
+        }
+    }
+
+    public static class TestLogger implements org.codehaus.plexus.logging.Logger {
+
+        public void debug(String string) {
+            System.out.println("[debug] " + string);
+        }
+
+        public void debug(String string, Throwable throwable) {
+            System.out.println("[debug] " + string);
+            throwable.printStackTrace();
+        }
+
+        public boolean isDebugEnabled() {
+            return false;
+        }
+
+        public void info(String string) {
+            System.out.println("[info] " + string);
+        }
+
+        public void info(String string, Throwable throwable) {
+            System.out.println("[info] " + string);
+            throwable.printStackTrace();
+        }
+
+        public boolean isInfoEnabled() {
+            return false;
+        }
+
+        public void warn(String string) {
+            System.out.println("[warn] " + string);
+        }
+
+        public void warn(String string, Throwable throwable) {
+            System.out.println("[warn] " + string);
+            throwable.printStackTrace();
+        }
+
+        public boolean isWarnEnabled() {
+            return false;
+        }
+
+        public void error(String string) {
+            System.out.println("[error] " + string);
+        }
+
+        public void error(String string, Throwable throwable) {
+            System.out.println("[error] " + string);
+            throwable.printStackTrace();
+        }
+
+        public boolean isErrorEnabled() {
+            return false;
+        }
+
+        public void fatalError(String string) {
+            System.out.println("[fatalError] " + string);
+        }
+
+        public void fatalError(String string, Throwable throwable) {
+            System.out.println("[fatalError] " + string);
+            throwable.printStackTrace();
+        }
+
+        public boolean isFatalErrorEnabled() {
+            return false;
+        }
+
+        public Logger getChildLogger(String string) {
+            return null;
+        }
+
+        public int getThreshold() {
+            return 0;
+        }
+
+        public String getName() {
+            return null;
+        }
+    }
+
+}
\ No newline at end of file