diff --git a/components/net/sf/briar/plugins/file/FilePlugin.java b/components/net/sf/briar/plugins/file/FilePlugin.java index 56e3d5bb054caf5a434f73b0899f91271a61a2bb..abe37fac527cd659dde2413ee13962ab2f1715cb 100644 --- a/components/net/sf/briar/plugins/file/FilePlugin.java +++ b/components/net/sf/briar/plugins/file/FilePlugin.java @@ -6,6 +6,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.Map; +import java.util.concurrent.Executor; import net.sf.briar.api.ContactId; import net.sf.briar.api.db.DbException; @@ -23,6 +24,7 @@ import org.apache.commons.io.FileSystemUtils; abstract class FilePlugin implements BatchTransportPlugin { private final ConnectionRecogniser recogniser; + private final Executor executor; protected Map<String, String> localProperties = null; protected Map<ContactId, Map<String, String>> remoteProperties = null; @@ -34,8 +36,9 @@ abstract class FilePlugin implements BatchTransportPlugin { protected abstract File chooseOutputDirectory(); protected abstract void writerFinished(File f); - FilePlugin(ConnectionRecogniser recogniser) { + FilePlugin(ConnectionRecogniser recogniser, Executor executor) { this.recogniser = recogniser; + this.executor = executor; } public synchronized void start(Map<String, String> localProperties, @@ -117,42 +120,55 @@ abstract class FilePlugin implements BatchTransportPlugin { return FileSystemUtils.freeSpaceKb(path) * 1024L; } - protected void createReaderFromFile(File f) { + protected void createReaderFromFile(final File f) { if(!started) throw new IllegalStateException(); - if(!isPossibleConnectionFilename(f.getName())) return; - if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return; - try { - FileInputStream in = new FileInputStream(f); - byte[] iv = new byte[TransportConstants.IV_LENGTH]; - int offset = 0; - while(offset < iv.length) { - int read = in.read(iv, offset, iv.length - offset); - if(read == -1) break; - offset += read; - } - if(offset < iv.length) { - // The file was truncated - in.close(); - return; - } - ContactId c = recogniser.acceptConnection(iv); - if(c == null) { - // Nobody there - in.close(); - return; - } - FileTransportReader reader = new FileTransportReader(f, in); - callback.readerCreated(c, iv, reader); - } catch(DbException e) { - // FIXME: At least log it - return; - } catch(IOException e) { - // FIXME: At least log it - return; - } + executor.execute(new ReaderCreator(f)); } protected boolean isPossibleConnectionFilename(String filename) { return filename.toLowerCase().matches("[a-z]{8}\\.dat"); } + + private class ReaderCreator implements Runnable { + + private final File f; + + private ReaderCreator(File f) { + this.f = f; + } + + public void run() { + if(!isPossibleConnectionFilename(f.getName())) return; + if(f.length() < TransportConstants.MIN_CONNECTION_LENGTH) return; + try { + FileInputStream in = new FileInputStream(f); + byte[] iv = new byte[TransportConstants.IV_LENGTH]; + int offset = 0; + while(offset < iv.length) { + int read = in.read(iv, offset, iv.length - offset); + if(read == -1) break; + offset += read; + } + if(offset < iv.length) { + // The file was truncated + in.close(); + return; + } + ContactId c = recogniser.acceptConnection(iv); + if(c == null) { + // Nobody there + in.close(); + return; + } + FileTransportReader reader = new FileTransportReader(f, in); + callback.readerCreated(c, iv, reader); + } catch(DbException e) { + // FIXME: At least log it + return; + } catch(IOException e) { + // FIXME: At least log it + return; + } + } + } } diff --git a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java index bd959c219c598befbd268e110e3152c0b1440141..29041633eb2e5174b6a714adca1d9733e28518ed 100644 --- a/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java +++ b/components/net/sf/briar/plugins/file/RemovableDrivePlugin.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.IOException; import java.util.List; import java.util.Map; +import java.util.concurrent.Executor; import net.sf.briar.api.ContactId; import net.sf.briar.api.TransportId; @@ -22,9 +23,9 @@ implements RemovableDriveMonitor.Callback { private final RemovableDriveFinder finder; private final RemovableDriveMonitor monitor; - RemovableDrivePlugin(ConnectionRecogniser recogniser, + RemovableDrivePlugin(ConnectionRecogniser recogniser, Executor executor, RemovableDriveFinder finder, RemovableDriveMonitor monitor) { - super(recogniser); + super(recogniser, executor); this.finder = finder; this.monitor = monitor; } diff --git a/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java b/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java index 625a7de03354634a9ad391d59985d1eda119e3a3..0792589ccfdf31151e21bb2715eca271058d05a5 100644 --- a/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java +++ b/test/net/sf/briar/plugins/file/RemovableDrivePluginTest.java @@ -6,6 +6,7 @@ import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.Executor; import junit.framework.TestCase; import net.sf.briar.TestUtils; @@ -36,6 +37,7 @@ public class RemovableDrivePluginTest extends TestCase { @Test public void testGetId() { Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -44,7 +46,7 @@ public class RemovableDrivePluginTest extends TestCase { context.mock(RemovableDriveMonitor.class); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); assertEquals(RemovableDrivePlugin.TRANSPORT_ID, plugin.getId().getInt()); @@ -57,6 +59,7 @@ public class RemovableDrivePluginTest extends TestCase { final List<File> drives = Collections.emptyList(); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -73,7 +76,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); assertNull(plugin.createWriter(contactId)); @@ -90,6 +93,7 @@ public class RemovableDrivePluginTest extends TestCase { drives.add(drive2); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -109,7 +113,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); assertNull(plugin.createWriter(contactId)); @@ -128,6 +132,7 @@ public class RemovableDrivePluginTest extends TestCase { drives.add(drive2); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -147,7 +152,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); assertNull(plugin.createWriter(contactId)); @@ -168,6 +173,7 @@ public class RemovableDrivePluginTest extends TestCase { assertTrue(drive1.createNewFile()); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -187,7 +193,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); assertNull(plugin.createWriter(contactId)); @@ -208,6 +214,7 @@ public class RemovableDrivePluginTest extends TestCase { assertTrue(drive1.mkdir()); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -227,7 +234,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); assertNotNull(plugin.createWriter(contactId)); @@ -251,6 +258,7 @@ public class RemovableDrivePluginTest extends TestCase { assertTrue(drive1.mkdir()); Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -271,7 +279,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); BatchTransportWriter writer = plugin.createWriter(contactId); @@ -299,6 +307,7 @@ public class RemovableDrivePluginTest extends TestCase { @Test public void testEmptyDriveIsIgnored() throws Exception { Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -313,7 +322,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); plugin.start(null, null, null, callback); plugin.driveInserted(testDir); @@ -324,6 +333,7 @@ public class RemovableDrivePluginTest extends TestCase { @Test public void testFilenames() { Mockery context = new Mockery(); + final Executor executor = context.mock(Executor.class); final ConnectionRecogniser recogniser = context.mock(ConnectionRecogniser.class); final RemovableDriveFinder finder = @@ -332,7 +342,7 @@ public class RemovableDrivePluginTest extends TestCase { context.mock(RemovableDriveMonitor.class); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + executor, finder, monitor); assertFalse(plugin.isPossibleConnectionFilename("abcdefg.dat")); assertFalse(plugin.isPossibleConnectionFilename("abcdefghi.dat")); @@ -361,7 +371,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + new ImmediateExecutor(), finder, monitor); plugin.start(null, null, null, callback); File f = new File(testDir, "abcdefgh.dat"); @@ -394,7 +404,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + new ImmediateExecutor(), finder, monitor); plugin.start(null, null, null, callback); File f = new File(testDir, "abcdefgh.dat"); @@ -430,7 +440,7 @@ public class RemovableDrivePluginTest extends TestCase { }}); RemovableDrivePlugin plugin = new RemovableDrivePlugin(recogniser, - finder, monitor); + new ImmediateExecutor(), finder, monitor); plugin.start(null, null, null, callback); File f = new File(testDir, "abcdefgh.dat"); @@ -448,4 +458,11 @@ public class RemovableDrivePluginTest extends TestCase { public void tearDown() { TestUtils.deleteTestDirectory(testDir); } + + private static class ImmediateExecutor implements Executor { + + public void execute(Runnable r) { + r.run(); + } + } }