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