diff --git a/components/net/sf/briar/plugins/file/LinuxRemovableDriveMonitor.java b/components/net/sf/briar/plugins/file/LinuxRemovableDriveMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..71a3e838ae3786861d79b8bbbddfa7fca2894664 --- /dev/null +++ b/components/net/sf/briar/plugins/file/LinuxRemovableDriveMonitor.java @@ -0,0 +1,9 @@ +package net.sf.briar.plugins.file; + +class LinuxRemovableDriveMonitor extends UnixRemovableDriveMonitor { + + @Override + protected String[] getPathsToWatch() { + return new String[] { "/mnt", "/media" }; + } +} diff --git a/components/net/sf/briar/plugins/file/MacRemovableDriveMonitor.java b/components/net/sf/briar/plugins/file/MacRemovableDriveMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..e2886facbc6cc56d73edc2c673979110c1c942a7 --- /dev/null +++ b/components/net/sf/briar/plugins/file/MacRemovableDriveMonitor.java @@ -0,0 +1,9 @@ +package net.sf.briar.plugins.file; + +class MacRemovableDriveMonitor extends UnixRemovableDriveMonitor { + + @Override + protected String[] getPathsToWatch() { + return new String[] { "/Volumes" }; + } +} diff --git a/components/net/sf/briar/plugins/file/PollingRemovableDriveMonitor.java b/components/net/sf/briar/plugins/file/PollingRemovableDriveMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..f693aa6a9985dfb1c1c5d220406d3bd4877709a7 --- /dev/null +++ b/components/net/sf/briar/plugins/file/PollingRemovableDriveMonitor.java @@ -0,0 +1,89 @@ +package net.sf.briar.plugins.file; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable { + + private final RemovableDriveFinder finder; + private final long pollingInterval; + private final LinkedList<File> inserted; + private final LinkedList<IOException> exceptions; + private final Object pollingLock; + + private boolean started = false, stopped = false; + private Thread pollingThread = null; + + public PollingRemovableDriveMonitor(RemovableDriveFinder finder, + long pollingInterval) { + this.finder = finder; + this.pollingInterval = pollingInterval; + inserted = new LinkedList<File>(); + exceptions = new LinkedList<IOException>(); + pollingLock = new Object(); + } + + public synchronized void start() throws IOException { + if(started || stopped) throw new IllegalStateException(); + started = true; + pollingThread = new Thread(this); + pollingThread.start(); + } + + public synchronized File waitForInsertion() throws IOException { + if(!started || stopped) throw new IllegalStateException(); + if(!exceptions.isEmpty()) throw exceptions.poll(); + while(inserted.isEmpty()) { + try { + wait(); + } catch(InterruptedException ignored) {} + if(!exceptions.isEmpty()) throw exceptions.poll(); + } + return inserted.poll(); + } + + public synchronized void stop() throws IOException { + if(!started || stopped) throw new IllegalStateException(); + if(!exceptions.isEmpty()) throw exceptions.poll(); + stopped = true; + synchronized(pollingLock) { + pollingLock.notifyAll(); + } + } + + public void run() { + try { + List<File> drives = finder.findRemovableDrives(); + while(true) { + synchronized(this) { + if(stopped) return; + } + synchronized(pollingLock) { + try { + pollingLock.wait(pollingInterval); + } catch(InterruptedException ignored) {} + } + synchronized(this) { + if(stopped) return; + } + List<File> newDrives = finder.findRemovableDrives(); + for(File f : newDrives) { + if(!drives.contains(f)) { + synchronized(this) { + inserted.add(f); + notifyAll(); + } + } + } + drives = newDrives; + } + } catch(IOException e) { + synchronized(this) { + exceptions.add(e); + notifyAll(); + } + } + } +} diff --git a/components/net/sf/briar/plugins/file/RemovableDriveMonitor.java b/components/net/sf/briar/plugins/file/RemovableDriveMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..3ce0cc5f27b716edfb44e00ca206b28f9994fcd9 --- /dev/null +++ b/components/net/sf/briar/plugins/file/RemovableDriveMonitor.java @@ -0,0 +1,13 @@ +package net.sf.briar.plugins.file; + +import java.io.File; +import java.io.IOException; + +interface RemovableDriveMonitor { + + void start() throws IOException; + + File waitForInsertion() throws IOException; + + void stop() throws IOException; +} diff --git a/components/net/sf/briar/plugins/file/UnixRemovableDriveMonitor.java b/components/net/sf/briar/plugins/file/UnixRemovableDriveMonitor.java new file mode 100644 index 0000000000000000000000000000000000000000..3a211cc509063e41839fc1d5c73195a2eac4ed1b --- /dev/null +++ b/components/net/sf/briar/plugins/file/UnixRemovableDriveMonitor.java @@ -0,0 +1,67 @@ +package net.sf.briar.plugins.file; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import net.contentobjects.jnotify.JNotify; +import net.contentobjects.jnotify.JNotifyListener; + +abstract class UnixRemovableDriveMonitor implements RemovableDriveMonitor, +JNotifyListener { + + private final List<Integer> watches = new ArrayList<Integer>(); + private final LinkedList<File> inserted = new LinkedList<File>(); + + private boolean started = false, stopped = false; + + protected abstract String[] getPathsToWatch(); + + public synchronized void start() throws IOException { + if(started || stopped) throw new IllegalStateException(); + started = true; + int mask = JNotify.FILE_CREATED; + for(String path : getPathsToWatch()) { + if(new File(path).exists()) + watches.add(JNotify.addWatch(path, mask, false, this)); + } + } + + public synchronized File waitForInsertion() throws IOException { + if(!started || stopped) throw new IllegalStateException(); + while(inserted.isEmpty()) { + try { + wait(); + } catch(InterruptedException ignored) {} + } + return inserted.poll(); + } + + public synchronized void stop() throws IOException { + if(!started || stopped) throw new IllegalStateException(); + stopped = true; + for(Integer w : watches) JNotify.removeWatch(w); + } + + public void fileCreated(int wd, String rootPath, String name) { + synchronized(this) { + inserted.add(new File(rootPath + "/" + name)); + notifyAll(); + } + } + + public void fileDeleted(int wd, String rootPath, String name) { + throw new UnsupportedOperationException(); + } + + public void fileModified(int wd, String rootPath, String name) { + throw new UnsupportedOperationException(); + } + + public void fileRenamed(int wd, String rootPath, String oldName, + String newName) { + throw new UnsupportedOperationException(); + } +}