diff --git a/api/net/sf/briar/api/db/DatabaseListener.java b/api/net/sf/briar/api/db/DatabaseListener.java index 3d52e8fbbef812a20137600337a50c647b21e3ff..85433fd03b6b990d3f159aa8014e1c2bdbe713ec 100644 --- a/api/net/sf/briar/api/db/DatabaseListener.java +++ b/api/net/sf/briar/api/db/DatabaseListener.java @@ -4,6 +4,7 @@ package net.sf.briar.api.db; public interface DatabaseListener { static enum Event { + CONTACTS_UPDATED, MESSAGES_ADDED, SUBSCRIPTIONS_UPDATED, TRANSPORTS_UPDATED diff --git a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java index 5c984a207e122926162fce1d64e059665cb7ce0e..2eb0dde3880619bcb066010efcd5221276545db7 100644 --- a/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java +++ b/components/net/sf/briar/db/ReadWriteLockDatabaseComponent.java @@ -12,7 +12,7 @@ import java.util.logging.Logger; import net.sf.briar.api.ContactId; import net.sf.briar.api.Rating; -import net.sf.briar.api.db.DatabaseListener; +import net.sf.briar.api.db.DatabaseListener.Event; import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.NoSuchContactException; import net.sf.briar.api.protocol.Ack; @@ -106,17 +106,17 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { public ContactId addContact(Map<String, Map<String, String>> transports, byte[] secret) throws DbException { if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact"); + ContactId c; contactLock.writeLock().lock(); try { transportLock.writeLock().lock(); try { Txn txn = db.startTransaction(); try { - ContactId c = db.addContact(txn, transports, secret); + c = db.addContact(txn, transports, secret); db.commitTransaction(txn); if(LOG.isLoggable(Level.FINE)) LOG.fine("Added contact " + c); - return c; } catch(DbException e) { db.abortTransaction(txn); throw e; @@ -127,6 +127,9 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } finally { contactLock.writeLock().unlock(); } + // Call the listeners outside the lock + callListeners(Event.CONTACTS_UPDATED); + return c; } public void addLocallyGeneratedMessage(Message m) throws DbException { @@ -167,7 +170,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { contactLock.readLock().unlock(); } // Call the listeners outside the lock - if(added) callListeners(DatabaseListener.Event.MESSAGES_ADDED); + if(added) callListeners(Event.MESSAGES_ADDED); } public void findLostBatches(ContactId c) throws DbException { @@ -781,7 +784,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { contactLock.readLock().unlock(); } // Call the listeners outside the lock - if(anyAdded) callListeners(DatabaseListener.Event.MESSAGES_ADDED); + if(anyAdded) callListeners(Event.MESSAGES_ADDED); } public void receiveOffer(ContactId c, Offer o, RequestWriter r) @@ -913,6 +916,8 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } finally { contactLock.writeLock().unlock(); } + // Call the listeners outside the lock + callListeners(Event.CONTACTS_UPDATED); } public void setConnectionWindow(ContactId c, int transportId, @@ -984,7 +989,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { transportLock.writeLock().unlock(); } // Call the listeners outside the lock - if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED); + if(changed) callListeners(Event.TRANSPORTS_UPDATED); } public void setTransportProperties(String name, @@ -1008,7 +1013,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { transportLock.writeLock().unlock(); } // Call the listeners outside the lock - if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED); + if(changed) callListeners(Event.TRANSPORTS_UPDATED); } public void setVisibility(GroupId g, Collection<ContactId> visible) @@ -1059,7 +1064,7 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { subscriptionLock.writeLock().unlock(); } // Call the listeners outside the lock - if(added) callListeners(DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + if(added) callListeners(Event.SUBSCRIPTIONS_UPDATED); } public void unsubscribe(GroupId g) throws DbException { @@ -1097,6 +1102,6 @@ class ReadWriteLockDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { contactLock.readLock().unlock(); } // Call the listeners outside the lock - if(removed) callListeners(DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + if(removed) callListeners(Event.SUBSCRIPTIONS_UPDATED); } } \ No newline at end of file diff --git a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java index c5ca968e59a59287a596822275a9355aa152d440..d99f65f4ed7fc4d616ad3eaf3a4cdcc2aaf5a7f9 100644 --- a/components/net/sf/briar/db/SynchronizedDatabaseComponent.java +++ b/components/net/sf/briar/db/SynchronizedDatabaseComponent.java @@ -11,7 +11,7 @@ import java.util.logging.Logger; import net.sf.briar.api.ContactId; import net.sf.briar.api.Rating; -import net.sf.briar.api.db.DatabaseListener; +import net.sf.briar.api.db.DatabaseListener.Event; import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.NoSuchContactException; import net.sf.briar.api.protocol.Ack; @@ -89,21 +89,24 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { public ContactId addContact(Map<String, Map<String, String>> transports, byte[] secret) throws DbException { if(LOG.isLoggable(Level.FINE)) LOG.fine("Adding contact"); + ContactId c; synchronized(contactLock) { synchronized(transportLock) { Txn txn = db.startTransaction(); try { - ContactId c = db.addContact(txn, transports, secret); + c = db.addContact(txn, transports, secret); db.commitTransaction(txn); if(LOG.isLoggable(Level.FINE)) LOG.fine("Added contact " + c); - return c; } catch(DbException e) { db.abortTransaction(txn); throw e; } } } + // Call the listeners outside the lock + callListeners(Event.CONTACTS_UPDATED); + return c; } public void addLocallyGeneratedMessage(Message m) throws DbException { @@ -139,7 +142,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(added) callListeners(DatabaseListener.Event.MESSAGES_ADDED); + if(added) callListeners(Event.MESSAGES_ADDED); } public void findLostBatches(ContactId c) throws DbException { @@ -597,7 +600,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(anyAdded) callListeners(DatabaseListener.Event.MESSAGES_ADDED); + if(anyAdded) callListeners(Event.MESSAGES_ADDED); } public void receiveOffer(ContactId c, Offer o, RequestWriter r) @@ -693,6 +696,8 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } } + // Call the listeners outside the lock + callListeners(Event.CONTACTS_UPDATED); } public void setConnectionWindow(ContactId c, int transportId, @@ -749,7 +754,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED); + if(changed) callListeners(Event.TRANSPORTS_UPDATED); } public void setTransportProperties(String name, @@ -770,7 +775,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(changed) callListeners(DatabaseListener.Event.TRANSPORTS_UPDATED); + if(changed) callListeners(Event.TRANSPORTS_UPDATED); } public void setVisibility(GroupId g, Collection<ContactId> visible) @@ -812,7 +817,7 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(added) callListeners(DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + if(added) callListeners(Event.SUBSCRIPTIONS_UPDATED); } public void unsubscribe(GroupId g) throws DbException { @@ -838,6 +843,6 @@ class SynchronizedDatabaseComponent<Txn> extends DatabaseComponentImpl<Txn> { } } // Call the listeners outside the lock - if(removed) callListeners(DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + if(removed) callListeners(Event.SUBSCRIPTIONS_UPDATED); } } diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java index b7c1d33a206c840899571e92c099b41653133db0..193f4392ea419bddd0daee58d2db8844f09e192e 100644 --- a/test/net/sf/briar/db/DatabaseComponentTest.java +++ b/test/net/sf/briar/db/DatabaseComponentTest.java @@ -15,6 +15,7 @@ import net.sf.briar.api.db.DatabaseListener; import net.sf.briar.api.db.DbException; import net.sf.briar.api.db.NoSuchContactException; import net.sf.briar.api.db.Status; +import net.sf.briar.api.db.DatabaseListener.Event; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.AuthorId; import net.sf.briar.api.protocol.Batch; @@ -101,6 +102,7 @@ public abstract class DatabaseComponentTest extends TestCase { // addContact(transports) oneOf(database).addContact(txn, transports, secret); will(returnValue(contactId)); + oneOf(listener).eventOccurred(Event.CONTACTS_UPDATED); // getContacts() oneOf(database).getContacts(txn); will(returnValue(Collections.singletonList(contactId))); @@ -125,8 +127,7 @@ public abstract class DatabaseComponentTest extends TestCase { oneOf(database).containsSubscription(txn, groupId); will(returnValue(false)); oneOf(database).addSubscription(txn, group); - oneOf(listener).eventOccurred( - DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + oneOf(listener).eventOccurred(Event.SUBSCRIPTIONS_UPDATED); // subscribe(group) again oneOf(group).getId(); will(returnValue(groupId)); @@ -139,8 +140,7 @@ public abstract class DatabaseComponentTest extends TestCase { oneOf(database).containsSubscription(txn, groupId); will(returnValue(true)); oneOf(database).removeSubscription(txn, groupId); - oneOf(listener).eventOccurred( - DatabaseListener.Event.SUBSCRIPTIONS_UPDATED); + oneOf(listener).eventOccurred(Event.SUBSCRIPTIONS_UPDATED); // unsubscribe(groupId) again oneOf(database).containsSubscription(txn, groupId); will(returnValue(false)); @@ -151,6 +151,7 @@ public abstract class DatabaseComponentTest extends TestCase { connectionWindow); // removeContact(contactId) oneOf(database).removeContact(txn, contactId); + oneOf(listener).eventOccurred(Event.CONTACTS_UPDATED); // close() oneOf(cleaner).stopCleaning(); oneOf(database).close(); @@ -1124,8 +1125,7 @@ public abstract class DatabaseComponentTest extends TestCase { oneOf(database).setSendability(txn, messageId, 0); oneOf(database).commitTransaction(txn); // The message was added, so the listener should be called - oneOf(listener).eventOccurred( - DatabaseListener.Event.MESSAGES_ADDED); + oneOf(listener).eventOccurred(Event.MESSAGES_ADDED); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner); @@ -1180,8 +1180,7 @@ public abstract class DatabaseComponentTest extends TestCase { will(returnValue(Collections.singletonMap("foo", properties))); oneOf(database).setTransportProperties(txn, "foo", properties1); oneOf(database).commitTransaction(txn); - oneOf(listener).eventOccurred( - DatabaseListener.Event.TRANSPORTS_UPDATED); + oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner); @@ -1234,8 +1233,7 @@ public abstract class DatabaseComponentTest extends TestCase { will(returnValue(config)); oneOf(database).setTransportConfig(txn, "foo", config1); oneOf(database).commitTransaction(txn); - oneOf(listener).eventOccurred( - DatabaseListener.Event.TRANSPORTS_UPDATED); + oneOf(listener).eventOccurred(Event.TRANSPORTS_UPDATED); }}); DatabaseComponent db = createDatabaseComponent(database, cleaner);