mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-13 11:19:04 +01:00
Changed the format of transport properties from (key, value) pairs to
(transport name, key, value) triples. This makes it possible for each transport plugin to update its locally stored properties atomically.
This commit is contained in:
@@ -82,7 +82,7 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: contacts write, transports write.
|
||||
*/
|
||||
ContactId addContact(T txn, Map<String, String> transports)
|
||||
ContactId addContact(T txn, Map<String, Map<String, String>> transports)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
@@ -272,14 +272,15 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: transports read.
|
||||
*/
|
||||
Map<String, String> getTransports(T txn) throws DbException;
|
||||
Map<String, Map<String, String>> getTransports(T txn) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the transport properties for the given contact.
|
||||
* <p>
|
||||
* Locking: contacts read, transports read.
|
||||
*/
|
||||
Map<String, String> getTransports(T txn, ContactId c) throws DbException;
|
||||
Map<String, Map<String, String>> getTransports(T txn, ContactId c)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the contacts to which the given group is visible.
|
||||
@@ -397,11 +398,12 @@ interface Database<T> {
|
||||
long timestamp) throws DbException;
|
||||
|
||||
/**
|
||||
* Sets the local transport properties, replacing any existing properties.
|
||||
* Sets the local transport properties for the transport with the given
|
||||
* name, replacing any existing properties for that transport.
|
||||
* <p>
|
||||
* Locking: transports write.
|
||||
*/
|
||||
void setTransports(T txn, Map<String, String> transports)
|
||||
void setTransports(T txn, String name, Map<String, String> transports)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
@@ -411,8 +413,9 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: contacts write, transports write.
|
||||
*/
|
||||
void setTransports(T txn, ContactId c, Map<String, String> transports,
|
||||
long timestamp) throws DbException;
|
||||
void setTransports(T txn, ContactId c,
|
||||
Map<String, Map<String, String>> transports, long timestamp)
|
||||
throws DbException;
|
||||
|
||||
/**
|
||||
* Makes the given group visible to the given set of contacts and invisible
|
||||
|
||||
@@ -159,17 +159,19 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private static final String CREATE_CONTACT_TRANSPORTS =
|
||||
"CREATE TABLE contactTransports"
|
||||
+ " (contactId INT NOT NULL,"
|
||||
+ " transportName VARCHAR NOT NULL,"
|
||||
+ " key VARCHAR NOT NULL,"
|
||||
+ " value VARCHAR NOT NULL,"
|
||||
+ " PRIMARY KEY (contactId, key),"
|
||||
+ " PRIMARY KEY (contactId, transportName, key),"
|
||||
+ " FOREIGN KEY (contactId) REFERENCES contacts (contactId)"
|
||||
+ " ON DELETE CASCADE)";
|
||||
|
||||
private static final String CREATE_LOCAL_TRANSPORTS =
|
||||
"CREATE TABLE localTransports"
|
||||
+ " (key VARCHAR NOT NULL,"
|
||||
private static final String CREATE_TRANSPORTS =
|
||||
"CREATE TABLE transports"
|
||||
+ " (transportName VARCHAR NOT NULL,"
|
||||
+ " key VARCHAR NOT NULL,"
|
||||
+ " value VARCHAR NOT NULL,"
|
||||
+ " PRIMARY KEY (key))";
|
||||
+ " PRIMARY KEY (transportName, key))";
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(JdbcDatabase.class.getName());
|
||||
@@ -252,7 +254,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
s.executeUpdate(INDEX_STATUSES_BY_MESSAGE);
|
||||
s.executeUpdate(INDEX_STATUSES_BY_CONTACT);
|
||||
s.executeUpdate(insertTypeNames(CREATE_CONTACT_TRANSPORTS));
|
||||
s.executeUpdate(insertTypeNames(CREATE_LOCAL_TRANSPORTS));
|
||||
s.executeUpdate(insertTypeNames(CREATE_TRANSPORTS));
|
||||
s.close();
|
||||
} catch(SQLException e) {
|
||||
tryToClose(s);
|
||||
@@ -406,7 +408,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public ContactId addContact(Connection txn, Map<String, String> transports)
|
||||
public ContactId addContact(Connection txn,
|
||||
Map<String, Map<String, String>> transports)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
@@ -434,24 +437,27 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
if(affected != 1) throw new DbStateException();
|
||||
ps.close();
|
||||
// Store the contact's transport properties
|
||||
if(transports != null) {
|
||||
sql = "INSERT INTO contactTransports (contactId, key, value)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
for(Entry<String, String> e : transports.entrySet()) {
|
||||
ps.setString(2, e.getKey());
|
||||
ps.setString(3, e.getValue());
|
||||
sql = "INSERT INTO contactTransports"
|
||||
+ " (contactId, transportName, key, value)"
|
||||
+ " VALUES (?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
int batchSize = 0;
|
||||
for(Entry<String, Map<String, String>> e : transports.entrySet()) {
|
||||
ps.setString(2, e.getKey());
|
||||
for(Entry<String, String> e1 : e.getValue().entrySet()) {
|
||||
ps.setString(3, e1.getKey());
|
||||
ps.setString(4, e1.getValue());
|
||||
ps.addBatch();
|
||||
batchSize++;
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != transports.size())
|
||||
throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != batchSize) throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
return c;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(ps);
|
||||
@@ -1119,19 +1125,31 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports(Connection txn)
|
||||
public Map<String, Map<String, String>> getTransports(Connection txn)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT key, value FROM localTransports";
|
||||
String sql = "SELECT transportName, key, value"
|
||||
+ " FROM transports"
|
||||
+ " ORDER BY transportName";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
Map<String, String> transports = new TreeMap<String, String>();
|
||||
while(rs.next()) transports.put(rs.getString(1), rs.getString(2));
|
||||
Map<String, Map<String, String>> outer =
|
||||
new TreeMap<String, Map<String, String>>();
|
||||
Map<String, String> inner = null;
|
||||
String lastName = null;
|
||||
while(rs.next()) {
|
||||
String name = rs.getString(1);
|
||||
if(!name.equals(lastName)) {
|
||||
inner = new TreeMap<String, String>();
|
||||
outer.put(name, inner);
|
||||
}
|
||||
inner.put(rs.getString(2), rs.getString(3));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return transports;
|
||||
return outer;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
@@ -1139,21 +1157,33 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports(Connection txn, ContactId c)
|
||||
throws DbException {
|
||||
public Map<String, Map<String, String>> getTransports(Connection txn,
|
||||
ContactId c) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT key, value FROM contactTransports"
|
||||
+ " WHERE contactId = ?";
|
||||
String sql = "SELECT transportName, key, value"
|
||||
+ " FROM contactTransports"
|
||||
+ " WHERE contactId = ?"
|
||||
+ " ORDER BY transportName";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
rs = ps.executeQuery();
|
||||
Map<String, String> transports = new TreeMap<String, String>();
|
||||
while(rs.next()) transports.put(rs.getString(1), rs.getString(2));
|
||||
Map<String, Map<String, String>> outer =
|
||||
new TreeMap<String, Map<String, String>>();
|
||||
Map<String, String> inner = null;
|
||||
String lastName = null;
|
||||
while(rs.next()) {
|
||||
String name = rs.getString(1);
|
||||
if(!name.equals(lastName)) {
|
||||
inner = new TreeMap<String, String>();
|
||||
outer.put(name, inner);
|
||||
}
|
||||
inner.put(rs.getString(2), rs.getString(3));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return transports;
|
||||
return outer;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
@@ -1579,33 +1609,33 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransports(Connection txn, Map<String, String> transports)
|
||||
throws DbException {
|
||||
public void setTransports(Connection txn, String name,
|
||||
Map<String, String> transports) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
// Delete any existing transports
|
||||
String sql = "DELETE FROM localTransports";
|
||||
// Delete any existing properties for the named transport
|
||||
String sql = "DELETE FROM transports WHERE transportName = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, name);
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
// Store the new transports
|
||||
if(!transports.isEmpty()) {
|
||||
sql = "INSERT INTO localTransports (key, value)"
|
||||
+ " VALUES (?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
for(Entry<String, String> e : transports.entrySet()) {
|
||||
ps.setString(1, e.getKey());
|
||||
ps.setString(2, e.getValue());
|
||||
ps.addBatch();
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != transports.size())
|
||||
throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
// Store the new properties
|
||||
sql = "INSERT INTO transports (transportName, key, value)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setString(1, name);
|
||||
for(Entry<String, String> e : transports.entrySet()) {
|
||||
ps.setString(2, e.getKey());
|
||||
ps.setString(3, e.getValue());
|
||||
ps.addBatch();
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != transports.size())
|
||||
throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
} catch(SQLException e) {
|
||||
tryToClose(ps);
|
||||
throw new DbException(e);
|
||||
@@ -1613,7 +1643,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
|
||||
public void setTransports(Connection txn, ContactId c,
|
||||
Map<String, String> transports, long timestamp) throws DbException {
|
||||
Map<String, Map<String, String>> transports, long timestamp)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
@@ -1636,24 +1667,27 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
// Store the new transports
|
||||
if(transports != null) {
|
||||
sql = "INSERT INTO contactTransports (contactId, key, value)"
|
||||
+ " VALUES (?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
for(Entry<String, String> e : transports.entrySet()) {
|
||||
ps.setString(2, e.getKey());
|
||||
ps.setString(3, e.getValue());
|
||||
sql = "INSERT INTO contactTransports"
|
||||
+ " (contactId, transportName, key, value)"
|
||||
+ " VALUES (?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
int batchSize = 0;
|
||||
for(Entry<String, Map<String, String>> e : transports.entrySet()) {
|
||||
ps.setString(2, e.getKey());
|
||||
for(Entry<String, String> e1 : e.getValue().entrySet()) {
|
||||
ps.setString(3, e1.getKey());
|
||||
ps.setString(4, e1.getValue());
|
||||
ps.addBatch();
|
||||
batchSize++;
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != transports.size())
|
||||
throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
}
|
||||
int[] batchAffected = ps.executeBatch();
|
||||
if(batchAffected.length != batchSize) throw new DbStateException();
|
||||
for(int i = 0; i < batchAffected.length; i++) {
|
||||
if(batchAffected[i] != 1) throw new DbStateException();
|
||||
}
|
||||
ps.close();
|
||||
// Update the timestamp
|
||||
sql = "UPDATE contacts SET transportsTimestamp = ?"
|
||||
+ " WHERE contactId = ?";
|
||||
|
||||
@@ -125,7 +125,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public ContactId addContact(Map<String, String> transports)
|
||||
public ContactId addContact(Map<String, Map<String, String>> transports)
|
||||
throws DbException {
|
||||
if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
|
||||
contactLock.writeLock().lock();
|
||||
@@ -497,7 +497,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn);
|
||||
t.writeTransports(transports);
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Added " + transports.size() + " transports");
|
||||
@@ -568,12 +569,13 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports() throws DbException {
|
||||
public Map<String, Map<String, String>> getTransports() throws DbException {
|
||||
transportLock.readLock().lock();
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn);
|
||||
db.commitTransaction(txn);
|
||||
return transports;
|
||||
} catch(DbException e) {
|
||||
@@ -585,7 +587,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports(ContactId c) throws DbException {
|
||||
public Map<String, Map<String, String>> getTransports(ContactId c)
|
||||
throws DbException {
|
||||
contactLock.readLock().lock();
|
||||
try {
|
||||
if(!containsContact(c)) throw new NoSuchContactException();
|
||||
@@ -593,7 +596,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn, c);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn, c);
|
||||
db.commitTransaction(txn);
|
||||
return transports;
|
||||
} catch(DbException e) {
|
||||
@@ -826,7 +830,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = t.getTransports();
|
||||
Map<String, Map<String, String>> transports =
|
||||
t.getTransports();
|
||||
db.setTransports(txn, c, transports, t.getTimestamp());
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Received " + transports.size()
|
||||
@@ -902,15 +907,15 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransports(Map<String, String> transports)
|
||||
public void setTransports(String name, Map<String, String> transports)
|
||||
throws DbException {
|
||||
boolean changed = false;
|
||||
transportLock.writeLock().lock();
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
if(!transports.equals(db.getTransports(txn))) {
|
||||
db.setTransports(txn, transports);
|
||||
if(!transports.equals(db.getTransports(txn).get(name))) {
|
||||
db.setTransports(txn, name, transports);
|
||||
changed = true;
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
|
||||
@@ -96,7 +96,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public ContactId addContact(Map<String, String> transports)
|
||||
public ContactId addContact(Map<String, Map<String, String>> transports)
|
||||
throws DbException {
|
||||
if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact");
|
||||
synchronized(contactLock) {
|
||||
@@ -366,7 +366,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
synchronized(transportLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn);
|
||||
t.writeTransports(transports);
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Added " + transports.size() + " transports");
|
||||
@@ -424,11 +425,12 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports() throws DbException {
|
||||
public Map<String, Map<String, String>> getTransports() throws DbException {
|
||||
synchronized(transportLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn);
|
||||
db.commitTransaction(txn);
|
||||
return transports;
|
||||
} catch(DbException e) {
|
||||
@@ -438,13 +440,15 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports(ContactId c) throws DbException {
|
||||
public Map<String, Map<String, String>> getTransports(ContactId c)
|
||||
throws DbException {
|
||||
synchronized(contactLock) {
|
||||
if(!containsContact(c)) throw new NoSuchContactException();
|
||||
synchronized(transportLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = db.getTransports(txn, c);
|
||||
Map<String, Map<String, String>> transports =
|
||||
db.getTransports(txn, c);
|
||||
db.commitTransaction(txn);
|
||||
return transports;
|
||||
} catch(DbException e) {
|
||||
@@ -614,7 +618,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
synchronized(transportLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Map<String, String> transports = t.getTransports();
|
||||
Map<String, Map<String, String>> transports =
|
||||
t.getTransports();
|
||||
db.setTransports(txn, c, transports, t.getTimestamp());
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Received " + transports.size()
|
||||
@@ -668,14 +673,14 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransports(Map<String, String> transports)
|
||||
public void setTransports(String name, Map<String, String> transports)
|
||||
throws DbException {
|
||||
boolean changed = false;
|
||||
synchronized(transportLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
if(!transports.equals(db.getTransports(txn))) {
|
||||
db.setTransports(txn, transports);
|
||||
if(!transports.equals(db.getTransports(txn).get(name))) {
|
||||
db.setTransports(txn, name, transports);
|
||||
changed = true;
|
||||
}
|
||||
db.commitTransaction(txn);
|
||||
|
||||
@@ -71,7 +71,7 @@ class InvitationWorker implements Runnable {
|
||||
File invitationDat = new File(dir, "invitation.dat");
|
||||
callback.encryptingFile(invitationDat);
|
||||
// FIXME: Create a real invitation
|
||||
Map<String, String> transports;
|
||||
Map<String, Map<String, String>> transports;
|
||||
try {
|
||||
transports = databaseComponent.getTransports();
|
||||
} catch(DbException e) {
|
||||
|
||||
@@ -6,5 +6,6 @@ import net.sf.briar.api.protocol.Transports;
|
||||
|
||||
interface TransportFactory {
|
||||
|
||||
Transports createTransports(Map<String, String> transports, long timestamp);
|
||||
Transports createTransports(Map<String, Map<String, String>> transports,
|
||||
long timestamp);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import net.sf.briar.api.protocol.Transports;
|
||||
|
||||
class TransportFactoryImpl implements TransportFactory {
|
||||
|
||||
public Transports createTransports(Map<String, String> transports,
|
||||
public Transports createTransports(Map<String, Map<String, String>> transports,
|
||||
long timestamp) {
|
||||
return new TransportsImpl(transports, timestamp);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.sf.briar.protocol;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.sf.briar.api.protocol.Tags;
|
||||
import net.sf.briar.api.protocol.Transports;
|
||||
@@ -26,10 +27,26 @@ class TransportReader implements ObjectReader<Transports> {
|
||||
// Read the data
|
||||
r.addConsumer(counting);
|
||||
r.readUserDefinedTag(Tags.TRANSPORTS);
|
||||
Map<String, String> transports = r.readMap(String.class, String.class);
|
||||
// Transport maps are always written in delimited form
|
||||
Map<String, Map<String, String>> outer =
|
||||
new TreeMap<String, Map<String, String>>();
|
||||
r.readMapStart();
|
||||
while(!r.hasMapEnd()) {
|
||||
String name = r.readString(Transports.MAX_SIZE);
|
||||
Map<String, String> inner = new TreeMap<String, String>();
|
||||
r.readMapStart();
|
||||
while(!r.hasMapEnd()) {
|
||||
String key = r.readString(Transports.MAX_SIZE);
|
||||
String value = r.readString(Transports.MAX_SIZE);
|
||||
inner.put(key, value);
|
||||
}
|
||||
r.readMapEnd();
|
||||
outer.put(name, inner);
|
||||
}
|
||||
r.readMapEnd();
|
||||
long timestamp = r.readInt64();
|
||||
r.removeConsumer(counting);
|
||||
// Build and return the transports update
|
||||
return transportFactory.createTransports(transports, timestamp);
|
||||
return transportFactory.createTransports(outer, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,16 @@ import net.sf.briar.api.protocol.Transports;
|
||||
|
||||
class TransportsImpl implements Transports {
|
||||
|
||||
private final Map<String, String> transports;
|
||||
private final Map<String, Map<String, String>> transports;
|
||||
private final long timestamp;
|
||||
|
||||
TransportsImpl(Map<String, String> transports, long timestamp) {
|
||||
TransportsImpl(Map<String, Map<String, String>> transports,
|
||||
long timestamp) {
|
||||
this.transports = transports;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public Map<String, String> getTransports() {
|
||||
public Map<String, Map<String, String>> getTransports() {
|
||||
return transports;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.sf.briar.protocol.writers;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import net.sf.briar.api.protocol.Tags;
|
||||
import net.sf.briar.api.protocol.writers.TransportWriter;
|
||||
@@ -19,10 +20,21 @@ class TransportWriterImpl implements TransportWriter {
|
||||
w = writerFactory.createWriter(out);
|
||||
}
|
||||
|
||||
public void writeTransports(Map<String, String> transports)
|
||||
public void writeTransports(Map<String, Map<String, String>> transports)
|
||||
throws IOException {
|
||||
w.writeUserDefinedTag(Tags.TRANSPORTS);
|
||||
w.writeMap(transports);
|
||||
// Transport maps are always written in delimited form
|
||||
w.writeMapStart();
|
||||
for(Entry<String, Map<String, String>> e : transports.entrySet()) {
|
||||
w.writeString(e.getKey());
|
||||
w.writeMapStart();
|
||||
for(Entry<String, String> e1 : e.getValue().entrySet()) {
|
||||
w.writeString(e1.getKey());
|
||||
w.writeString(e1.getValue());
|
||||
}
|
||||
w.writeMapEnd();
|
||||
}
|
||||
w.writeMapEnd();
|
||||
w.writeInt64(System.currentTimeMillis());
|
||||
out.flush();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user