Changed the root package from net.sf.briar to org.briarproject.

This commit is contained in:
akwizgran
2014-01-08 16:18:30 +00:00
parent dce70f487c
commit 832476412c
427 changed files with 2507 additions and 2507 deletions

View File

@@ -0,0 +1,22 @@
package org.briarproject.plugins.file;
class LinuxRemovableDriveFinder extends UnixRemovableDriveFinder {
@Override
protected String getMountCommand() {
return "/bin/mount";
}
@Override
protected String parseMountPoint(String line) {
// The format is "/dev/foo on /bar/baz type bam (opt1,opt2)"
String pattern = "^/dev/[^ ]+ on (.*) type [^ ]+ \\([^)]+\\)$";
String path = line.replaceFirst(pattern, "$1");
return path.equals(line) ? null : path;
}
@Override
protected boolean isRemovableDriveMountPoint(String path) {
return path.startsWith("/mnt/") || path.startsWith("/media/");
}
}

View File

@@ -0,0 +1,9 @@
package org.briarproject.plugins.file;
class LinuxRemovableDriveMonitor extends UnixRemovableDriveMonitor {
@Override
protected String[] getPathsToWatch() {
return new String[] { "/mnt", "/media" };
}
}

View File

@@ -0,0 +1,22 @@
package org.briarproject.plugins.file;
class MacRemovableDriveFinder extends UnixRemovableDriveFinder {
@Override
protected String getMountCommand() {
return "/sbin/mount";
}
@Override
protected String parseMountPoint(String line) {
// The format is "/dev/foo on /bar/baz (opt1, opt2)"
String pattern = "^/dev/[^ ]+ on (.*) \\([^)]+\\)$";
String path = line.replaceFirst(pattern, "$1");
return path.equals(line) ? null : path;
}
@Override
protected boolean isRemovableDriveMountPoint(String path) {
return path.startsWith("/Volumes/");
}
}

View File

@@ -0,0 +1,9 @@
package org.briarproject.plugins.file;
class MacRemovableDriveMonitor extends UnixRemovableDriveMonitor {
@Override
protected String[] getPathsToWatch() {
return new String[] { "/Volumes" };
}
}

View File

@@ -0,0 +1,66 @@
package org.briarproject.plugins.file;
import static java.util.logging.Level.INFO;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
class PollingRemovableDriveMonitor implements RemovableDriveMonitor, Runnable {
private static final Logger LOG =
Logger.getLogger(PollingRemovableDriveMonitor.class.getName());
private final Executor pluginExecutor;
private final RemovableDriveFinder finder;
private final long pollingInterval;
private final Object pollingLock = new Object();
private volatile boolean running = false;
private volatile Callback callback = null;
public PollingRemovableDriveMonitor(Executor pluginExecutor,
RemovableDriveFinder finder, long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.finder = finder;
this.pollingInterval = pollingInterval;
}
public void start(Callback callback) throws IOException {
this.callback = callback;
running = true;
pluginExecutor.execute(this);
}
public void stop() throws IOException {
running = false;
synchronized(pollingLock) {
pollingLock.notifyAll();
}
}
public void run() {
try {
Collection<File> drives = finder.findRemovableDrives();
while(running) {
synchronized(pollingLock) {
pollingLock.wait(pollingInterval);
}
if(!running) return;
Collection<File> newDrives = finder.findRemovableDrives();
for(File f : newDrives) {
if(!drives.contains(f)) callback.driveInserted(f);
}
drives = newDrives;
}
} catch(InterruptedException e) {
if(LOG.isLoggable(INFO))
LOG.info("Interrupted while waiting to poll");
Thread.currentThread().interrupt();
} catch(IOException e) {
callback.exceptionThrown(e);
}
}
}

View File

@@ -0,0 +1,10 @@
package org.briarproject.plugins.file;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
interface RemovableDriveFinder {
Collection<File> findRemovableDrives() throws IOException;
}

View File

@@ -0,0 +1,18 @@
package org.briarproject.plugins.file;
import java.io.File;
import java.io.IOException;
interface RemovableDriveMonitor {
void start(Callback c) throws IOException;
void stop() throws IOException;
interface Callback {
void driveInserted(File root);
void exceptionThrown(IOException e);
}
}

View File

@@ -0,0 +1,133 @@
package org.briarproject.plugins.file;
import static java.util.logging.Level.WARNING;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.logging.Logger;
import org.briarproject.api.ContactId;
import org.briarproject.api.TransportId;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.system.FileUtils;
import org.briarproject.util.StringUtils;
class RemovableDrivePlugin extends FilePlugin
implements RemovableDriveMonitor.Callback {
static final byte[] TRANSPORT_ID =
StringUtils.fromHexString("7c81bf5c9b1cd557685548c85f976bbd"
+ "e633d2418ea2e230e5710fb43c6f8cc0"
+ "68abca3a9d0edb13bcea13b851725c5d");
static final TransportId ID = new TransportId(TRANSPORT_ID);
private static final Logger LOG =
Logger.getLogger(RemovableDrivePlugin.class.getName());
private final RemovableDriveFinder finder;
private final RemovableDriveMonitor monitor;
RemovableDrivePlugin(Executor pluginExecutor, FileUtils fileUtils,
SimplexPluginCallback callback, RemovableDriveFinder finder,
RemovableDriveMonitor monitor, int maxFrameLength,
long maxLatency) {
super(pluginExecutor, fileUtils, callback, maxFrameLength, maxLatency);
this.finder = finder;
this.monitor = monitor;
}
public TransportId getId() {
return ID;
}
public String getName() {
return "REMOVABLE_DRIVE_PLUGIN_NAME";
}
public boolean start() throws IOException {
running = true;
monitor.start(this);
return true;
}
public void stop() throws IOException {
running = false;
monitor.stop();
}
public boolean shouldPoll() {
return false;
}
public long getPollingInterval() {
throw new UnsupportedOperationException();
}
public void poll(Collection<ContactId> connected) {
throw new UnsupportedOperationException();
}
@Override
protected File chooseOutputDirectory() {
try {
List<File> drives =
new ArrayList<File>(finder.findRemovableDrives());
if(drives.isEmpty()) return null;
String[] paths = new String[drives.size()];
for(int i = 0; i < paths.length; i++) {
paths[i] = drives.get(i).getPath();
}
int i = callback.showChoice(paths, "REMOVABLE_DRIVE_CHOOSE_DRIVE");
if(i == -1) return null;
return drives.get(i);
} catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
return null;
}
}
@Override
protected void readerFinished(File f) {
callback.showMessage("REMOVABLE_DRIVE_READ_FINISHED");
}
@Override
protected void writerFinished(File f) {
callback.showMessage("REMOVABLE_DRIVE_WRITE_FINISHED");
}
@Override
protected Collection<File> findFilesByName(String filename) {
List<File> matches = new ArrayList<File>();
try {
for(File drive : finder.findRemovableDrives()) {
File[] files = drive.listFiles();
if(files != null) {
for(File f : files) {
if(f.isFile() && filename.equals(f.getName()))
matches.add(f);
}
}
}
} catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
return Collections.unmodifiableList(matches);
}
public void driveInserted(File root) {
File[] files = root.listFiles();
if(files != null) {
for(File f : files) if(f.isFile()) createReaderFromFile(f);
}
}
public void exceptionThrown(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}

View File

@@ -0,0 +1,57 @@
package org.briarproject.plugins.file;
import static org.briarproject.api.transport.TransportConstants.MAX_FRAME_LENGTH;
import java.util.concurrent.Executor;
import org.briarproject.api.TransportId;
import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.system.FileUtils;
import org.briarproject.util.OsUtils;
public class RemovableDrivePluginFactory implements SimplexPluginFactory {
// Maximum latency 14 days (Royal Mail or lackadaisical carrier pigeon)
private static final long MAX_LATENCY = 14 * 24 * 60 * 60 * 1000;
private static final long POLLING_INTERVAL = 10 * 1000; // 10 seconds
private final Executor pluginExecutor;
private final FileUtils fileUtils;
public RemovableDrivePluginFactory(Executor pluginExecutor,
FileUtils fileUtils) {
this.pluginExecutor = pluginExecutor;
this.fileUtils = fileUtils;
}
public TransportId getId() {
return RemovableDrivePlugin.ID;
}
public SimplexPlugin createPlugin(SimplexPluginCallback callback) {
RemovableDriveFinder finder;
RemovableDriveMonitor monitor;
if(OsUtils.isLinux()) {
finder = new LinuxRemovableDriveFinder();
monitor = new LinuxRemovableDriveMonitor();
} else if(OsUtils.isMacLeopardOrNewer()) {
finder = new MacRemovableDriveFinder();
monitor = new MacRemovableDriveMonitor();
} else if(OsUtils.isMac()) {
// JNotify requires OS X 10.5 or newer, so we have to poll
finder = new MacRemovableDriveFinder();
monitor = new PollingRemovableDriveMonitor(pluginExecutor, finder,
POLLING_INTERVAL);
} else if(OsUtils.isWindows()) {
finder = new WindowsRemovableDriveFinder();
monitor = new PollingRemovableDriveMonitor(pluginExecutor, finder,
POLLING_INTERVAL);
} else {
return null;
}
return new RemovableDrivePlugin(pluginExecutor, fileUtils, callback,
finder, monitor, MAX_FRAME_LENGTH, MAX_LATENCY);
}
}

View File

@@ -0,0 +1,40 @@
package org.briarproject.plugins.file;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;
abstract class UnixRemovableDriveFinder implements RemovableDriveFinder {
protected abstract String getMountCommand();
protected abstract String parseMountPoint(String line);
protected abstract boolean isRemovableDriveMountPoint(String path);
public List<File> findRemovableDrives() throws IOException {
List<File> drives = new ArrayList<File>();
Process p = new ProcessBuilder(getMountCommand()).start();
Scanner s = new Scanner(p.getInputStream(), "UTF-8");
try {
while(s.hasNextLine()) {
String line = s.nextLine();
String[] tokens = line.split(" ");
if(tokens.length < 3) continue;
// The general format is "/dev/foo on /bar/baz ..."
if(tokens[0].startsWith("/dev/") && tokens[1].equals("on")) {
// The path may contain spaces so we can't use tokens[2]
String path = parseMountPoint(line);
if(isRemovableDriveMountPoint(path)) {
File f = new File(path);
if(f.exists() && f.isDirectory()) drives.add(f);
}
}
}
} finally {
s.close();
}
return Collections.unmodifiableList(drives);
}
}

View File

@@ -0,0 +1,72 @@
package org.briarproject.plugins.file;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.contentobjects.jnotify.JNotify;
import net.contentobjects.jnotify.JNotifyListener;
abstract class UnixRemovableDriveMonitor implements RemovableDriveMonitor,
JNotifyListener {
// Locking: this
private final List<Integer> watches = new ArrayList<Integer>();
private boolean started = false; // Locking: this
private Callback callback = null; // Locking: this
protected abstract String[] getPathsToWatch();
public void start(Callback callback) throws IOException {
List<Integer> watches = new ArrayList<Integer>();
int mask = JNotify.FILE_CREATED;
for(String path : getPathsToWatch()) {
if(new File(path).exists())
watches.add(JNotify.addWatch(path, mask, false, this));
}
synchronized(this) {
assert !started;
assert this.callback == null;
started = true;
this.callback = callback;
this.watches.addAll(watches);
}
}
public void stop() throws IOException {
List<Integer> watches;
synchronized(this) {
assert started;
assert callback != null;
started = false;
callback = null;
watches = new ArrayList<Integer>(this.watches);
this.watches.clear();
}
for(Integer w : watches) JNotify.removeWatch(w);
}
public void fileCreated(int wd, String rootPath, String name) {
Callback callback;
synchronized(this) {
callback = this.callback;
}
if(callback != null)
callback.driveInserted(new File(rootPath + "/" + name));
}
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();
}
}

View File

@@ -0,0 +1,31 @@
package org.briarproject.plugins.file;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import com.sun.jna.platform.win32.Kernel32;
class WindowsRemovableDriveFinder implements RemovableDriveFinder {
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364939.aspx
private static final int DRIVE_REMOVABLE = 2;
public Collection<File> findRemovableDrives() throws IOException {
File[] roots = File.listRoots();
if(roots == null) throw new IOException();
List<File> drives = new ArrayList<File>();
for(File root : roots) {
try {
int type = Kernel32.INSTANCE.GetDriveType(root.getPath());
if(type == DRIVE_REMOVABLE) drives.add(root);
} catch(RuntimeException e) {
throw new IOException(e);
}
}
return Collections.unmodifiableList(drives);
}
}