From 94722a9f2a0e2bcf26f7ab06e9206ba882facd1d Mon Sep 17 00:00:00 2001 From: akwizgran <akwizgran@users.sourceforge.net> Date: Wed, 26 Oct 2011 15:40:38 +0100 Subject: [PATCH] Broadcast an event when an author's rating changes. --- .../api/db/event/RatingChangedEvent.java | 23 +++++++++++++++ .../sf/briar/db/DatabaseComponentImpl.java | 5 ++++ .../sf/briar/db/DatabaseComponentTest.java | 29 ++++++++++++++----- 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 api/net/sf/briar/api/db/event/RatingChangedEvent.java diff --git a/api/net/sf/briar/api/db/event/RatingChangedEvent.java b/api/net/sf/briar/api/db/event/RatingChangedEvent.java new file mode 100644 index 0000000000..a3395ef27e --- /dev/null +++ b/api/net/sf/briar/api/db/event/RatingChangedEvent.java @@ -0,0 +1,23 @@ +package net.sf.briar.api.db.event; + +import net.sf.briar.api.Rating; +import net.sf.briar.api.protocol.AuthorId; + +public class RatingChangedEvent extends DatabaseEvent { + + private final AuthorId author; + private final Rating rating; + + public RatingChangedEvent(AuthorId author, Rating rating) { + this.author = author; + this.rating = rating; + } + + public AuthorId getAuthor() { + return author; + } + + public Rating getRating() { + return rating; + } +} diff --git a/components/net/sf/briar/db/DatabaseComponentImpl.java b/components/net/sf/briar/db/DatabaseComponentImpl.java index b9ae4b7c60..6bce3e9d8b 100644 --- a/components/net/sf/briar/db/DatabaseComponentImpl.java +++ b/components/net/sf/briar/db/DatabaseComponentImpl.java @@ -35,6 +35,7 @@ import net.sf.briar.api.db.event.ContactRemovedEvent; import net.sf.briar.api.db.event.DatabaseEvent; import net.sf.briar.api.db.event.DatabaseListener; import net.sf.briar.api.db.event.MessagesAddedEvent; +import net.sf.briar.api.db.event.RatingChangedEvent; import net.sf.briar.api.db.event.SubscriptionsUpdatedEvent; import net.sf.briar.api.db.event.TransportsUpdatedEvent; import net.sf.briar.api.protocol.Ack; @@ -1233,6 +1234,7 @@ DatabaseCleaner.Callback { } public void setRating(AuthorId a, Rating r) throws DbException { + boolean changed; messageLock.writeLock().lock(); try { ratingLock.writeLock().lock(); @@ -1240,6 +1242,7 @@ DatabaseCleaner.Callback { T txn = db.startTransaction(); try { Rating old = db.setRating(txn, a, r); + changed = (old != r); // Update the sendability of the author's messages if(r == Rating.GOOD && old != Rating.GOOD) updateAuthorSendability(txn, a, true); @@ -1256,6 +1259,8 @@ DatabaseCleaner.Callback { } finally { messageLock.writeLock().unlock(); } + // Call the listeners outside the lock + if(changed) callListeners(new RatingChangedEvent(a, r)); } public void setSeen(ContactId c, Collection<MessageId> seen) diff --git a/test/net/sf/briar/db/DatabaseComponentTest.java b/test/net/sf/briar/db/DatabaseComponentTest.java index 7d4efe5703..e2618ad7c3 100644 --- a/test/net/sf/briar/db/DatabaseComponentTest.java +++ b/test/net/sf/briar/db/DatabaseComponentTest.java @@ -19,6 +19,7 @@ import net.sf.briar.api.db.event.ContactAddedEvent; import net.sf.briar.api.db.event.ContactRemovedEvent; import net.sf.briar.api.db.event.DatabaseListener; import net.sf.briar.api.db.event.MessagesAddedEvent; +import net.sf.briar.api.db.event.RatingChangedEvent; import net.sf.briar.api.db.event.TransportsUpdatedEvent; import net.sf.briar.api.protocol.Ack; import net.sf.briar.api.protocol.AuthorId; @@ -114,6 +115,15 @@ public abstract class DatabaseComponentTest extends TestCase { // getRating(authorId) oneOf(database).getRating(txn, authorId); will(returnValue(Rating.UNRATED)); + // setRating(authorId, Rating.GOOD) + oneOf(database).setRating(txn, authorId, Rating.GOOD); + will(returnValue(Rating.UNRATED)); + oneOf(database).getMessagesByAuthor(txn, authorId); + will(returnValue(Collections.<MessageId>emptyList())); + oneOf(listener).eventOccurred(with(any(RatingChangedEvent.class))); + // setRating(authorId, Rating.GOOD) again + oneOf(database).setRating(txn, authorId, Rating.GOOD); + will(returnValue(Rating.GOOD)); // addContact(transports) oneOf(database).addContact(txn, transports, secret); will(returnValue(contactId)); @@ -177,18 +187,20 @@ public abstract class DatabaseComponentTest extends TestCase { db.open(false); db.addListener(listener); assertEquals(Rating.UNRATED, db.getRating(authorId)); + db.setRating(authorId, Rating.GOOD); // First time - listeners called + db.setRating(authorId, Rating.GOOD); // Second time - not called assertEquals(contactId, db.addContact(transports, secret)); assertEquals(Collections.singletonList(contactId), db.getContacts()); assertEquals(connectionWindow, db.getConnectionWindow(contactId, transportId)); assertEquals(secret, db.getSharedSecret(contactId)); assertEquals(remoteProperties, db.getRemoteProperties(transportId)); - db.subscribe(group); // First time - check listeners are called - db.subscribe(group); // Second time - check listeners aren't called + db.subscribe(group); // First time - listeners called + db.subscribe(group); // Second time - not called assertEquals(Collections.emptyList(), db.getMessageHeaders(groupId)); assertEquals(Collections.singletonList(groupId), db.getSubscriptions()); - db.unsubscribe(groupId); // First time - check listeners are called - db.unsubscribe(groupId); // Second time - check listeners aren't called + db.unsubscribe(groupId); // First time - listeners called + db.unsubscribe(groupId); // Second time - not called db.setConnectionWindow(contactId, transportId, connectionWindow); db.removeContact(contactId); db.removeListener(listener); @@ -204,10 +216,11 @@ public abstract class DatabaseComponentTest extends TestCase { final Database<Object> database = context.mock(Database.class); final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); context.checking(new Expectations() {{ - // setRating(Rating.GOOD) + // setRating(authorId, Rating.GOOD) allowing(database).startTransaction(); will(returnValue(txn)); oneOf(database).setRating(txn, authorId, Rating.GOOD); + will(returnValue(Rating.UNRATED)); // The sendability of the author's messages should be incremented oneOf(database).getMessagesByAuthor(txn, authorId); will(returnValue(Collections.singletonList(messageId))); @@ -233,10 +246,11 @@ public abstract class DatabaseComponentTest extends TestCase { final Database<Object> database = context.mock(Database.class); final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); context.checking(new Expectations() {{ - // setRating(Rating.GOOD) + // setRating(authorId, Rating.GOOD) oneOf(database).startTransaction(); will(returnValue(txn)); oneOf(database).setRating(txn, authorId, Rating.GOOD); + will(returnValue(Rating.UNRATED)); // The sendability of the author's messages should be incremented oneOf(database).getMessagesByAuthor(txn, authorId); will(returnValue(Collections.singletonList(messageId))); @@ -267,10 +281,11 @@ public abstract class DatabaseComponentTest extends TestCase { final Database<Object> database = context.mock(Database.class); final DatabaseCleaner cleaner = context.mock(DatabaseCleaner.class); context.checking(new Expectations() {{ - // setRating(Rating.GOOD) + // setRating(authorId, Rating.GOOD) oneOf(database).startTransaction(); will(returnValue(txn)); oneOf(database).setRating(txn, authorId, Rating.GOOD); + will(returnValue(Rating.UNRATED)); // The sendability of the author's messages should be incremented oneOf(database).getMessagesByAuthor(txn, authorId); will(returnValue(Collections.singletonList(messageId))); -- GitLab