Plugins should not modify their properties or configs.

This commit is contained in:
akwizgran
2011-10-06 17:58:08 +01:00
parent 8468b84c54
commit 3e522c81fa
4 changed files with 61 additions and 26 deletions

View File

@@ -5,7 +5,10 @@ import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
@@ -44,9 +47,18 @@ abstract class FilePlugin implements BatchTransportPlugin {
throws InvalidPropertiesException, InvalidConfigException, IOException { throws InvalidPropertiesException, InvalidConfigException, IOException {
if(started) throw new IllegalStateException(); if(started) throw new IllegalStateException();
started = true; started = true;
this.localProperties = localProperties; this.localProperties = Collections.unmodifiableMap(localProperties);
this.remoteProperties = remoteProperties; // Copy the remoteProperties map to make its values unmodifiable
this.config = config; // Copy the remoteProperties map to make its values unmodifiable
int size = remoteProperties.size();
Map<ContactId, Map<String, String>> m =
new HashMap<ContactId, Map<String, String>>(size);
for(Entry<ContactId, Map<String, String>> e
: remoteProperties.entrySet()) {
m.put(e.getKey(), Collections.unmodifiableMap(e.getValue()));
}
this.remoteProperties = m;
this.config = Collections.unmodifiableMap(config);
this.callback = callback; this.callback = callback;
} }
@@ -58,20 +70,20 @@ abstract class FilePlugin implements BatchTransportPlugin {
public synchronized void setLocalProperties(Map<String, String> properties) public synchronized void setLocalProperties(Map<String, String> properties)
throws InvalidPropertiesException { throws InvalidPropertiesException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
localProperties = properties; localProperties = Collections.unmodifiableMap(properties);
} }
public synchronized void setRemoteProperties(ContactId c, public synchronized void setRemoteProperties(ContactId c,
Map<String, String> properties) Map<String, String> properties)
throws InvalidPropertiesException { throws InvalidPropertiesException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
remoteProperties.put(c, properties); remoteProperties.put(c, Collections.unmodifiableMap(properties));
} }
public synchronized void setConfig(Map<String, String> config) public synchronized void setConfig(Map<String, String> config)
throws InvalidConfigException { throws InvalidConfigException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
this.config = config; this.config = Collections.unmodifiableMap(config);
} }
public BatchTransportReader createReader(ContactId c) { public BatchTransportReader createReader(ContactId c) {
@@ -105,8 +117,7 @@ abstract class FilePlugin implements BatchTransportPlugin {
return FileSystemUtils.freeSpaceKb(path) * 1024L; return FileSystemUtils.freeSpaceKb(path) * 1024L;
} }
// Package access for testing protected void createReaderFromFile(final File f) {
void createReaderFromFile(final File f) {
if(!started) return; if(!started) return;
executor.execute(new ReaderCreator(f)); executor.execute(new ReaderCreator(f));
} }

View File

@@ -6,6 +6,7 @@ import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
@@ -59,9 +60,10 @@ public class SimpleSocketPlugin extends SocketPlugin {
String host = i.getAddress().getHostAddress(); String host = i.getAddress().getHostAddress();
String port = String.valueOf(i.getPort()); String port = String.valueOf(i.getPort());
// FIXME: Special handling for private IP addresses? // FIXME: Special handling for private IP addresses?
localProperties.put("host", host); Map<String, String> m = new TreeMap<String, String>(localProperties);
localProperties.put("port", port); m.put("host", host);
callback.setLocalProperties(localProperties); m.put("port", port);
callback.setLocalProperties(m);
} }
private SocketAddress createSocketAddress(Map<String, String> properties) { private SocketAddress createSocketAddress(Map<String, String> properties) {

View File

@@ -4,7 +4,10 @@ import java.io.IOException;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import net.sf.briar.api.ContactId; import net.sf.briar.api.ContactId;
@@ -43,9 +46,17 @@ abstract class SocketPlugin implements StreamTransportPlugin {
throws InvalidPropertiesException, InvalidConfigException { throws InvalidPropertiesException, InvalidConfigException {
if(started) throw new IllegalStateException(); if(started) throw new IllegalStateException();
started = true; started = true;
this.localProperties = localProperties; this.localProperties = Collections.unmodifiableMap(localProperties);
this.remoteProperties = remoteProperties; // Copy the remoteProperties map to make its values unmodifiable
this.config = config; int size = remoteProperties.size();
Map<ContactId, Map<String, String>> m =
new HashMap<ContactId, Map<String, String>>(size);
for(Entry<ContactId, Map<String, String>> e
: remoteProperties.entrySet()) {
m.put(e.getKey(), Collections.unmodifiableMap(e.getValue()));
}
this.remoteProperties = m;
this.config = Collections.unmodifiableMap(config);
this.callback = callback; this.callback = callback;
executor.execute(createBinder()); executor.execute(createBinder());
} }
@@ -129,7 +140,7 @@ abstract class SocketPlugin implements StreamTransportPlugin {
public synchronized void setLocalProperties(Map<String, String> properties) public synchronized void setLocalProperties(Map<String, String> properties)
throws InvalidPropertiesException { throws InvalidPropertiesException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
localProperties = properties; localProperties = Collections.unmodifiableMap(properties);
// Close and reopen the socket if its address has changed // Close and reopen the socket if its address has changed
if(socket != null) { if(socket != null) {
SocketAddress addr = socket.getLocalSocketAddress(); SocketAddress addr = socket.getLocalSocketAddress();
@@ -148,13 +159,13 @@ abstract class SocketPlugin implements StreamTransportPlugin {
Map<String, String> properties) Map<String, String> properties)
throws InvalidPropertiesException { throws InvalidPropertiesException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
remoteProperties.put(c, properties); remoteProperties.put(c, Collections.unmodifiableMap(properties));
} }
public synchronized void setConfig(Map<String, String> config) public synchronized void setConfig(Map<String, String> config)
throws InvalidConfigException { throws InvalidConfigException {
if(!started) throw new IllegalStateException(); if(!started) throw new IllegalStateException();
this.config = config; this.config = Collections.unmodifiableMap(config);
} }
public synchronized void poll() { public synchronized void poll() {

View File

@@ -5,7 +5,10 @@ import java.io.FileOutputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -27,8 +30,16 @@ public class RemovableDrivePluginTest extends TestCase {
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final ContactId contactId = new ContactId(0); private final ContactId contactId = new ContactId(0);
private Map<String, String> localProperties = null;
private Map<ContactId, Map<String, String>> remoteProperties = null;
private Map<String, String> config = null;
@Before @Before
public void setUp() { public void setUp() {
localProperties = new TreeMap<String, String>();
remoteProperties = new HashMap<ContactId, Map<String, String>>();
remoteProperties.put(contactId, new TreeMap<String, String>());
config = new TreeMap<String, String>();
testDir.mkdirs(); testDir.mkdirs();
} }
@@ -71,7 +82,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
assertNull(plugin.createWriter(contactId)); assertNull(plugin.createWriter(contactId));
@@ -106,7 +117,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
assertNull(plugin.createWriter(contactId)); assertNull(plugin.createWriter(contactId));
File[] files = drive1.listFiles(); File[] files = drive1.listFiles();
@@ -143,7 +154,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
assertNull(plugin.createWriter(contactId)); assertNull(plugin.createWriter(contactId));
File[] files = drive1.listFiles(); File[] files = drive1.listFiles();
@@ -182,7 +193,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
assertNull(plugin.createWriter(contactId)); assertNull(plugin.createWriter(contactId));
File[] files = drive1.listFiles(); File[] files = drive1.listFiles();
@@ -221,7 +232,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
assertNotNull(plugin.createWriter(contactId)); assertNotNull(plugin.createWriter(contactId));
// The output file should exist and should be empty // The output file should exist and should be empty
@@ -264,7 +275,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
BatchTransportWriter writer = plugin.createWriter(contactId); BatchTransportWriter writer = plugin.createWriter(contactId);
assertNotNull(writer); assertNotNull(writer);
@@ -305,7 +316,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor, RemovableDrivePlugin plugin = new RemovableDrivePlugin(executor,
finder, monitor); finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
plugin.driveInserted(testDir); plugin.driveInserted(testDir);
@@ -350,7 +361,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin( RemovableDrivePlugin plugin = new RemovableDrivePlugin(
new ImmediateExecutor(), finder, monitor); new ImmediateExecutor(), finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
File f = new File(testDir, "abcdefgh.dat"); File f = new File(testDir, "abcdefgh.dat");
OutputStream out = new FileOutputStream(f); OutputStream out = new FileOutputStream(f);
@@ -380,7 +391,7 @@ public class RemovableDrivePluginTest extends TestCase {
RemovableDrivePlugin plugin = new RemovableDrivePlugin( RemovableDrivePlugin plugin = new RemovableDrivePlugin(
new ImmediateExecutor(), finder, monitor); new ImmediateExecutor(), finder, monitor);
plugin.start(null, null, null, callback); plugin.start(localProperties, remoteProperties, config, callback);
File f = new File(testDir, "abcdefgh.dat"); File f = new File(testDir, "abcdefgh.dat");
OutputStream out = new FileOutputStream(f); OutputStream out = new FileOutputStream(f);