Use numeric IDs rather than names to identify transports.

This commit is contained in:
akwizgran
2011-09-29 15:40:09 +01:00
parent c77b4e5b91
commit 7190509ede
20 changed files with 164 additions and 169 deletions

View File

@@ -50,7 +50,7 @@ public interface DatabaseComponent {
* Adds a new contact to the database with the given transport properties * Adds a new contact to the database with the given transport properties
* and shared secret, returns an ID for the contact. * and shared secret, returns an ID for the contact.
*/ */
ContactId addContact(Map<String, Map<String, String>> transports, ContactId addContact(Map<Integer, Map<String, String>> transports,
byte[] secret) throws DbException; byte[] secret) throws DbException;
/** Adds a locally generated group message to the database. */ /** Adds a locally generated group message to the database. */
@@ -123,14 +123,14 @@ public interface DatabaseComponent {
/** Returns the set of groups to which the user subscribes. */ /** Returns the set of groups to which the user subscribes. */
Collection<Group> getSubscriptions() throws DbException; Collection<Group> getSubscriptions() throws DbException;
/** Returns the configuration for the transport with the given name. */ /** Returns the configuration for the given transport. */
Map<String, String> getTransportConfig(String name) throws DbException; Map<String, String> getTransportConfig(int transportId) throws DbException;
/** Returns all local transport properties. */ /** Returns all local transport properties. */
Map<String, Map<String, String>> getTransports() throws DbException; Map<Integer, Map<String, String>> getTransports() throws DbException;
/** Returns all transport properties for the given contact. */ /** Returns all transport properties for the given contact. */
Map<String, Map<String, String>> getTransports(ContactId c) Map<Integer, Map<String, String>> getTransports(ContactId c)
throws DbException; throws DbException;
/** Returns the contacts to which the given group is visible. */ /** Returns the contacts to which the given group is visible. */
@@ -181,17 +181,17 @@ public interface DatabaseComponent {
void setSeen(ContactId c, Collection<MessageId> seen) throws DbException; void setSeen(ContactId c, Collection<MessageId> seen) throws DbException;
/** /**
* Sets the configuration for the transport with the given name, replacing * Sets the configuration for the given transport, replacing any existing
* any existing configuration for that transport. * configuration for that transport.
*/ */
void setTransportConfig(String name, Map<String, String> config) void setTransportConfig(int transportId, Map<String, String> config)
throws DbException; throws DbException;
/** /**
* Sets the transport properties for the transport with the given name, * Sets the transport properties for the given transport, replacing any
* replacing any existing properties for that transport. * existing properties for that transport.
*/ */
void setTransportProperties(String name, Map<String, String> properties) void setTransportProperties(int transportId, Map<String, String> properties)
throws DbException; throws DbException;
/** /**

View File

@@ -5,9 +5,6 @@ import java.util.Map;
/** A packet updating the sender's transport properties. */ /** A packet updating the sender's transport properties. */
public interface TransportUpdate { public interface TransportUpdate {
/** The maximum length of a plugin's name in UTF-8 bytes. */
static final int MAX_NAME_LENGTH = 50;
/** The maximum length of a property's key or value in UTF-8 bytes. */ /** The maximum length of a property's key or value in UTF-8 bytes. */
static final int MAX_KEY_OR_VALUE_LENGTH = 100; static final int MAX_KEY_OR_VALUE_LENGTH = 100;
@@ -18,7 +15,7 @@ public interface TransportUpdate {
static final int MAX_PLUGINS_PER_UPDATE = 50; static final int MAX_PLUGINS_PER_UPDATE = 50;
/** Returns the transport properties contained in the update. */ /** Returns the transport properties contained in the update. */
Map<String, Map<String, String>> getTransports(); Map<Integer, Map<String, String>> getTransports();
/** /**
* Returns the update's timestamp. Updates that are older than the newest * Returns the update's timestamp. Updates that are older than the newest

View File

@@ -7,6 +7,6 @@ import java.util.Map;
public interface TransportWriter { public interface TransportWriter {
/** Writes the contents of the update. */ /** Writes the contents of the update. */
void writeTransports(Map<String, Map<String, String>> transports, void writeTransports(Map<Integer, Map<String, String>> transports,
long timestamp) throws IOException; long timestamp) throws IOException;
} }

View File

@@ -12,11 +12,8 @@ import net.sf.briar.api.transport.InvalidTransportException;
*/ */
public interface BatchTransportPlugin { public interface BatchTransportPlugin {
/** /** Returns the plugin's transport identifier. */
* Returns the plugin's name, which is used to distinguish its transport int getTransportId();
* and configuration properties from those of other plugins.
*/
String getName();
/** /**
* Starts the plugin. Any connections that are later initiated by contacts * Starts the plugin. Any connections that are later initiated by contacts

View File

@@ -12,11 +12,8 @@ import net.sf.briar.api.transport.InvalidTransportException;
*/ */
public interface StreamTransportPlugin { public interface StreamTransportPlugin {
/** /** Returns the plugin's transport identifier. */
* Returns the plugin's name, which is used to distinguish its transport int getTransportId();
* and configuration properties from those of other plugins.
*/
String getName();
/** /**
* Starts the plugin. Any connections that are later initiated by contacts * Starts the plugin. Any connections that are later initiated by contacts

View File

@@ -83,7 +83,7 @@ interface Database<T> {
* <p> * <p>
* Locking: contacts write, transports write. * Locking: contacts write, transports write.
*/ */
ContactId addContact(T txn, Map<String, Map<String, String>> transports, ContactId addContact(T txn, Map<Integer, Map<String, String>> transports,
byte[] secret) throws DbException; byte[] secret) throws DbException;
/** /**
@@ -315,11 +315,11 @@ interface Database<T> {
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException; Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
/** /**
* Returns the configuration for the transport with the given name. * Returns the configuration for the given transport.
* <p> * <p>
* Locking: transports read. * Locking: transports read.
*/ */
Map<String, String> getTransportConfig(T txn, String name) Map<String, String> getTransportConfig(T txn, int transportId)
throws DbException; throws DbException;
/** /**
@@ -327,14 +327,14 @@ interface Database<T> {
* <p> * <p>
* Locking: transports read. * Locking: transports read.
*/ */
Map<String, Map<String, String>> getTransports(T txn) throws DbException; Map<Integer, Map<String, String>> getTransports(T txn) throws DbException;
/** /**
* Returns all transport properties for the given contact. * Returns all transport properties for the given contact.
* <p> * <p>
* Locking: contacts read, transports read. * Locking: contacts read, transports read.
*/ */
Map<String, Map<String, String>> getTransports(T txn, ContactId c) Map<Integer, Map<String, String>> getTransports(T txn, ContactId c)
throws DbException; throws DbException;
/** /**
@@ -471,21 +471,21 @@ interface Database<T> {
throws DbException; throws DbException;
/** /**
* Sets the configuration for the transport with the given name, replacing * Sets the configuration for the given transport, replacing any existing
* any existing configuration for that transport. * configuration for that transport.
* <p> * <p>
* Locking: transports write. * Locking: transports write.
*/ */
void setTransportConfig(T txn, String name, Map<String, String> config) void setTransportConfig(T txn, int transportId, Map<String, String> config)
throws DbException; throws DbException;
/** /**
* Sets the transport properties for the transport with the given name, * Sets the transport properties for the given transport, replacing any
* replacing any existing properties for that transport. * existing properties for that transport.
* <p> * <p>
* Locking: transports write. * Locking: transports write.
*/ */
void setTransportProperties(T txn, String name, void setTransportProperties(T txn, int transportId,
Map<String, String> properties) throws DbException; Map<String, String> properties) throws DbException;
/** /**
@@ -496,7 +496,7 @@ interface Database<T> {
* Locking: contacts read, transports write. * Locking: contacts read, transports write.
*/ */
void setTransports(T txn, ContactId c, void setTransports(T txn, ContactId c,
Map<String, Map<String, String>> transports, long timestamp) Map<Integer, Map<String, String>> transports, long timestamp)
throws DbException; throws DbException;
/** /**

View File

@@ -117,7 +117,7 @@ DatabaseCleaner.Callback {
} }
} }
public ContactId addContact(Map<String, Map<String, String>> transports, public ContactId addContact(Map<Integer, Map<String, String>> transports,
byte[] secret) throws DbException { byte[] secret) throws DbException {
if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact"); if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
ContactId c; ContactId c;
@@ -604,7 +604,7 @@ DatabaseCleaner.Callback {
public void generateTransportUpdate(ContactId c, TransportWriter t) public void generateTransportUpdate(ContactId c, TransportWriter t)
throws DbException, IOException { throws DbException, IOException {
Map<String, Map<String, String>> transports; Map<Integer, Map<String, String>> transports;
long timestamp; long timestamp;
contactLock.readLock().lock(); contactLock.readLock().lock();
try { try {
@@ -750,13 +750,14 @@ DatabaseCleaner.Callback {
} }
} }
public Map<String, String> getTransportConfig(String name) public Map<String, String> getTransportConfig(int transportId)
throws DbException { throws DbException {
transportLock.readLock().lock(); transportLock.readLock().lock();
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, String> config = db.getTransportConfig(txn, name); Map<String, String> config =
db.getTransportConfig(txn, transportId);
db.commitTransaction(txn); db.commitTransaction(txn);
return config; return config;
} catch(DbException e) { } catch(DbException e) {
@@ -768,12 +769,13 @@ DatabaseCleaner.Callback {
} }
} }
public Map<String, Map<String, String>> getTransports() throws DbException { public Map<Integer, Map<String, String>> getTransports()
throws DbException {
transportLock.readLock().lock(); transportLock.readLock().lock();
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
db.getTransports(txn); db.getTransports(txn);
db.commitTransaction(txn); db.commitTransaction(txn);
return transports; return transports;
@@ -786,7 +788,7 @@ DatabaseCleaner.Callback {
} }
} }
public Map<String, Map<String, String>> getTransports(ContactId c) public Map<Integer, Map<String, String>> getTransports(ContactId c)
throws DbException { throws DbException {
contactLock.readLock().lock(); contactLock.readLock().lock();
try { try {
@@ -795,7 +797,7 @@ DatabaseCleaner.Callback {
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
db.getTransports(txn, c); db.getTransports(txn, c);
db.commitTransaction(txn); db.commitTransaction(txn);
return transports; return transports;
@@ -1044,7 +1046,7 @@ DatabaseCleaner.Callback {
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
t.getTransports(); t.getTransports();
db.setTransports(txn, c, transports, t.getTimestamp()); db.setTransports(txn, c, transports, t.getTimestamp());
if(LOG.isLoggable(Level.FINE)) if(LOG.isLoggable(Level.FINE))
@@ -1218,16 +1220,17 @@ DatabaseCleaner.Callback {
+ indirect + " indirectly"); + indirect + " indirectly");
} }
public void setTransportConfig(String name, public void setTransportConfig(int transportId,
Map<String, String> config) throws DbException { Map<String, String> config) throws DbException {
boolean changed = false; boolean changed = false;
transportLock.writeLock().lock(); transportLock.writeLock().lock();
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, String> old = db.getTransportConfig(txn, name); Map<String, String> old =
db.getTransportConfig(txn, transportId);
if(!config.equals(old)) { if(!config.equals(old)) {
db.setTransportConfig(txn, name, config); db.setTransportConfig(txn, transportId, config);
changed = true; changed = true;
} }
db.commitTransaction(txn); db.commitTransaction(txn);
@@ -1242,16 +1245,18 @@ DatabaseCleaner.Callback {
if(changed) callListeners(Event.TRANSPORTS_UPDATED); if(changed) callListeners(Event.TRANSPORTS_UPDATED);
} }
public void setTransportProperties(String name, public void setTransportProperties(int transportId,
Map<String, String> properties) throws DbException { Map<String, String> properties) throws DbException {
boolean changed = false; boolean changed = false;
transportLock.writeLock().lock(); transportLock.writeLock().lock();
try { try {
T txn = db.startTransaction(); T txn = db.startTransaction();
try { try {
Map<String, String> old = db.getTransports(txn).get(name); Map<Integer, Map<String, String>> transports =
db.getTransports(txn);
Map<String, String> old = transports.get(transportId);
if(!properties.equals(old)) { if(!properties.equals(old)) {
db.setTransportProperties(txn, name, properties); db.setTransportProperties(txn, transportId, properties);
changed = true; changed = true;
} }
db.commitTransaction(txn); db.commitTransaction(txn);

View File

@@ -167,26 +167,26 @@ abstract class JdbcDatabase implements Database<Connection> {
private static final String CREATE_CONTACT_TRANSPORTS = private static final String CREATE_CONTACT_TRANSPORTS =
"CREATE TABLE contactTransports" "CREATE TABLE contactTransports"
+ " (contactId INT NOT NULL," + " (contactId INT NOT NULL,"
+ " name VARCHAR NOT NULL," + " transportId INT NOT NULL,"
+ " key VARCHAR NOT NULL," + " key VARCHAR NOT NULL,"
+ " value VARCHAR NOT NULL," + " value VARCHAR NOT NULL,"
+ " PRIMARY KEY (contactId, name, key)," + " PRIMARY KEY (contactId, transportId, key),"
+ " FOREIGN KEY (contactId) REFERENCES contacts (contactId)" + " FOREIGN KEY (contactId) REFERENCES contacts (contactId)"
+ " ON DELETE CASCADE)"; + " ON DELETE CASCADE)";
private static final String CREATE_TRANSPORTS = private static final String CREATE_TRANSPORTS =
"CREATE TABLE transports" "CREATE TABLE transports"
+ " (name VARCHAR NOT NULL," + " (transportId INT NOT NULL,"
+ " key VARCHAR NOT NULL," + " key VARCHAR NOT NULL,"
+ " value VARCHAR NOT NULL," + " value VARCHAR NOT NULL,"
+ " PRIMARY KEY (name, key))"; + " PRIMARY KEY (transportId, key))";
private static final String CREATE_TRANSPORT_CONFIG = private static final String CREATE_TRANSPORT_CONFIG =
"CREATE TABLE transportConfig" "CREATE TABLE transportConfig"
+ " (name VARCHAR NOT NULL," + " (transportId INT NOT NULL,"
+ " key VARCHAR NOT NULL," + " key VARCHAR NOT NULL,"
+ " value VARCHAR NOT NULL," + " value VARCHAR NOT NULL,"
+ " PRIMARY KEY (name, key))"; + " PRIMARY KEY (transportId, key))";
private static final String CREATE_CONNECTION_WINDOWS = private static final String CREATE_CONNECTION_WINDOWS =
"CREATE TABLE connectionWindows" "CREATE TABLE connectionWindows"
@@ -455,7 +455,7 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
public ContactId addContact(Connection txn, public ContactId addContact(Connection txn,
Map<String, Map<String, String>> transports, byte[] secret) Map<Integer, Map<String, String>> transports, byte[] secret)
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
@@ -481,13 +481,13 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.close(); ps.close();
// Store the contact's transport properties // Store the contact's transport properties
sql = "INSERT INTO contactTransports" sql = "INSERT INTO contactTransports"
+ " (contactId, name, key, value)" + " (contactId, transportId, key, value)"
+ " VALUES (?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt()); ps.setInt(1, c.getInt());
int batchSize = 0; int batchSize = 0;
for(Entry<String, Map<String, String>> e : transports.entrySet()) { for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
ps.setString(2, e.getKey()); ps.setInt(2, e.getKey());
for(Entry<String, String> e1 : e.getValue().entrySet()) { for(Entry<String, String> e1 : e.getValue().entrySet()) {
ps.setString(3, e1.getKey()); ps.setString(3, e1.getKey());
ps.setString(4, e1.getValue()); ps.setString(4, e1.getValue());
@@ -1394,14 +1394,14 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
public Map<String, String> getTransportConfig(Connection txn, public Map<String, String> getTransportConfig(Connection txn,
String name) throws DbException { int transportId) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT key, value FROM transportConfig" String sql = "SELECT key, value FROM transportConfig"
+ " WHERE name = ?"; + " WHERE transportId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setString(1, name); ps.setInt(1, transportId);
rs = ps.executeQuery(); rs = ps.executeQuery();
Map<String, String> config = new TreeMap<String, String>(); Map<String, String> config = new TreeMap<String, String>();
while(rs.next()) config.put(rs.getString(1), rs.getString(2)); while(rs.next()) config.put(rs.getString(1), rs.getString(2));
@@ -1415,24 +1415,24 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public Map<String, Map<String, String>> getTransports(Connection txn) public Map<Integer, Map<String, String>> getTransports(Connection txn)
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT name, key, value FROM transports" String sql = "SELECT transportId, key, value FROM transports"
+ " ORDER BY name"; + " ORDER BY transportId";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
rs = ps.executeQuery(); rs = ps.executeQuery();
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
Map<String, String> properties = null; Map<String, String> properties = null;
String lastName = null; Integer lastId = null;
while(rs.next()) { while(rs.next()) {
String name = rs.getString(1); Integer transportId = rs.getInt(1);
if(!name.equals(lastName)) { if(!transportId.equals(lastId)) {
properties = new TreeMap<String, String>(); properties = new TreeMap<String, String>();
transports.put(name, properties); transports.put(transportId, properties);
} }
properties.put(rs.getString(2), rs.getString(3)); properties.put(rs.getString(2), rs.getString(3));
} }
@@ -1446,26 +1446,26 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public Map<String, Map<String, String>> getTransports(Connection txn, public Map<Integer, Map<String, String>> getTransports(Connection txn,
ContactId c) throws DbException { ContactId c) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
String sql = "SELECT name, key, value FROM contactTransports" String sql = "SELECT transportId, key, value FROM contactTransports"
+ " WHERE contactId = ?" + " WHERE contactId = ?"
+ " ORDER BY name"; + " ORDER BY transportId";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt()); ps.setInt(1, c.getInt());
rs = ps.executeQuery(); rs = ps.executeQuery();
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
Map<String, String> properties = null; Map<String, String> properties = null;
String lastName = null; Integer lastId = null;
while(rs.next()) { while(rs.next()) {
String name = rs.getString(1); Integer transportId = rs.getInt(1);
if(!name.equals(lastName)) { if(!transportId.equals(lastId)) {
properties = new TreeMap<String, String>(); properties = new TreeMap<String, String>();
transports.put(name, properties); transports.put(transportId, properties);
} }
properties.put(rs.getString(2), rs.getString(3)); properties.put(rs.getString(2), rs.getString(3));
} }
@@ -2039,26 +2039,26 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public void setTransportConfig(Connection txn, String name, public void setTransportConfig(Connection txn, int transportId,
Map<String, String> config) throws DbException { Map<String, String> config) throws DbException {
setTransportDetails(txn, name, config, "transportConfig"); setTransportDetails(txn, transportId, config, "transportConfig");
} }
private void setTransportDetails(Connection txn, String name, private void setTransportDetails(Connection txn, int transportId,
Map<String, String> details, String table) throws DbException { Map<String, String> details, String table) throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
try { try {
// Delete any existing details for the named transport // Delete any existing details for the given transport
String sql = "DELETE FROM " + table + " WHERE name = ?"; String sql = "DELETE FROM " + table + " WHERE transportId = ?";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setString(1, name); ps.setInt(1, transportId);
ps.executeUpdate(); ps.executeUpdate();
ps.close(); ps.close();
// Store the new details // Store the new details
sql = "INSERT INTO " + table + " (name, key, value)" sql = "INSERT INTO " + table + " (transportId, key, value)"
+ " VALUES (?, ?, ?)"; + " VALUES (?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setString(1, name); ps.setInt(1, transportId);
for(Entry<String, String> e : details.entrySet()) { for(Entry<String, String> e : details.entrySet()) {
ps.setString(2, e.getKey()); ps.setString(2, e.getKey());
ps.setString(3, e.getValue()); ps.setString(3, e.getValue());
@@ -2077,13 +2077,13 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
} }
public void setTransportProperties(Connection txn, String name, public void setTransportProperties(Connection txn, int transportId,
Map<String, String> properties) throws DbException { Map<String, String> properties) throws DbException {
setTransportDetails(txn, name, properties, "transports"); setTransportDetails(txn, transportId, properties, "transports");
} }
public void setTransports(Connection txn, ContactId c, public void setTransports(Connection txn, ContactId c,
Map<String, Map<String, String>> transports, long timestamp) Map<Integer, Map<String, String>> transports, long timestamp)
throws DbException { throws DbException {
PreparedStatement ps = null; PreparedStatement ps = null;
ResultSet rs = null; ResultSet rs = null;
@@ -2107,13 +2107,14 @@ abstract class JdbcDatabase implements Database<Connection> {
ps.executeUpdate(); ps.executeUpdate();
ps.close(); ps.close();
// Store the new transports // Store the new transports
sql = "INSERT INTO contactTransports (contactId, name, key, value)" sql = "INSERT INTO contactTransports"
+ " (contactId, transportId, key, value)"
+ " VALUES (?, ?, ?, ?)"; + " VALUES (?, ?, ?, ?)";
ps = txn.prepareStatement(sql); ps = txn.prepareStatement(sql);
ps.setInt(1, c.getInt()); ps.setInt(1, c.getInt());
int batchSize = 0; int batchSize = 0;
for(Entry<String, Map<String, String>> e : transports.entrySet()) { for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
ps.setString(2, e.getKey()); ps.setInt(2, e.getKey());
for(Entry<String, String> e1 : e.getValue().entrySet()) { for(Entry<String, String> e1 : e.getValue().entrySet()) {
ps.setString(3, e1.getKey()); ps.setString(3, e1.getKey());
ps.setString(4, e1.getValue()); ps.setString(4, e1.getValue());

View File

@@ -70,7 +70,7 @@ class InvitationWorker implements Runnable {
File invitationDat = new File(dir, "invitation.dat"); File invitationDat = new File(dir, "invitation.dat");
callback.encryptingFile(invitationDat); callback.encryptingFile(invitationDat);
// FIXME: Create a real invitation // FIXME: Create a real invitation
Map<String, Map<String, String>> transports; Map<Integer, Map<String, String>> transports;
try { try {
transports = db.getTransports(); transports = db.getTransports();
} catch(DbException e) { } catch(DbException e) {

View File

@@ -6,6 +6,6 @@ import net.sf.briar.api.protocol.TransportUpdate;
interface TransportFactory { interface TransportFactory {
TransportUpdate createTransports(Map<String, Map<String, String>> transports, TransportUpdate createTransportUpdate(
long timestamp); Map<Integer, Map<String, String>> transports, long timestamp);
} }

View File

@@ -6,8 +6,8 @@ import net.sf.briar.api.protocol.TransportUpdate;
class TransportFactoryImpl implements TransportFactory { class TransportFactoryImpl implements TransportFactory {
public TransportUpdate createTransports(Map<String, Map<String, String>> transports, public TransportUpdate createTransportUpdate(
long timestamp) { Map<Integer, Map<String, String>> transports, long timestamp) {
return new TransportUpdateImpl(transports, timestamp); return new TransportUpdateImpl(transports, timestamp);
} }
} }

View File

@@ -37,25 +37,25 @@ class TransportReader implements ObjectReader<TransportUpdate> {
r.removeObjectReader(Types.TRANSPORT_PROPERTIES); r.removeObjectReader(Types.TRANSPORT_PROPERTIES);
if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE) if(l.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE)
throw new FormatException(); throw new FormatException();
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
for(TransportProperties t : l) { for(TransportProperties t : l) {
if(transports.put(t.name, t.properties) != null) if(transports.put(t.transportId, t.properties) != null)
throw new FormatException(); // Duplicate plugin name throw new FormatException(); // Duplicate plugin name
} }
long timestamp = r.readInt64(); long timestamp = r.readInt64();
r.removeConsumer(counting); r.removeConsumer(counting);
// Build and return the transport update // Build and return the transport update
return transportFactory.createTransports(transports, timestamp); return transportFactory.createTransportUpdate(transports, timestamp);
} }
private static class TransportProperties { private static class TransportProperties {
private final String name; private final int transportId;
private final Map<String, String> properties; private final Map<String, String> properties;
TransportProperties(String name, Map<String, String> properties) { TransportProperties(int transportId, Map<String, String> properties) {
this.name = name; this.transportId = transportId;
this.properties = properties; this.properties = properties;
} }
} }
@@ -65,14 +65,14 @@ class TransportReader implements ObjectReader<TransportUpdate> {
public TransportProperties readObject(Reader r) throws IOException { public TransportProperties readObject(Reader r) throws IOException {
r.readUserDefinedId(Types.TRANSPORT_PROPERTIES); r.readUserDefinedId(Types.TRANSPORT_PROPERTIES);
String name = r.readString(TransportUpdate.MAX_NAME_LENGTH); int transportId = r.readInt32();
r.setMaxStringLength(TransportUpdate.MAX_KEY_OR_VALUE_LENGTH); r.setMaxStringLength(TransportUpdate.MAX_KEY_OR_VALUE_LENGTH);
Map<String, String> properties = Map<String, String> properties =
r.readMap(String.class, String.class); r.readMap(String.class, String.class);
r.resetMaxStringLength(); r.resetMaxStringLength();
if(properties.size() > TransportUpdate.MAX_PROPERTIES_PER_PLUGIN) if(properties.size() > TransportUpdate.MAX_PROPERTIES_PER_PLUGIN)
throw new FormatException(); throw new FormatException();
return new TransportProperties(name, properties); return new TransportProperties(transportId, properties);
} }
} }
} }

View File

@@ -6,16 +6,16 @@ import net.sf.briar.api.protocol.TransportUpdate;
class TransportUpdateImpl implements TransportUpdate { class TransportUpdateImpl implements TransportUpdate {
private final Map<String, Map<String, String>> transports; private final Map<Integer, Map<String, String>> transports;
private final long timestamp; private final long timestamp;
TransportUpdateImpl(Map<String, Map<String, String>> transports, TransportUpdateImpl(Map<Integer, Map<String, String>> transports,
long timestamp) { long timestamp) {
this.transports = transports; this.transports = transports;
this.timestamp = timestamp; this.timestamp = timestamp;
} }
public Map<String, Map<String, String>> getTransports() { public Map<Integer, Map<String, String>> getTransports() {
return transports; return transports;
} }

View File

@@ -20,13 +20,13 @@ class TransportWriterImpl implements TransportWriter {
w = writerFactory.createWriter(out); w = writerFactory.createWriter(out);
} }
public void writeTransports(Map<String, Map<String, String>> transports, public void writeTransports(Map<Integer, Map<String, String>> transports,
long timestamp) throws IOException { long timestamp) throws IOException {
w.writeUserDefinedId(Types.TRANSPORT_UPDATE); w.writeUserDefinedId(Types.TRANSPORT_UPDATE);
w.writeListStart(); w.writeListStart();
for(Entry<String, Map<String, String>> e : transports.entrySet()) { for(Entry<Integer, Map<String, String>> e : transports.entrySet()) {
w.writeUserDefinedId(Types.TRANSPORT_PROPERTIES); w.writeUserDefinedId(Types.TRANSPORT_PROPERTIES);
w.writeString(e.getKey()); w.writeInt32(e.getKey());
w.writeMap(e.getValue()); w.writeMap(e.getValue());
} }
w.writeListEnd(); w.writeListEnd();

View File

@@ -73,7 +73,7 @@ public class ProtocolIntegrationTest extends TestCase {
private final Message message, message1, message2, message3; private final Message message, message1, message2, message3;
private final String authorName = "Alice"; private final String authorName = "Alice";
private final String messageBody = "Hello world"; private final String messageBody = "Hello world";
private final Map<String, Map<String, String>> transports; private final Map<Integer, Map<String, String>> transports;
public ProtocolIntegrationTest() throws Exception { public ProtocolIntegrationTest() throws Exception {
super(); super();
@@ -114,7 +114,7 @@ public class ProtocolIntegrationTest extends TestCase {
message3 = messageEncoder.encodeMessage(null, group1, message3 = messageEncoder.encodeMessage(null, group1,
groupKeyPair.getPrivate(), author, authorKeyPair.getPrivate(), groupKeyPair.getPrivate(), author, authorKeyPair.getPrivate(),
messageBody.getBytes("UTF-8")); messageBody.getBytes("UTF-8"));
transports = Collections.singletonMap("foo", transports = Collections.singletonMap(transportId,
Collections.singletonMap("bar", "baz")); Collections.singletonMap("bar", "baz"));
} }

View File

@@ -53,7 +53,7 @@ public abstract class DatabaseComponentTest extends TestCase {
private final byte[] raw; private final byte[] raw;
private final Message message, privateMessage; private final Message message, privateMessage;
private final Group group; private final Group group;
private final Map<String, Map<String, String>> transports; private final Map<Integer, Map<String, String>> transports;
private final byte[] secret; private final byte[] secret;
public DatabaseComponentTest() { public DatabaseComponentTest() {
@@ -72,7 +72,7 @@ public abstract class DatabaseComponentTest extends TestCase {
privateMessage = privateMessage =
new TestMessage(messageId, null, null, null, timestamp, raw); new TestMessage(messageId, null, null, null, timestamp, raw);
group = new TestGroup(groupId, "The really exciting group", null); group = new TestGroup(groupId, "The really exciting group", null);
transports = Collections.singletonMap("foo", transports = Collections.singletonMap(123,
Collections.singletonMap("bar", "baz")); Collections.singletonMap("bar", "baz"));
secret = new byte[123]; secret = new byte[123];
} }
@@ -1284,15 +1284,15 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).getTransports(txn); oneOf(database).getTransports(txn);
will(returnValue(Collections.singletonMap("foo", properties))); will(returnValue(Collections.singletonMap(123, properties)));
oneOf(database).setTransportProperties(txn, "foo", properties1); oneOf(database).setTransportProperties(txn, 123, properties1);
oneOf(database).commitTransaction(txn); oneOf(database).commitTransaction(txn);
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED); oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, cleaner); DatabaseComponent db = createDatabaseComponent(database, cleaner);
db.addListener(listener); db.addListener(listener);
db.setTransportProperties("foo", properties1); db.setTransportProperties(123, properties1);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -1311,13 +1311,13 @@ public abstract class DatabaseComponentTest extends TestCase {
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).getTransports(txn); oneOf(database).getTransports(txn);
will(returnValue(Collections.singletonMap("foo", properties))); will(returnValue(Collections.singletonMap(123, properties)));
oneOf(database).commitTransaction(txn); oneOf(database).commitTransaction(txn);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, cleaner); DatabaseComponent db = createDatabaseComponent(database, cleaner);
db.addListener(listener); db.addListener(listener);
db.setTransportProperties("foo", properties); db.setTransportProperties(123, properties);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -1336,16 +1336,16 @@ public abstract class DatabaseComponentTest extends TestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).getTransportConfig(txn, "foo"); oneOf(database).getTransportConfig(txn, 123);
will(returnValue(config)); will(returnValue(config));
oneOf(database).setTransportConfig(txn, "foo", config1); oneOf(database).setTransportConfig(txn, 123, config1);
oneOf(database).commitTransaction(txn); oneOf(database).commitTransaction(txn);
oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED); oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, cleaner); DatabaseComponent db = createDatabaseComponent(database, cleaner);
db.addListener(listener); db.addListener(listener);
db.setTransportConfig("foo", config1); db.setTransportConfig(123, config1);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }
@@ -1363,14 +1363,14 @@ public abstract class DatabaseComponentTest extends TestCase {
context.checking(new Expectations() {{ context.checking(new Expectations() {{
oneOf(database).startTransaction(); oneOf(database).startTransaction();
will(returnValue(txn)); will(returnValue(txn));
oneOf(database).getTransportConfig(txn, "foo"); oneOf(database).getTransportConfig(txn, 123);
will(returnValue(config)); will(returnValue(config));
oneOf(database).commitTransaction(txn); oneOf(database).commitTransaction(txn);
}}); }});
DatabaseComponent db = createDatabaseComponent(database, cleaner); DatabaseComponent db = createDatabaseComponent(database, cleaner);
db.addListener(listener); db.addListener(listener);
db.setTransportConfig("foo", config); db.setTransportConfig(123, config);
context.assertIsSatisfied(); context.assertIsSatisfied();
} }

View File

@@ -65,7 +65,7 @@ public class H2DatabaseTest extends TestCase {
private final byte[] raw; private final byte[] raw;
private final Message message, privateMessage; private final Message message, privateMessage;
private final Group group; private final Group group;
private final Map<String, Map<String, String>> transports; private final Map<Integer, Map<String, String>> transports;
private final Map<Group, Long> subscriptions; private final Map<Group, Long> subscriptions;
private final byte[] secret; private final byte[] secret;
@@ -91,7 +91,7 @@ public class H2DatabaseTest extends TestCase {
privateMessage = privateMessage =
new TestMessage(privateMessageId, null, null, null, timestamp, raw); new TestMessage(privateMessageId, null, null, null, timestamp, raw);
group = groupFactory.createGroup(groupId, "Group name", null); group = groupFactory.createGroup(groupId, "Group name", null);
transports = Collections.singletonMap("foo", transports = Collections.singletonMap(123,
Collections.singletonMap("bar", "baz")); Collections.singletonMap("bar", "baz"));
subscriptions = Collections.singletonMap(group, 0L); subscriptions = Collections.singletonMap(group, 0L);
secret = new byte[123]; secret = new byte[123];
@@ -991,27 +991,28 @@ public class H2DatabaseTest extends TestCase {
assertEquals(transports, db.getTransports(txn, contactId)); assertEquals(transports, db.getTransports(txn, contactId));
// Replace the transport properties // Replace the transport properties
Map<String, Map<String, String>> transports1 = Map<Integer, Map<String, String>> transports1 =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
transports1.put("foo", Collections.singletonMap("bar", "baz")); transports1.put(123, Collections.singletonMap("bar", "baz"));
transports1.put("bar", Collections.singletonMap("baz", "quux")); transports1.put(456, Collections.singletonMap("baz", "quux"));
db.setTransports(txn, contactId, transports1, 1); db.setTransports(txn, contactId, transports1, 1);
assertEquals(transports1, db.getTransports(txn, contactId)); assertEquals(transports1, db.getTransports(txn, contactId));
// Remove the transport properties // Remove the transport properties
db.setTransports(txn, contactId, db.setTransports(txn, contactId,
Collections.<String, Map<String, String>>emptyMap(), 2); Collections.<Integer, Map<String, String>>emptyMap(), 2);
assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId)); assertEquals(Collections.emptyMap(), db.getTransports(txn, contactId));
// Set the local transport properties // Set the local transport properties
for(String name : transports.keySet()) { for(Integer transportId : transports.keySet()) {
db.setTransportProperties(txn, name, transports.get(name)); Map<String, String> properties = transports.get(transportId);
db.setTransportProperties(txn, transportId, properties);
} }
assertEquals(transports, db.getTransports(txn)); assertEquals(transports, db.getTransports(txn));
// Remove the local transport properties // Remove the local transport properties
for(String name : transports.keySet()) { for(Integer transportId : transports.keySet()) {
db.setTransportProperties(txn, name, db.setTransportProperties(txn, transportId,
Collections.<String, String>emptyMap()); Collections.<String, String>emptyMap());
} }
assertEquals(Collections.emptyMap(), db.getTransports(txn)); assertEquals(Collections.emptyMap(), db.getTransports(txn));
@@ -1029,17 +1030,17 @@ public class H2DatabaseTest extends TestCase {
Connection txn = db.startTransaction(); Connection txn = db.startTransaction();
// Set the transport config // Set the transport config
db.setTransportConfig(txn, "foo", config); db.setTransportConfig(txn, 123, config);
assertEquals(config, db.getTransportConfig(txn, "foo")); assertEquals(config, db.getTransportConfig(txn, 123));
// Update the transport config // Update the transport config
db.setTransportConfig(txn, "foo", config1); db.setTransportConfig(txn, 123, config1);
assertEquals(config1, db.getTransportConfig(txn, "foo")); assertEquals(config1, db.getTransportConfig(txn, 123));
// Remove the transport config // Remove the transport config
db.setTransportConfig(txn, "foo", db.setTransportConfig(txn, 123,
Collections.<String, String>emptyMap()); Collections.<String, String>emptyMap());
assertEquals(Collections.emptyMap(), db.getTransportConfig(txn, "foo")); assertEquals(Collections.emptyMap(), db.getTransportConfig(txn, 123));
db.commitTransaction(txn); db.commitTransaction(txn);
db.close(); db.close();
@@ -1055,18 +1056,18 @@ public class H2DatabaseTest extends TestCase {
assertEquals(transports, db.getTransports(txn, contactId)); assertEquals(transports, db.getTransports(txn, contactId));
// Replace the transport properties using a timestamp of 2 // Replace the transport properties using a timestamp of 2
Map<String, Map<String, String>> transports1 = Map<Integer, Map<String, String>> transports1 =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
transports1.put("foo", Collections.singletonMap("bar", "baz")); transports1.put(123, Collections.singletonMap("bar", "baz"));
transports1.put("bar", Collections.singletonMap("baz", "quux")); transports1.put(456, Collections.singletonMap("baz", "quux"));
db.setTransports(txn, contactId, transports1, 2); db.setTransports(txn, contactId, transports1, 2);
assertEquals(transports1, db.getTransports(txn, contactId)); assertEquals(transports1, db.getTransports(txn, contactId));
// Try to replace the transport properties using a timestamp of 1 // Try to replace the transport properties using a timestamp of 1
Map<String, Map<String, String>> transports2 = Map<Integer, Map<String, String>> transports2 =
new TreeMap<String, Map<String, String>>(); new TreeMap<Integer, Map<String, String>>();
transports2.put("bar", Collections.singletonMap("baz", "quux")); transports2.put(456, Collections.singletonMap("baz", "quux"));
transports2.put("baz", Collections.singletonMap("quux", "fnord")); transports2.put(789, Collections.singletonMap("quux", "fnord"));
db.setTransports(txn, contactId, transports2, 1); db.setTransports(txn, contactId, transports2, 1);
// The old properties should still be there // The old properties should still be there

View File

@@ -47,7 +47,7 @@ public class ProtocolReadWriteTest extends TestCase {
private final String messageBody = "Hello world"; private final String messageBody = "Hello world";
private final BitSet bitSet; private final BitSet bitSet;
private final Map<Group, Long> subscriptions; private final Map<Group, Long> subscriptions;
private final Map<String, Map<String, String>> transports; private final Map<Integer, Map<String, String>> transports;
private final long timestamp = System.currentTimeMillis(); private final long timestamp = System.currentTimeMillis();
public ProtocolReadWriteTest() throws Exception { public ProtocolReadWriteTest() throws Exception {
@@ -67,7 +67,7 @@ public class ProtocolReadWriteTest extends TestCase {
bitSet.set(3); bitSet.set(3);
bitSet.set(7); bitSet.set(7);
subscriptions = Collections.singletonMap(group, 123L); subscriptions = Collections.singletonMap(group, 123L);
transports = Collections.singletonMap("foo", transports = Collections.singletonMap(123,
Collections.singletonMap("bar", "baz")); Collections.singletonMap("bar", "baz"));
} }

View File

@@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream;
import java.security.PrivateKey; import java.security.PrivateKey;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.TreeMap;
import junit.framework.TestCase; import junit.framework.TestCase;
import net.sf.briar.TestUtils; import net.sf.briar.TestUtils;
@@ -189,13 +190,10 @@ public class ConstantsTest extends TestCase {
public void testTransportsFitIntoUpdate() throws Exception { public void testTransportsFitIntoUpdate() throws Exception {
// Create the maximum number of plugins, each with the maximum number // Create the maximum number of plugins, each with the maximum number
// of maximum-length properties // of maximum-length properties
Map<String, Map<String, String>> transports = Map<Integer, Map<String, String>> transports =
new HashMap<String, Map<String, String>>( new TreeMap<Integer, Map<String, String>>();
TransportUpdate.MAX_PLUGINS_PER_UPDATE);
for(int i = 0; i < TransportUpdate.MAX_PLUGINS_PER_UPDATE; i++) { for(int i = 0; i < TransportUpdate.MAX_PLUGINS_PER_UPDATE; i++) {
String name = createRandomString(TransportUpdate.MAX_NAME_LENGTH); Map<String, String> properties = new TreeMap<String, String>();
Map<String, String> properties = new HashMap<String, String>(
TransportUpdate.MAX_PROPERTIES_PER_PLUGIN);
for(int j = 0; j < TransportUpdate.MAX_PROPERTIES_PER_PLUGIN; j++) { for(int j = 0; j < TransportUpdate.MAX_PROPERTIES_PER_PLUGIN; j++) {
String key = createRandomString( String key = createRandomString(
TransportUpdate.MAX_KEY_OR_VALUE_LENGTH); TransportUpdate.MAX_KEY_OR_VALUE_LENGTH);
@@ -203,7 +201,7 @@ public class ConstantsTest extends TestCase {
TransportUpdate.MAX_KEY_OR_VALUE_LENGTH); TransportUpdate.MAX_KEY_OR_VALUE_LENGTH);
properties.put(key, value); properties.put(key, value);
} }
transports.put(name, properties); transports.put(i, properties);
} }
// Add the transports to an update // Add the transports to an update
ByteArrayOutputStream out = new ByteArrayOutputStream( ByteArrayOutputStream out = new ByteArrayOutputStream(
@@ -212,8 +210,7 @@ public class ConstantsTest extends TestCase {
t.writeTransports(transports, Long.MAX_VALUE); t.writeTransports(transports, Long.MAX_VALUE);
// Check the size of the serialised update // Check the size of the serialised update
assertTrue(out.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE * assertTrue(out.size() > TransportUpdate.MAX_PLUGINS_PER_UPDATE *
(TransportUpdate.MAX_NAME_LENGTH + (4 + TransportUpdate.MAX_PROPERTIES_PER_PLUGIN *
TransportUpdate.MAX_PROPERTIES_PER_PLUGIN *
TransportUpdate.MAX_KEY_OR_VALUE_LENGTH * 2) + 8); TransportUpdate.MAX_KEY_OR_VALUE_LENGTH * 2) + 8);
assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH); assertTrue(out.size() <= ProtocolConstants.MAX_PACKET_LENGTH);
} }

View File

@@ -43,7 +43,7 @@ public class BatchConnectionReadWriteTest extends TestCase {
private final File testDir = TestUtils.getTestDirectory(); private final File testDir = TestUtils.getTestDirectory();
private final File aliceDir = new File(testDir, "alice"); private final File aliceDir = new File(testDir, "alice");
private final File bobDir = new File(testDir, "bob"); private final File bobDir = new File(testDir, "bob");
private final Map<String, Map<String, String>> transports = private final Map<Integer, Map<String, String>> transports =
Collections.emptyMap(); Collections.emptyMap();
private final byte[] aliceSecret, bobSecret; private final byte[] aliceSecret, bobSecret;
private final int transportId = 123; private final int transportId = 123;