mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 11:49:04 +01:00
Store group details in the database. Some tests are still failing...
This commit is contained in:
23
components/net/sf/briar/crypto/CryptoModule.java
Normal file
23
components/net/sf/briar/crypto/CryptoModule.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package net.sf.briar.crypto;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import net.sf.briar.api.crypto.KeyParser;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class CryptoModule extends AbstractModule {
|
||||
|
||||
public static final String DIGEST_ALGO = "SHA-256";
|
||||
public static final String KEY_PAIR_ALGO = "RSA";
|
||||
public static final String SIGNATURE_ALGO = "SHA256withRSA";
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
try {
|
||||
bind(KeyParser.class).toInstance(new KeyParserImpl(KEY_PAIR_ALGO));
|
||||
} catch(NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
components/net/sf/briar/crypto/KeyParserImpl.java
Normal file
26
components/net/sf/briar/crypto/KeyParserImpl.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package net.sf.briar.crypto;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.EncodedKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
import net.sf.briar.api.crypto.KeyParser;
|
||||
|
||||
public class KeyParserImpl implements KeyParser {
|
||||
|
||||
private final KeyFactory keyFactory;
|
||||
|
||||
KeyParserImpl(String algorithm) throws NoSuchAlgorithmException {
|
||||
keyFactory = KeyFactory.getInstance(algorithm);
|
||||
}
|
||||
|
||||
public PublicKey parsePublicKey(byte[] encodedKey)
|
||||
throws InvalidKeySpecException {
|
||||
EncodedKeySpec e = new X509EncodedKeySpec(encodedKey);
|
||||
return keyFactory.generatePublic(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import net.sf.briar.api.db.DbException;
|
||||
import net.sf.briar.api.db.Status;
|
||||
import net.sf.briar.api.protocol.AuthorId;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
@@ -105,7 +106,7 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: subscriptions write.
|
||||
*/
|
||||
void addSubscription(T txn, GroupId g) throws DbException;
|
||||
void addSubscription(T txn, Group g) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns true iff the database contains the given contact.
|
||||
@@ -235,14 +236,14 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: subscriptions read.
|
||||
*/
|
||||
Collection<GroupId> getSubscriptions(T txn) throws DbException;
|
||||
Collection<Group> getSubscriptions(T txn) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the groups to which the given contact subscribes.
|
||||
* <p>
|
||||
* Locking: contacts read, subscriptions read.
|
||||
*/
|
||||
Collection<GroupId> getSubscriptions(T txn, ContactId c) throws DbException;
|
||||
Collection<Group> getSubscriptions(T txn, ContactId c) throws DbException;
|
||||
|
||||
/**
|
||||
* Returns the local transport details.
|
||||
@@ -335,7 +336,7 @@ interface Database<T> {
|
||||
* <p>
|
||||
* Locking: contacts write, subscriptions write.
|
||||
*/
|
||||
void setSubscriptions(T txn, ContactId c, Collection<GroupId> subs,
|
||||
void setSubscriptions(T txn, ContactId c, Collection<Group> subs,
|
||||
long timestamp) throws DbException;
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ import java.util.logging.Logger;
|
||||
import net.sf.briar.api.crypto.Password;
|
||||
import net.sf.briar.api.db.DatabasePassword;
|
||||
import net.sf.briar.api.db.DbException;
|
||||
import net.sf.briar.api.protocol.GroupFactory;
|
||||
|
||||
import org.apache.commons.io.FileSystemUtils;
|
||||
|
||||
@@ -30,8 +31,9 @@ class H2Database extends JdbcDatabase {
|
||||
private final long maxSize;
|
||||
|
||||
@Inject
|
||||
H2Database(File dir, @DatabasePassword Password password, long maxSize) {
|
||||
super("BINARY(32)", "BIGINT");
|
||||
H2Database(File dir, @DatabasePassword Password password, long maxSize,
|
||||
GroupFactory groupFactory) {
|
||||
super(groupFactory, "BINARY(32)", "BIGINT", "BINARY");
|
||||
home = new File(dir, "db");
|
||||
this.password = password;
|
||||
url = "jdbc:h2:split:" + home.getPath()
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.sf.briar.db;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.security.PublicKey;
|
||||
import java.sql.Blob;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
@@ -23,6 +24,8 @@ import net.sf.briar.api.db.DbException;
|
||||
import net.sf.briar.api.db.Status;
|
||||
import net.sf.briar.api.protocol.AuthorId;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupFactory;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
@@ -37,6 +40,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
private static final String CREATE_LOCAL_SUBSCRIPTIONS =
|
||||
"CREATE TABLE localSubscriptions"
|
||||
+ " (groupId HASH NOT NULL,"
|
||||
+ " name VARCHAR NOT NULL,"
|
||||
+ " salt BINARY,"
|
||||
+ " publicKey BINARY,"
|
||||
+ " PRIMARY KEY (groupId))";
|
||||
|
||||
private static final String CREATE_MESSAGES =
|
||||
@@ -84,6 +90,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
"CREATE TABLE contactSubscriptions"
|
||||
+ " (contactId INT NOT NULL,"
|
||||
+ " groupId HASH NOT NULL,"
|
||||
+ " name VARCHAR NOT NULL,"
|
||||
+ " salt BINARY,"
|
||||
+ " publicKey BINARY,"
|
||||
+ " PRIMARY KEY (contactId, groupId),"
|
||||
+ " FOREIGN KEY (contactId) REFERENCES contacts (contactId)"
|
||||
+ " ON DELETE CASCADE)";
|
||||
@@ -157,7 +166,8 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
Logger.getLogger(JdbcDatabase.class.getName());
|
||||
|
||||
// Different database libraries use different names for certain types
|
||||
private final String hashType, timestampType;
|
||||
private final String hashType, timestampType, binaryType;
|
||||
private final GroupFactory groupFactory;
|
||||
private final LinkedList<Connection> connections =
|
||||
new LinkedList<Connection>(); // Locking: self
|
||||
|
||||
@@ -166,9 +176,12 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
protected abstract Connection createConnection() throws SQLException;
|
||||
|
||||
JdbcDatabase(String hashType, String timestampType) {
|
||||
JdbcDatabase(GroupFactory groupFactory, String hashType,
|
||||
String timestampType, String binaryType) {
|
||||
this.groupFactory = groupFactory;
|
||||
this.hashType = hashType;
|
||||
this.timestampType = timestampType;
|
||||
this.binaryType = binaryType;
|
||||
}
|
||||
|
||||
protected void open(boolean resume, File dir, String driverClass)
|
||||
@@ -255,7 +268,9 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
|
||||
private String insertTypeNames(String s) {
|
||||
s = s.replaceAll("HASH", hashType);
|
||||
return s.replaceAll("TIMESTAMP", timestampType);
|
||||
s = s.replaceAll("TIMESTAMP", timestampType);
|
||||
s = s.replaceAll("BINARY", binaryType);
|
||||
return s;
|
||||
}
|
||||
|
||||
private void tryToClose(Connection c) {
|
||||
@@ -512,12 +527,18 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public void addSubscription(Connection txn, GroupId g) throws DbException {
|
||||
public void addSubscription(Connection txn, Group g) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
try {
|
||||
String sql = "INSERT INTO localSubscriptions (groupId) VALUES (?)";
|
||||
String sql = "INSERT INTO localSubscriptions"
|
||||
+ " (groupId, name, salt, publicKey)"
|
||||
+ " VALUES (?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setBytes(1, g.getBytes());
|
||||
ps.setBytes(1, g.getId().getBytes());
|
||||
ps.setString(2, g.getName());
|
||||
ps.setBytes(3, g.getSalt());
|
||||
PublicKey k = g.getPublicKey();
|
||||
ps.setBytes(4, k == null ? null : k.getEncoded());
|
||||
int rowsAffected = ps.executeUpdate();
|
||||
assert rowsAffected == 1;
|
||||
ps.close();
|
||||
@@ -964,19 +985,26 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<GroupId> getSubscriptions(Connection txn)
|
||||
public Collection<Group> getSubscriptions(Connection txn)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT groupId FROM localSubscriptions";
|
||||
String sql = "SELECT (groupId, name, salt, publicKey)"
|
||||
+ " FROM localSubscriptions";
|
||||
ps = txn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
Collection<GroupId> ids = new ArrayList<GroupId>();
|
||||
while(rs.next()) ids.add(new GroupId(rs.getBytes(1)));
|
||||
Collection<Group> subs = new ArrayList<Group>();
|
||||
while(rs.next()) {
|
||||
GroupId id = new GroupId(rs.getBytes(1));
|
||||
String name = rs.getString(2);
|
||||
byte[] salt = rs.getBytes(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
subs.add(groupFactory.createGroup(id, name, salt, publicKey));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return ids;
|
||||
return subs;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
@@ -985,21 +1013,28 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<GroupId> getSubscriptions(Connection txn, ContactId c)
|
||||
public Collection<Group> getSubscriptions(Connection txn, ContactId c)
|
||||
throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = "SELECT groupId FROM contactSubscriptions"
|
||||
String sql = "SELECT (groupId, name, salt, publicKey)"
|
||||
+ " FROM contactSubscriptions"
|
||||
+ " WHERE contactId = ?";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
rs = ps.executeQuery();
|
||||
Collection<GroupId> ids = new ArrayList<GroupId>();
|
||||
while(rs.next()) ids.add(new GroupId(rs.getBytes(1)));
|
||||
Collection<Group> subs = new ArrayList<Group>();
|
||||
while(rs.next()) {
|
||||
GroupId id = new GroupId(rs.getBytes(1));
|
||||
String name = rs.getString(2);
|
||||
byte[] salt = rs.getBytes(3);
|
||||
byte[] publicKey = rs.getBytes(4);
|
||||
subs.add(groupFactory.createGroup(id, name, salt, publicKey));
|
||||
}
|
||||
rs.close();
|
||||
ps.close();
|
||||
return ids;
|
||||
return subs;
|
||||
} catch(SQLException e) {
|
||||
tryToClose(rs);
|
||||
tryToClose(ps);
|
||||
@@ -1329,7 +1364,7 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
}
|
||||
|
||||
public void setSubscriptions(Connection txn, ContactId c,
|
||||
Collection<GroupId> subs, long timestamp) throws DbException {
|
||||
Collection<Group> subs, long timestamp) throws DbException {
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
@@ -1354,12 +1389,17 @@ abstract class JdbcDatabase implements Database<Connection> {
|
||||
ps.executeUpdate();
|
||||
ps.close();
|
||||
// Store the new subscriptions
|
||||
sql = "INSERT INTO contactSubscriptions (contactId, groupId)"
|
||||
+ " VALUES (?, ?)";
|
||||
sql = "INSERT INTO contactSubscriptions"
|
||||
+ "(contactId, groupId, name, salt, publicKey)"
|
||||
+ " VALUES (?, ?, ?, ?, ?)";
|
||||
ps = txn.prepareStatement(sql);
|
||||
ps.setInt(1, c.getInt());
|
||||
for(GroupId g : subs) {
|
||||
ps.setBytes(2, g.getBytes());
|
||||
for(Group g : subs) {
|
||||
ps.setBytes(2, g.getId().getBytes());
|
||||
ps.setString(3, g.getName());
|
||||
ps.setBytes(4, g.getSalt());
|
||||
PublicKey k = g.getPublicKey();
|
||||
ps.setBytes(5, k == null ? null : k.getEncoded());
|
||||
ps.addBatch();
|
||||
}
|
||||
int[] rowsAffectedArray = ps.executeBatch();
|
||||
|
||||
@@ -21,6 +21,7 @@ import net.sf.briar.api.protocol.AuthorId;
|
||||
import net.sf.briar.api.protocol.Batch;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.BatchWriter;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
@@ -347,8 +348,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
// FIXME: This should deal in Groups, not GroupIds
|
||||
Collection<GroupId> subs = db.getSubscriptions(txn);
|
||||
Collection<Group> subs = db.getSubscriptions(txn);
|
||||
s.setSubscriptions(subs);
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Added " + subs.size() + " subscriptions");
|
||||
@@ -431,12 +431,12 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<GroupId> getSubscriptions() throws DbException {
|
||||
public Collection<Group> getSubscriptions() throws DbException {
|
||||
subscriptionLock.readLock().lock();
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Collection<GroupId> subs = db.getSubscriptions(txn);
|
||||
Collection<Group> subs = db.getSubscriptions(txn);
|
||||
db.commitTransaction(txn);
|
||||
return subs;
|
||||
} catch(DbException e) {
|
||||
@@ -575,7 +575,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
try {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Collection<GroupId> subs = s.getSubscriptions();
|
||||
Collection<Group> subs = s.getSubscriptions();
|
||||
db.setSubscriptions(txn, c, subs, s.getTimestamp());
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Received " + subs.size() + " subscriptions");
|
||||
@@ -678,7 +678,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public void subscribe(GroupId g) throws DbException {
|
||||
public void subscribe(Group g) throws DbException {
|
||||
if(LOG.isLoggable(Level.FINE)) LOG.fine("Subscribing to " + g);
|
||||
subscriptionLock.writeLock().lock();
|
||||
try {
|
||||
|
||||
@@ -20,6 +20,7 @@ import net.sf.briar.api.protocol.AuthorId;
|
||||
import net.sf.briar.api.protocol.Batch;
|
||||
import net.sf.briar.api.protocol.BatchId;
|
||||
import net.sf.briar.api.protocol.BatchWriter;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
import net.sf.briar.api.protocol.Message;
|
||||
import net.sf.briar.api.protocol.MessageId;
|
||||
@@ -252,8 +253,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
synchronized(subscriptionLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
// FIXME: This should deal in Groups, not GroupIds
|
||||
Collection<GroupId> subs = db.getSubscriptions(txn);
|
||||
Collection<Group> subs = db.getSubscriptions(txn);
|
||||
s.setSubscriptions(subs);
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Added " + subs.size() + " subscriptions");
|
||||
@@ -320,11 +320,11 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<GroupId> getSubscriptions() throws DbException {
|
||||
public Collection<Group> getSubscriptions() throws DbException {
|
||||
synchronized(subscriptionLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Collection<GroupId> subs = db.getSubscriptions(txn);
|
||||
Collection<Group> subs = db.getSubscriptions(txn);
|
||||
db.commitTransaction(txn);
|
||||
return subs;
|
||||
} catch(DbException e) {
|
||||
@@ -429,7 +429,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
synchronized(subscriptionLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
try {
|
||||
Collection<GroupId> subs = s.getSubscriptions();
|
||||
Collection<Group> subs = s.getSubscriptions();
|
||||
db.setSubscriptions(txn, c, subs, s.getTimestamp());
|
||||
if(LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Received " + subs.size() + " subscriptions");
|
||||
@@ -504,7 +504,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> {
|
||||
}
|
||||
}
|
||||
|
||||
public void subscribe(GroupId g) throws DbException {
|
||||
public void subscribe(Group g) throws DbException {
|
||||
if(LOG.isLoggable(Level.FINE)) LOG.fine("Subscribing to " + g);
|
||||
synchronized(subscriptionLock) {
|
||||
Txn txn = db.startTransaction();
|
||||
|
||||
38
components/net/sf/briar/protocol/GroupFactoryImpl.java
Normal file
38
components/net/sf/briar/protocol/GroupFactoryImpl.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
import net.sf.briar.api.crypto.KeyParser;
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupFactory;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
class GroupFactoryImpl implements GroupFactory {
|
||||
|
||||
private final KeyParser keyParser;
|
||||
|
||||
@Inject
|
||||
GroupFactoryImpl(KeyParser keyParser) {
|
||||
this.keyParser = keyParser;
|
||||
}
|
||||
|
||||
public Group createGroup(GroupId id, String name, byte[] salt,
|
||||
byte[] publicKey) {
|
||||
if(salt == null && publicKey == null)
|
||||
throw new IllegalArgumentException();
|
||||
if(salt != null && publicKey != null)
|
||||
throw new IllegalArgumentException();
|
||||
PublicKey key = null;
|
||||
if(publicKey != null) {
|
||||
try {
|
||||
key = keyParser.parsePublicKey(publicKey);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
return new GroupImpl(id, name, salt, key);
|
||||
}
|
||||
}
|
||||
42
components/net/sf/briar/protocol/GroupImpl.java
Normal file
42
components/net/sf/briar/protocol/GroupImpl.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
import net.sf.briar.api.protocol.Group;
|
||||
import net.sf.briar.api.protocol.GroupId;
|
||||
|
||||
public class GroupImpl implements Group {
|
||||
|
||||
private final GroupId id;
|
||||
private final String name;
|
||||
private final byte[] salt;
|
||||
private final PublicKey publicKey;
|
||||
|
||||
GroupImpl(GroupId id, String name, byte[] salt, PublicKey publicKey) {
|
||||
assert salt == null || publicKey == null;
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.salt = salt;
|
||||
this.publicKey = publicKey;
|
||||
}
|
||||
|
||||
public GroupId getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public boolean isRestricted() {
|
||||
return salt == null;
|
||||
}
|
||||
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publicKey;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,15 @@
|
||||
package net.sf.briar.protocol;
|
||||
|
||||
import net.sf.briar.api.protocol.GroupFactory;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
|
||||
public class ProtocolModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AckFactory.class).to(AckFactoryImpl.class);
|
||||
bind(BatchFactory.class).to(BatchFactoryImpl.class);
|
||||
bind(GroupFactory.class).to(GroupFactoryImpl.class);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user