diff --git a/core/src/net/sf/openrocket/startup/ApplicationModule.java b/core/src/net/sf/openrocket/startup/ApplicationModule.java index 20590d57c..16932e968 100644 --- a/core/src/net/sf/openrocket/startup/ApplicationModule.java +++ b/core/src/net/sf/openrocket/startup/ApplicationModule.java @@ -4,8 +4,6 @@ import net.sf.openrocket.gui.watcher.WatchService; import net.sf.openrocket.gui.watcher.WatchServiceImpl; import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.logging.LogHelper; -import net.sf.openrocket.util.watcher.DirectoryChangeReactor; -import net.sf.openrocket.util.watcher.DirectoryChangeReactorImpl; import com.google.inject.AbstractModule; @@ -16,7 +14,6 @@ public class ApplicationModule extends AbstractModule { bind(LogHelper.class).toInstance(Application.getLogger()); bind(Preferences.class).toInstance(Application.getPreferences()); bind(Translator.class).toInstance(Application.getTranslator()); - bind(DirectoryChangeReactor.class).to(DirectoryChangeReactorImpl.class); bind(WatchService.class).to(WatchServiceImpl.class); } diff --git a/core/src/net/sf/openrocket/util/watcher/Directory.java b/core/src/net/sf/openrocket/util/watcher/Directory.java deleted file mode 100644 index 3d1269abb..000000000 --- a/core/src/net/sf/openrocket/util/watcher/Directory.java +++ /dev/null @@ -1,87 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.io.File; -import java.util.HashMap; - -/** - * A kind of watched file that is a directory. - */ -public class Directory extends WatchedFile { - - /** - * The contents. - */ - private final HashMap contents = new HashMap(); - - /** - * Internal lock object. - */ - private final Object lock = new Object(); - - /** - * Construct a directory to be watched. - * - * @param dir the directory to be watched - * - * @throws IllegalArgumentException if dir is null, does not exist, or is not a directory - */ - public Directory(File dir) throws IllegalArgumentException { - super(dir); - if (dir == null || !dir.isDirectory() || !dir.exists()) { - throw new IllegalArgumentException("Invalid directory."); - } - - init(); - } - - /** - * Initialize the directory handling. - */ - private void init() { - String[] result = list(); - for (String s : result) { - File t = new File(getTarget(), s); - if (t.exists()) { - contents.put(s, new WatchedFile(t)); - } - } - } - - /** - * Get the size of the directory's immediate contents (the number of files or subdirectories). - * - * @return the number of files and directories in this directory (not deep) - */ - public int size() { - return list().length; - } - - /** - * Get the list of filenames within this directory. - * - * @return an array of filenames - */ - String[] list() { - synchronized (lock) { - return getTarget().list(); - } - } - - /** - * Get the watched file contents. - * - * @return a map of watched files - */ - protected final HashMap getContents() { - return contents; - } - - /** - * Shared lock. - * - * @return a lock - */ - protected final Object getLock() { - return lock; - } -} diff --git a/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactor.java b/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactor.java deleted file mode 100644 index 75a66e9c1..000000000 --- a/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactor.java +++ /dev/null @@ -1,26 +0,0 @@ -package net.sf.openrocket.util.watcher; - -/** - * This interface abstracts the public API for a directory change reactor. In order to use the watcher subsystem, clients may use the default - * change reactor (that implements this interface), or use the WatchService directly. This interface is more of a convenience abstraction. - *

- * This only monitors directories. If you want to monitor an individual file, it is recommended that you monitor the directory that the file resides - * within, then filter the WatchEvents accordingly. - */ -public interface DirectoryChangeReactor { - - /** - * Register an event handler with the reactor. The event handler will be called when either a creation, modification, or deletion event is detected - * in the watched directory. Or a modification or a deletion event detected upon a watched file. - * - * @param theEventHandler the handler to be called when an event is detected - */ - void registerHandler(WatchedEventHandler theEventHandler); - - /** - * Unregister an event handler with the reactor. - * - * @param theEventHandler the handler - */ - void unregisterHandler(WatchedEventHandler theEventHandler); -} diff --git a/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactorImpl.java b/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactorImpl.java deleted file mode 100644 index c6736d05a..000000000 --- a/core/src/net/sf/openrocket/util/watcher/DirectoryChangeReactorImpl.java +++ /dev/null @@ -1,229 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import com.google.inject.Inject; - -import net.sf.openrocket.logging.LogHelper; - -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -/** - * This class is responsible for monitoring changes to files and directories and dispatching handle events appropriately. In order to use the watcher - * subsystem, clients may use the default change reactor (this class), or use the WatchService directly. This class is more of a convenience - * abstraction and doesn't necessarily represent the most efficient mechanism in all situations, but is sufficient for general purpose file watching - * (short of using JDK 7). - *

- * This reactor creates a new WatchService for each handler. A handler owns the business logic to be performed whenever a state change is detected in a - * monitored directory. Each handler can monitor one directory (and optionally that directory's subdirectories). It's possible to implement a - * different reactor that allows one handler to monitor many different directories or files. - *

- * The default polling interval is 5 seconds. To override the polling interval a system property (openrocket.watcher.poll) can be specified. The time - * value must be specified in milliseconds. - *

- * For example, to change the interval to 10 seconds: -Dopenrocket.watcher.poll=10000 - *

- *

- * Example Usage of this class: - *

- * 
- *
- * class MyHandler extends WatchedEventHandler  {
- *
- *   private Directory dirToWatch = new Directory(new File("/tmp"));
- *
- *   public Directory watchTarget() {
- *     return dirToWatch;
- *   }
- *
- *   public boolean watchRecursively() {
- *     return true;
- *   }
- *
- *   public void handleEvents(List> theEvents) {
- *     for (int i = 0; i < events.size(); i++) {
- *       WatchEvent watchEvent = events.get(i);
- *       // process the event
- *     }
- *   }
- * }
- * 
- *
- * Guice (assuming that the binding is performed in an appropriate module):
- * {@literal @}Inject
- *  DirectoryChangeReactor reactor;
- *  reactor.registerHandler(new MyHandler());
- *
- * Programmatically:
- *  DirectoryChangeReactor reactor = new DirectoryChangeReactorImpl();
- *  reactor.registerHandler(new MyHandler());
- * 
- */ -public class DirectoryChangeReactorImpl implements DirectoryChangeReactor { - - /** - * Property for polling frequency. - */ - public static final String WATCHER_POLLING_INTERVAL_PROPERTY = "openrocket.watcher.poll"; - /** - * The polling delay. Defaults to 5 seconds. - */ - public static final long DEFAULT_POLLING_DELAY = 5000; - /** - * The polling delay. Defaults to 5 seconds. - */ - private static long pollingDelay = DEFAULT_POLLING_DELAY; - - @Inject - private LogHelper log; - - /** - * Scheduler. - */ - private ScheduledExecutorService scheduler; - /** - * The ScheduledFuture. - */ - private ScheduledFuture directoryPollerFuture; - /** - * The runnable that does most of the work. - */ - private final DirectoryPoller directoryPoller = new DirectoryPoller(); - /** - * The collection of registered handlers. A new watch service is created for each handler. - */ - private final Map activeWatchers = new ConcurrentHashMap(); - /** - * Synchronization object. - */ - private final Object lock = new Object(); - - static { - try { - if (System.getProperty(WATCHER_POLLING_INTERVAL_PROPERTY) != null) { - pollingDelay = Long.parseLong(System.getProperty(WATCHER_POLLING_INTERVAL_PROPERTY)); - } - } - catch (Exception e) { - pollingDelay = DEFAULT_POLLING_DELAY; - } - } - - /** - * Constructor. - */ - public DirectoryChangeReactorImpl() { - this(LogHelper.getInstance()); - } - - /** - * Injected constructor. - */ - @Inject - public DirectoryChangeReactorImpl(LogHelper theLogger) { - log = theLogger; - startup(); - } - - /** - * Idempotent initialization. - */ - private void startup() { - - synchronized (lock) { - if (scheduler != null) { - scheduler.shutdownNow(); - } - scheduler = Executors.newScheduledThreadPool(1); - - scheduleFuture(); - } - } - - /** - * Cause all watch services to close. This method is idempotent. - */ - public void shutdown() { - synchronized (lock) { - - if (scheduler != null) { - scheduler.shutdownNow(); - } - for (Iterator iterator = activeWatchers.keySet().iterator(); iterator.hasNext(); ) { - WatchedEventHandler next = iterator.next(); - activeWatchers.get(next).close(); - iterator.remove(); - } - } - } - - @Override - public void registerHandler(WatchedEventHandler theEventHandler) { - synchronized (lock) { - unregisterHandler(theEventHandler); - final WatchService watchService = new WatchService(theEventHandler.watchRecursively()); - watchService.register(theEventHandler.watchTarget()); - activeWatchers.put(theEventHandler, watchService); - } - - } - - @Override - public void unregisterHandler(WatchedEventHandler theEventHandler) { - synchronized (lock) { - if (activeWatchers.containsKey(theEventHandler)) { - activeWatchers.get(theEventHandler).close(); - activeWatchers.remove(theEventHandler); - } - } - } - - /** - * Schedule the periodic poll. - */ - private void scheduleFuture() { - if (directoryPollerFuture != null - && !directoryPollerFuture.isDone() - && !directoryPollerFuture.isCancelled()) { - directoryPollerFuture.cancel(false); - } - directoryPollerFuture = scheduler.schedule(directoryPoller, pollingDelay, TimeUnit.MILLISECONDS); - } - - /** - * This runnable is responsible for checking all watch services for new events. - */ - private final class DirectoryPoller implements Runnable { - @Override - public void run() { - try { - if (!activeWatchers.isEmpty()) { - for (Iterator iterator = activeWatchers.keySet().iterator(); iterator.hasNext(); ) { - WatchedEventHandler next = iterator.next(); - try { - WatchService watchService = activeWatchers.get(next); - Collection watchKeyCollection = watchService.poll(); - if (!watchKeyCollection.isEmpty()) { - for (WatchService.WatchKey watchKey : watchKeyCollection) { - next.handleEvents(watchKey.pollEvents()); - } - } - } - catch (Exception e) { - log.error("Error notifying handler of watch event. Removing registration.", e); - iterator.remove(); - } - } - } - } - finally { - scheduleFuture(); - } - } - } -} \ No newline at end of file diff --git a/core/src/net/sf/openrocket/util/watcher/DirectoryMonitor.java b/core/src/net/sf/openrocket/util/watcher/DirectoryMonitor.java deleted file mode 100644 index 681f1ae15..000000000 --- a/core/src/net/sf/openrocket/util/watcher/DirectoryMonitor.java +++ /dev/null @@ -1,231 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.io.File; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -/** - * This class checks for changes in directories. Supported events: file creation, subdirectory creation, file modification, file and subdirectory - * deletion. - *

- * Synchronize calls to this class externally to ensure thread safety. - */ -final class DirectoryMonitor { - - /** - * The directories being monitored. - */ - private Set monitored = new HashSet(); - - /** - * Flag that indicates if subdirectories should automatically be monitored when they are created. - */ - private boolean monitorSubdirectories = false; - - /** - * Constructor. Self registration is set to false. - */ - DirectoryMonitor() { - this(false); - } - - /** - * Constructor. - * - * @param monitorOnCreate if true auto-monitor new subdirectories - */ - DirectoryMonitor(boolean monitorOnCreate) { - monitorSubdirectories = monitorOnCreate; - } - - /** - * Register a directory to be monitored for changes. - * - * @param dir directory to monitor - */ - void register(final Directory dir) { - if (dir != null && !monitored.contains(dir)) { - monitored.add(dir); - if (monitorSubdirectories) { - recurse(dir); - } - } - } - - private void recurse(final Directory dir) { - synchronized (dir.getLock()) { - String[] list = dir.list(); - for (String file : list) { - final File f = new File(dir.getTarget(), file); - if (f.isDirectory()) { - register(new Directory(f)); - } - } - } - } - - /** - * Clear/close and resources being monitored. - */ - void close() { - monitored.clear(); - } - - /** - * Unregister a directory. - * - * @param dir - */ - private void unregister(Directory dir) { - if (dir != null) { - monitored.remove(dir); - } - } - - /** - * - * The main business logic of this directory monitor. - * - * @return a WatchEvent instance or null - */ - Collection check() { - Map result = new HashMap(); - - for (Directory directory : monitored) { - synchronized (directory.getLock()) { - if (directory.exists()) { - Map watchedFiles = (Map) directory.getContents().clone(); - String[] filesCurrentlyInDirectory = directory.list(); - for (String s : filesCurrentlyInDirectory) { - if (directory.getContents().containsKey(s)) { - WatchEvent we = directory.getContents().get(s).check(); - if (!we.equals(WatchEvent.NO_EVENT)) { - add(result, directory, we); - } - } - else { - final File f = new File(directory.getTarget(), s); - WatchedFile nf = new WatchedFile(f); - add(result, directory, nf.createEvent()); - directory.getContents().put(s, nf); - if (f.isDirectory() && monitorSubdirectories) { - register(new Directory(f)); - } - } - watchedFiles.remove(s); - } - - for (String file : watchedFiles.keySet()) { - WatchEvent we = watchedFiles.get(file).check(); - if (!we.equals(WatchEvent.NO_EVENT)) { - add(result, directory, we); - if (we.kind().equals(WatchEventKind.ENTRY_DELETE)) { - directory.getContents().remove(file); - } - } - } - } - else { - add(result, directory, new DirectoryWatchEvent(WatchEventKind.ENTRY_DELETE, directory.getTarget())); - unregister(directory); - } - } - } - return result.values(); - } - - private void add(Map keyList, Directory dir, WatchEvent we) { - WatchKeyImpl key = keyList.get(dir); - if (key == null) { - key = new WatchKeyImpl(dir); - keyList.put(dir, key); - } - key.add(we); - } - - /** - * WatchKey impl. - */ - private class WatchKeyImpl implements WatchService.WatchKey { - - /** - * The target. - */ - private Directory watchKey; - - /** - * The list of events. - */ - private List> list = new ArrayList>(); - - /** - * Constructor. - * - * @param theKey - */ - WatchKeyImpl(Directory theKey) { - watchKey = theKey; - } - - @Override - public void cancel() { - unregister(watchKey); - } - - @Override - public List> pollEvents() { - return list; - } - - /** - * Add an event. - * - * @param event an event - */ - void add(WatchEvent event) { - list.add(event); - } - } - - /** - * A class that depicts an event upon a directory. - */ - private class DirectoryWatchEvent implements WatchEvent { - - /** - * The type of the event. - */ - private final Kind type; - - /** - * The resource target. - */ - private final File target; - - /** - * Constructor. - * - * @param theType the kind of the event - * @param theTarget the target directory file - */ - DirectoryWatchEvent(Kind theType, File theTarget) { - type = theType; - target = theTarget; - } - - @Override - public File context() { - return target; - } - - @Override - public Kind kind() { - return type; - } - } -} diff --git a/core/src/net/sf/openrocket/util/watcher/WatchEvent.java b/core/src/net/sf/openrocket/util/watcher/WatchEvent.java deleted file mode 100644 index 832bc431e..000000000 --- a/core/src/net/sf/openrocket/util/watcher/WatchEvent.java +++ /dev/null @@ -1,49 +0,0 @@ -package net.sf.openrocket.util.watcher; - -/** - * Mimics the JDK 7 implementation. - *

- * the type of the context object of the event - */ -public interface WatchEvent { - - /** - * Defines the target of the event. - * - * @return the entity for which the event was generated - */ - T context(); - - /** - * Defines the type of event. - * - * @return the kind of event - */ - WatchEvent.Kind kind(); - - /** - * Defines an API for a kind of event. - * - * @param - */ - static interface Kind { - String name(); - - Class type(); - } - - /** - * A null-object idiom event. - */ - public static final WatchEvent NO_EVENT = new WatchEvent() { - @Override - public Void context() { - return null; - } - - @Override - public Kind kind() { - return null; - } - }; -} diff --git a/core/src/net/sf/openrocket/util/watcher/WatchEventKind.java b/core/src/net/sf/openrocket/util/watcher/WatchEventKind.java deleted file mode 100644 index bb3b38681..000000000 --- a/core/src/net/sf/openrocket/util/watcher/WatchEventKind.java +++ /dev/null @@ -1,75 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.io.File; - -/** - * Mimics the kind of watch event in JDK 7. - */ -public final class WatchEventKind { - - /** - * An entry was created. - */ - public static final WatchEvent.Kind ENTRY_CREATE = new WatchEvent.Kind() { - @Override - public String name() { - return "ENTRY_CREATE"; - } - - @Override - public Class type() { - return File.class; - } - - @Override - public String toString() { - return name(); - } - }; - - /** - * An existing entry was deleted. - */ - public static final WatchEvent.Kind ENTRY_DELETE = new WatchEvent.Kind() { - @Override - public String name() { - return "ENTRY_DELETE"; - } - - @Override - public Class type() { - return File.class; - } - - @Override - public String toString() { - return name(); - } - }; - - /** - * An existing entry was modified. - */ - public static final WatchEvent.Kind ENTRY_MODIFY = new WatchEvent.Kind() { - @Override - public String name() { - return "ENTRY_MODIFY"; - } - - @Override - public Class type() { - return File.class; - } - - @Override - public String toString() { - return name(); - } - }; - - /** - * Disallow instantiation. - */ - private WatchEventKind() { - } -} diff --git a/core/src/net/sf/openrocket/util/watcher/WatchService.java b/core/src/net/sf/openrocket/util/watcher/WatchService.java deleted file mode 100644 index d96f49e78..000000000 --- a/core/src/net/sf/openrocket/util/watcher/WatchService.java +++ /dev/null @@ -1,160 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.io.File; -import java.util.Collection; -import java.util.List; -import java.util.concurrent.TimeUnit; - -/** - * A service that allows consumers to watch for changes to a directory or directories. This class manages the checking - * of state changes for one or more directories. Directories are the primary entity being monitored. - * Events detected include the creation of a file, creation of a subdirectory, the modification - * of a file, and the deletion of a file or subdirectory. - *

- * JDK 7 includes a WatchService, upon which this is loosely based. This implementation is JDK 6 compatible. - *

- * A limitation of this implementation is that it is polling based, not event driven. Also note, that this only monitors directories. If you want - * to monitor an individual file, it is recommended that you monitor the directory that the file resides within, - * then filter the WatchEvents accordingly. - * - * Example usage: - *

- *

- *     WatchService watcher = new WatchService();
- *     watcher.register(new File("/tmp"));
- *     ...
- *     Collection changed = watcher.poll();
- *     for (Iterator iterator = co.iterator(); iterator.hasNext(); ) {
- *        WatchKey key = iterator.next();
- *        //Do something with the WatchEvents in the key
- *     }
- *
- *     
- *

- */ -public class WatchService { - - /** - * An interface that defines keys of events. - */ - public static interface WatchKey { - /** - * Cancel the registration of the directory for which this key relates. - */ - void cancel(); - - /** - * Get a list of events detected for this key. - * - * @return a list, not null, of events - */ - List> pollEvents(); - } - - /** - * The manager of all directory monitoring. - */ - private final DirectoryMonitor monitor; - - /** - * Constructor. - */ - public WatchService() { - monitor = new DirectoryMonitor(); - } - - /** - * Constructor. - * - * @param watchRecursively if true, directories will be watched recursively - */ - public WatchService(boolean watchRecursively) { - monitor = new DirectoryMonitor(watchRecursively); - } - - /** - * Polling method to get a collection of keys that indicate events detected upon one or more files within a - * monitored directory. Each key represents one directory. The list of events represents changes to one or more - * files within that directory. Will not block and return immediately, even if there are no keys ready. - * - * @return a collection of keys; guaranteed not to be null but may be empty - */ - public Collection poll() { - return monitor.check(); - } - - /** - * Polling method to get a collection of keys that indicate events detected upon one or more files within a - * monitored directory. Each key represents one directory. The list of events represents changes to one or more - * files within that directory. Will block for a defined length of time if there are no keys ready. - * - * @param time the amount of time before the method returns - * @param unit the unit of time - * - * @return a collection of keys; guaranteed not to be null but may be empty - */ - public Collection poll(long time, TimeUnit unit) { - Collection result = monitor.check(); - if (result != null && !result.isEmpty()) { - return result; - } - - try { - Thread.sleep(unit.toMillis(time)); - } catch (InterruptedException e) { - } - return monitor.check(); - } - - /** - * Blocking method to get a collection of keys that indicate events detected upon one or more files within a - * monitored directory. Each key represents one directory. The list of events represents changes to one or more - * files within that directory. - * - * @return a collection of keys; guaranteed not to be null but may be empty - */ - public Collection take() { - long wait = 60000; - Collection result = null; - do { - result = poll(wait, TimeUnit.MILLISECONDS); - } while (result == null || result.isEmpty()); - return result; - } - - /** - * Close the service and release any resources currently being used. - */ - public void close() { - monitor.close(); - } - - /** - * Register a directory to be watched by this service. The file f must not be null and must refer to a directory - * that exists. Registration is idempotent - it can be called multiple times for the same directory with no ill - * effect. - * - * @param f the target directory to watch - * - * @throws IllegalArgumentException thrown if f is null, does not exist, or is not a directory - */ - public void register(File f) throws IllegalArgumentException { - monitor.register(new Directory(f)); - } - - /** - * Register a directory to be watched by this service. The file f must not be null and must refer to a directory - * that exists. Registration is idempotent - it can be called multiple times for the same directory with no ill - * effect. - * - * @param dir the target directory to watch - * - * @throws IllegalArgumentException thrown if dir is null - */ - public void register(Directory dir) throws IllegalArgumentException { - if (dir == null) { - throw new IllegalArgumentException("The directory may not be null."); - } - monitor.register(dir); - } -} diff --git a/core/src/net/sf/openrocket/util/watcher/WatchedEventHandler.java b/core/src/net/sf/openrocket/util/watcher/WatchedEventHandler.java deleted file mode 100644 index 64a184857..000000000 --- a/core/src/net/sf/openrocket/util/watcher/WatchedEventHandler.java +++ /dev/null @@ -1,33 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.util.List; - -/** - * The public contract that must be implemented by clients wanting to register an interest in, and receive notification of, - * changes to a directory or file. - */ -public interface WatchedEventHandler { - - /** - * Get the target being watched. - * - * @return a instance of a watched file - */ - W watchTarget(); - - /** - * If the target is a directory, then answer if subdirectories should also be watched for state changes. The watched target is a file, this has no - * meaning. - * - * @return true if directories are to be watched recursively (watch all subdirectories et. al.) - */ - boolean watchRecursively(); - - /** - * Callback method. This is invoked by the reactor whenever events are detected upon the target. - * - * @param theEvents a list of detected events; it's a list because if the target is a directory, potentially many files within the directory were - * affected - */ - void handleEvents(List> theEvents); -} diff --git a/core/src/net/sf/openrocket/util/watcher/WatchedFile.java b/core/src/net/sf/openrocket/util/watcher/WatchedFile.java deleted file mode 100644 index 40de53ea7..000000000 --- a/core/src/net/sf/openrocket/util/watcher/WatchedFile.java +++ /dev/null @@ -1,148 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import java.io.File; - -/** - * Models a file on the filesystem that is being watched for state changes (other than creation). - */ -class WatchedFile { - - /** - * The last timestamp of the file. - */ - private long timeStamp; - - /** - * The file to watch. - */ - private final File target; - - /** - * Constructor. - * - * @param aFile the file to watch - * - * @throws IllegalArgumentException thrown if aFile is null - */ - WatchedFile(File aFile) throws IllegalArgumentException { - if (aFile == null) { - throw new IllegalArgumentException("The file may not be null."); - } - target = aFile; - timeStamp = target.lastModified(); - } - - /** - * Create a 'create' event. - * - * @return a watch event indicating the file was created - */ - WatchEvent createEvent() { - return new FileWatchEvent(WatchEventKind.ENTRY_CREATE); - } - - /** - * Get the watched target. - * - * @return the file being monitored - */ - File getTarget() { - return target; - } - - /** - * Detects if any changes have been made to the file. This is a 'destructive' read in the sense that it is not - * idempotent. The act of checking for changes resets the internal state and subsequent checks will indicate - * no changes until the next physical change. - * - * @return a WatchEvent instance or null if no event - */ - public final WatchEvent check() { - - if (!target.exists()) { - return new FileWatchEvent(WatchEventKind.ENTRY_DELETE); - } - - long latest = target.lastModified(); - - if (timeStamp != latest) { - timeStamp = latest; - return new FileWatchEvent(WatchEventKind.ENTRY_MODIFY); - } - return WatchEvent.NO_EVENT; - } - - /** - * Delegates existence check to the target. - * - * @return true if exists - */ - public boolean exists() { - return target.exists(); - } - - /** - * Determine equivalence to a given object. - * - * @param o another watched file - * - * @return true if the underlying file is the same - */ - @Override - public boolean equals(final Object o) { - if (this == o) { - return true; - } - if (!(o instanceof WatchedFile)) { - return false; - } - - final WatchedFile that = (WatchedFile) o; - - if (!target.equals(that.target)) { - return false; - } - - return true; - } - - /** - * Compute hash code. - * - * @return a hash value - */ - @Override - public int hashCode() { - return target.hashCode(); - } - - /** - * A class that depicts events that occur upon a file. - */ - protected class FileWatchEvent implements WatchEvent { - - /** - * The kind of event. - */ - private Kind type; - - /** - * Constructor. - * - * @param theType the - */ - FileWatchEvent(Kind theType) { - type = theType; - } - - @Override - public File context() { - return target; - } - - @Override - public Kind kind() { - return type; - } - } -} \ No newline at end of file diff --git a/core/test/net/sf/openrocket/util/watcher/DirectoryChangeReactorImplTest.java b/core/test/net/sf/openrocket/util/watcher/DirectoryChangeReactorImplTest.java deleted file mode 100644 index 2f8d9719d..000000000 --- a/core/test/net/sf/openrocket/util/watcher/DirectoryChangeReactorImplTest.java +++ /dev/null @@ -1,162 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.util.List; - -/** - */ -public class DirectoryChangeReactorImplTest { - - @Test - public void testRegisterHandler() throws Exception { - DirectoryChangeReactorImpl impl = new DirectoryChangeReactorImpl(); - - final File tempDir = DirectoryTest.createTempDir(); - tempDir.setWritable(true); - Directory directory = new Directory(tempDir); - File f1 = null; - File f2 = null; - - File sub = null; - Directory subdir; - - try { - WatchedEventHandlerImpl testHandler = new WatchedEventHandlerImpl(directory); - impl.registerHandler(testHandler); - - String baseName = System.currentTimeMillis() + "--"; - - f1 = new File(tempDir.getAbsolutePath(), baseName + "1"); - f1.createNewFile(); - long totalSleepTime = 0; - WatchEvent.Kind kind = null; - while (totalSleepTime < DirectoryChangeReactorImpl.DEFAULT_POLLING_DELAY + 1000) { - kind = testHandler.getKind(); - if (kind != null) { - break; - } - Thread.sleep(1000); - totalSleepTime += 1000; - } - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, kind); - Assert.assertEquals(testHandler.eventTarget, f1); - - f1.setLastModified(System.currentTimeMillis() + 10000); - totalSleepTime = 0; - kind = null; - while (totalSleepTime < DirectoryChangeReactorImpl.DEFAULT_POLLING_DELAY + 400) { - kind = testHandler.getKind(); - if (kind != null) { - break; - } - Thread.sleep(1000); - totalSleepTime += 1000; - } - Assert.assertEquals(WatchEventKind.ENTRY_MODIFY, kind); - Assert.assertEquals(testHandler.eventTarget, f1); - - f1.delete(); - totalSleepTime = 0; - kind = null; - while (totalSleepTime < DirectoryChangeReactorImpl.DEFAULT_POLLING_DELAY + 400) { - kind = testHandler.getKind(); - if (kind != null) { - break; - } - Thread.sleep(1000); - totalSleepTime += 1000; - } - Assert.assertEquals(WatchEventKind.ENTRY_DELETE, kind); - Assert.assertEquals(testHandler.eventTarget, f1); - - //test recursive nature of monitoring subdirectories - sub = DirectoryTest.createTempDir(tempDir); - subdir = new Directory(sub); - - totalSleepTime = 0; - kind = null; - while (totalSleepTime < DirectoryChangeReactorImpl.DEFAULT_POLLING_DELAY + 400) { - kind = testHandler.getKind(); - if (kind != null) { - break; - } - Thread.sleep(1000); - totalSleepTime += 1000; - } - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, kind); - Assert.assertEquals(testHandler.eventTarget, sub); - - f2 = new File(sub.getAbsolutePath(), baseName + "2"); - f2.createNewFile(); - totalSleepTime = 0; - kind = null; - while (totalSleepTime < DirectoryChangeReactorImpl.DEFAULT_POLLING_DELAY + 400) { - kind = testHandler.getKind(); - if (kind != null) { - break; - } - Thread.sleep(1000); - totalSleepTime += 1000; - } - //Eventually, both events will show up, but it's system dependent which one we get first, and if - //they both arrive together or on different polling cycles. This could be embellished, but for now - //just see if at least one arrives. - if (kind.equals(WatchEventKind.ENTRY_CREATE)) { - Assert.assertEquals(f2, testHandler.eventTarget); - } - else if (kind.equals(WatchEventKind.ENTRY_MODIFY)) { - Assert.assertEquals(sub, testHandler.eventTarget); - } - - } - finally { - if (f1 != null) { - f1.delete(); - } - if (sub != null) { - sub.delete(); - } - directory.getTarget().delete(); - impl.shutdown(); - } - } - - static class WatchedEventHandlerImpl implements WatchedEventHandler { - Directory file = null; - Object eventTarget = null; - - WatchEvent.Kind kind = null; - - WatchedEventHandlerImpl(final Directory theFile) { - file = theFile; - } - - @Override - public Directory watchTarget() { - return file; - } - - @Override - public boolean watchRecursively() { - return true; - } - - public WatchEvent.Kind getKind() { - WatchEvent.Kind tmp = kind; - kind = null; - return tmp; - } - - @Override - public void handleEvents(final List> theEvents) { - for (int i = 0; i < theEvents.size(); i++) { - WatchEvent watchEvent = theEvents.get(i); - kind = watchEvent.kind(); - eventTarget = watchEvent.context(); - } - } - } -} diff --git a/core/test/net/sf/openrocket/util/watcher/DirectoryMonitorTest.java b/core/test/net/sf/openrocket/util/watcher/DirectoryMonitorTest.java deleted file mode 100644 index 1aee06e4e..000000000 --- a/core/test/net/sf/openrocket/util/watcher/DirectoryMonitorTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; -import java.util.Collection; -import java.util.List; - -/** - */ -public class DirectoryMonitorTest { - - @Test - public void testCheck() throws Exception { - final File tempDir = DirectoryTest.createTempDir(); - tempDir.setWritable(true); - Directory directory = new Directory(tempDir); - File f1 = null; - File f2 = null; - File f3 = null; - try { - - DirectoryMonitor monitor = new DirectoryMonitor(); - monitor.register(directory); - - String baseName = System.currentTimeMillis() + "--"; - - f1 = new File(tempDir.getAbsolutePath(), baseName + "1"); - f1.createNewFile(); - f2 = new File(tempDir.getAbsolutePath(), baseName + "2"); - f2.createNewFile(); - f3 = new File(tempDir.getAbsolutePath(), baseName + "3"); - f3.createNewFile(); - - Collection keys = monitor.check(); - Assert.assertEquals(1, keys.size()); - WatchService.WatchKey wk = keys.iterator().next(); - List> events = wk.pollEvents(); - - Assert.assertEquals(3, events.size()); - for (int i = 0; i < events.size(); i++) { - WatchEvent watchEvent = events.get(i); - if (watchEvent.context().equals(f1)) { - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, watchEvent.kind()); - } - else if (watchEvent.context().equals(f2)) { - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, watchEvent.kind()); - } - else if (watchEvent.context().equals(f3)) { - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, watchEvent.kind()); - } - else { - System.err.println(watchEvent.context().toString()); - Assert.fail("Unknown target file."); - } - } - - f1.setLastModified(System.currentTimeMillis() + 10007); - f1.setReadable(true); - Thread.sleep(1000); - keys = monitor.check(); - Assert.assertEquals(1, keys.size()); - WatchService.WatchKey watchEvent = keys.iterator().next(); - Assert.assertEquals(1, watchEvent.pollEvents().size()); - Assert.assertEquals(f1, watchEvent.pollEvents().get(0).context()); - Assert.assertEquals(WatchEventKind.ENTRY_MODIFY, watchEvent.pollEvents().get(0).kind()); - } - finally { - if (f1 != null) { - f1.delete(); - } - if (f2 != null) { - f2.delete(); - } - if (f3 != null) { - f3.delete(); - } - directory.getTarget().delete(); - } - - } -} diff --git a/core/test/net/sf/openrocket/util/watcher/DirectoryTest.java b/core/test/net/sf/openrocket/util/watcher/DirectoryTest.java deleted file mode 100644 index a27cf296a..000000000 --- a/core/test/net/sf/openrocket/util/watcher/DirectoryTest.java +++ /dev/null @@ -1,177 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; - -/** - */ -public class DirectoryTest { - - @Test - public void testConstructor() throws Exception { - try { - new Directory(null); - Assert.fail(); - } - catch (IllegalArgumentException iae) { - //success - } - try { - new Directory(new File("foo")); - Assert.fail(); - } - catch (IllegalArgumentException iae) { - //success - } - } - - @Test - public void testSize() throws Exception { - final File tempDir = createTempDir(); - tempDir.setWritable(true); - Directory directory = new Directory(tempDir); - File f1 = null; - File f2 = null; - File f3 = null; - try { - Assert.assertTrue(directory.exists()); - Assert.assertEquals(0, directory.size()); - - String baseName = System.currentTimeMillis() + "--"; - - f1 = new File(tempDir.getAbsolutePath(), baseName + "1"); - f1.createNewFile(); - f2 = new File(tempDir.getAbsolutePath(), baseName + "2"); - f2.createNewFile(); - f3 = new File(tempDir.getAbsolutePath(), baseName + "3"); - f3.createNewFile(); - - Assert.assertEquals(3, directory.size()); - } - finally { - if (f1 != null) { - f1.delete(); - } - if (f2 != null) { - f2.delete(); - } - if (f3 != null) { - f3.delete(); - } - directory.getTarget().delete(); - } - } - - @Test - public void testList() throws Exception { - final File tempDir = createTempDir(); - tempDir.setWritable(true); - Directory directory = new Directory(tempDir); - File f1 = null; - File f2 = null; - File f3 = null; - try { - Assert.assertTrue(directory.exists()); - Assert.assertEquals(0, directory.size()); - - String baseName = System.currentTimeMillis() + "--"; - - f1 = new File(tempDir.getAbsolutePath(), baseName + "1"); - f1.createNewFile(); - f2 = new File(tempDir.getAbsolutePath(), baseName + "2"); - f2.createNewFile(); - f3 = new File(tempDir.getAbsolutePath(), baseName + "3"); - f3.createNewFile(); - - String[] files = directory.list(); - for (int i = 0; i < files.length; i++) { - String file = files[i]; - if (file.endsWith("1")) { - Assert.assertEquals(baseName + "1", file); - } - else if (file.endsWith("2")) { - Assert.assertEquals(baseName + "2", file); - } - else if (file.endsWith("3")) { - Assert.assertEquals(baseName + "3", file); - } - else { - Assert.fail(); - } - } - } - finally { - if (f1 != null) { - f1.delete(); - } - if (f2 != null) { - f2.delete(); - } - if (f3 != null) { - f3.delete(); - } - directory.getTarget().delete(); - } - } - - @Test - public void testContents() throws Exception { - final File tempDir = createTempDir(); - tempDir.setWritable(true); - Directory directory = new Directory(tempDir); - File f1 = null; - File f2 = null; - File f3 = null; - try { - String baseName = System.currentTimeMillis() + "--"; - - f1 = new File(tempDir.getAbsolutePath(), baseName + "1"); - f1.createNewFile(); - f2 = new File(tempDir.getAbsolutePath(), baseName + "2"); - f2.createNewFile(); - f3 = new File(tempDir.getAbsolutePath(), baseName + "3"); - f3.createNewFile(); - - Assert.assertEquals(0, directory.getContents().size()); - - //Contents is initialized at the time Directory is created. Since we had to create it for the test, - //we need a second Directory instance. - Directory directory1 = new Directory(tempDir); - Assert.assertEquals(3, directory1.getContents().size()); - } - finally { - if (f1 != null) { - f1.delete(); - } - if (f2 != null) { - f2.delete(); - } - if (f3 != null) { - f3.delete(); - } - directory.getTarget().delete(); - } - } - - //Borrowed from Google's Guava. - public static File createTempDir() { - File baseDir = new File(System.getProperty("java.io.tmpdir")); - return createTempDir(baseDir); - } - - public static File createTempDir(File parent) { - String baseName = System.currentTimeMillis() + "-"; - - for (int counter = 0; counter < 2; counter++) { - File tempDir = new File(parent, baseName + counter); - if (tempDir.mkdir()) { - return tempDir; - } - } - throw new IllegalStateException("Failed to create directory within " - + 2 + " attempts (tried " - + baseName + "0 to " + baseName + (2 - 1) + ')'); - } -} diff --git a/core/test/net/sf/openrocket/util/watcher/WatchedFileTest.java b/core/test/net/sf/openrocket/util/watcher/WatchedFileTest.java deleted file mode 100644 index 187648104..000000000 --- a/core/test/net/sf/openrocket/util/watcher/WatchedFileTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package net.sf.openrocket.util.watcher; - -import org.junit.Assert; -import org.junit.Test; - -import java.io.File; - -/** - */ -public class WatchedFileTest { - - @Test - public void testConstructor() throws Exception { - try { - new WatchedFile(null); - Assert.fail(); - } - catch (IllegalArgumentException iae) { - //success - } - - final File blah = new File("blah"); - WatchedFile wf = new WatchedFile(blah); - Assert.assertEquals(blah, wf.getTarget()); - } - - @Test - public void testCreateEvent() throws Exception { - final File blah = new File("blah"); - WatchedFile wf = new WatchedFile(blah); - Assert.assertEquals(blah, wf.createEvent().context()); - Assert.assertEquals(WatchEventKind.ENTRY_CREATE, wf.createEvent().kind()); - } - - @Test - public void testExists() throws Exception { - final File blah = new File("blah"); - WatchedFile wf = new WatchedFile(blah); - Assert.assertFalse(wf.exists()); - } - - @Test - public void testCheck() throws Exception { - final File blah = new File("blah"); - WatchedFile wf = new WatchedFile(blah); - - WatchEvent check = wf.check(); - Assert.assertEquals(WatchEventKind.ENTRY_DELETE, check.kind()); - - File f = File.createTempFile("tmp", "tmp"); - wf = new WatchedFile(f); - - check = wf.check(); - Assert.assertEquals(WatchEvent.NO_EVENT, check); - - f.setLastModified(System.currentTimeMillis() - 60000); - check = wf.check(); - Assert.assertEquals(WatchEventKind.ENTRY_MODIFY, check.kind()); - Assert.assertEquals(f, check.context()); - - //Check for reset of state - check = wf.check(); - Assert.assertEquals(WatchEvent.NO_EVENT, check); - } - - @Test - public void testEquals() throws Exception { - final File blah = new File("blah"); - final File blech = new File("blech"); - WatchedFile wf1 = new WatchedFile(blah); - WatchedFile wf2 = new WatchedFile(blah); - WatchedFile wf3 = new WatchedFile(blech); - - Assert.assertEquals(wf1, wf1); - Assert.assertEquals(wf1, wf2); - Assert.assertFalse(wf1.equals(wf3)); - Assert.assertFalse(wf1.equals(null)); - Assert.assertFalse(wf1.equals(new Object())); - - Assert.assertEquals(wf1.hashCode(), wf2.hashCode()); - } -}