Updated group-related events and exceptions.

This commit is contained in:
akwizgran
2016-01-27 17:29:17 +00:00
parent 9d537dce00
commit 3837efca6b
23 changed files with 159 additions and 226 deletions

View File

@@ -13,13 +13,12 @@ import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.sync.GroupId;
@@ -83,7 +82,7 @@ implements EventListener, OnItemClickListener {
Collection<Contact> c =
forumManager.getSubscribers(id);
available.add(new ForumContacts(f, c));
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Continue
}
}
@@ -123,15 +122,19 @@ implements EventListener, OnItemClickListener {
}
public void eventOccurred(Event e) {
if (e instanceof RemoteSubscriptionsUpdatedEvent) {
LOG.info("Remote subscriptions changed, reloading");
loadForums();
} else if (e instanceof SubscriptionAddedEvent) {
LOG.info("Subscription added, reloading");
loadForums();
} else if (e instanceof SubscriptionRemovedEvent) {
LOG.info("Subscription removed, reloading");
loadForums();
// TODO: What other events are needed here?
if (e instanceof GroupAddedEvent) {
GroupAddedEvent g = (GroupAddedEvent) e;
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
LOG.info("Forum added, reloading");
loadForums();
}
} else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
LOG.info("Forum removed, reloading");
loadForums();
}
}
}

View File

@@ -19,13 +19,13 @@ import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.android.AndroidNotificationManager;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostHeader;
@@ -159,7 +159,7 @@ public class ForumActivity extends BriarActivity implements EventListener,
if (LOG.isLoggable(INFO))
LOG.info("Loading forum " + duration + " ms");
displayForumName();
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
@@ -188,7 +188,7 @@ public class ForumActivity extends BriarActivity implements EventListener,
if (LOG.isLoggable(INFO))
LOG.info("Load took " + duration + " ms");
displayHeaders(headers);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
finishOnUiThread();
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
@@ -319,10 +319,10 @@ public class ForumActivity extends BriarActivity implements EventListener,
LOG.info("Message added, reloading");
loadHeaders();
}
} else if (e instanceof SubscriptionRemovedEvent) {
SubscriptionRemovedEvent s = (SubscriptionRemovedEvent) e;
} else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent s = (GroupRemovedEvent) e;
if (s.getGroup().getId().equals(groupId)) {
LOG.info("Subscription removed");
LOG.info("Forum removed");
finishOnUiThread();
}
}

View File

@@ -24,17 +24,15 @@ import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.forum.Forum;
import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.forum.ForumPostHeader;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId;
import java.util.Collection;
@@ -169,7 +167,7 @@ public class ForumListFragment extends BaseEventFragment implements
Collection<ForumPostHeader> headers =
forumManager.getPostHeaders(f.getId());
displayHeaders(f, headers);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Continue
}
}
@@ -254,6 +252,7 @@ public class ForumListFragment extends BaseEventFragment implements
}
public void eventOccurred(Event e) {
// TODO: What other events are needed here?
if (e instanceof MessageValidatedEvent) {
MessageValidatedEvent m = (MessageValidatedEvent) e;
ClientId c = m.getClientId();
@@ -261,16 +260,16 @@ public class ForumListFragment extends BaseEventFragment implements
LOG.info("Message added, reloading");
loadHeaders(m.getMessage().getGroupId());
}
} else if (e instanceof RemoteSubscriptionsUpdatedEvent) {
LOG.info("Remote subscriptions changed, reloading");
loadAvailable();
} else if (e instanceof SubscriptionAddedEvent) {
LOG.info("Group added, reloading");
loadHeaders();
} else if (e instanceof SubscriptionRemovedEvent) {
Group g = ((SubscriptionRemovedEvent) e).getGroup();
if (g.getClientId().equals(forumManager.getClientId())) {
LOG.info("Group removed, reloading");
} else if (e instanceof GroupAddedEvent) {
GroupAddedEvent g = (GroupAddedEvent) e;
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
LOG.info("Forum added, reloading");
loadHeaders();
}
} else if (e instanceof GroupRemovedEvent) {
GroupRemovedEvent g = (GroupRemovedEvent) e;
if (g.getGroup().getClientId().equals(forumManager.getClientId())) {
LOG.info("Forum removed, reloading");
loadHeaders();
}
}
@@ -288,7 +287,7 @@ public class ForumListFragment extends BaseEventFragment implements
if (LOG.isLoggable(INFO))
LOG.info("Partial load took " + duration + " ms");
displayHeaders(f, headers);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
removeForum(g);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))

View File

@@ -45,11 +45,8 @@ public interface DatabaseComponent {
*/
ContactId addContact(Author remote, AuthorId local) throws DbException;
/**
* Subscribes to a group, or returns false if the user already has the
* maximum number of subscriptions.
*/
boolean addGroup(Group g) throws DbException;
/** Stores a group. */
void addGroup(Group g) throws DbException;
/** Stores a local pseudonym. */
void addLocalAuthor(LocalAuthor a) throws DbException;
@@ -120,16 +117,13 @@ public interface DatabaseComponent {
/** Returns the unique ID for this device. */
DeviceId getDeviceId() throws DbException;
/** Returns the group with the given ID, if the user subscribes to it. */
/** Returns the group with the given ID. */
Group getGroup(GroupId g) throws DbException;
/** Returns the metadata for the given group. */
Metadata getGroupMetadata(GroupId g) throws DbException;
/**
* Returns all groups belonging to the given client to which the user
* subscribes.
*/
/** Returns all groups belonging to the given client. */
Collection<Group> getGroups(ClientId c) throws DbException;
/** Returns the local pseudonym with the given ID. */
@@ -221,10 +215,7 @@ public interface DatabaseComponent {
/** Removes a contact (and all associated state) from the database. */
void removeContact(ContactId c) throws DbException;
/**
* Unsubscribes from a group. Any messages belonging to the group
* are deleted from the database.
*/
/** Removes a group (and all associated state) from the database. */
void removeGroup(Group g) throws DbException;
/**
@@ -232,10 +223,7 @@ public interface DatabaseComponent {
*/
void removeLocalAuthor(AuthorId a) throws DbException;
/**
* Removes a transport (and any associated configuration and local
* properties) from the database.
*/
/** Removes a transport (and all associated state) from the database. */
void removeTransport(TransportId t) throws DbException;
/** Sets the status of the given contact. */

View File

@@ -0,0 +1,11 @@
package org.briarproject.api.db;
/**
* Thrown when a database operation is attempted for a group that is not in the
* database. This exception may occur due to concurrent updates and does not
* indicate a database error.
*/
public class NoSuchGroupException extends DbException {
private static final long serialVersionUID = -5494178507342571697L;
}

View File

@@ -1,12 +0,0 @@
package org.briarproject.api.db;
/**
* Thrown when a database operation is attempted for a group to which the user
* does not subscribe. This exception may occur due to concurrent updates and
* does not indicate a database error.
*/
public class NoSuchSubscriptionException extends DbException {
private static final long serialVersionUID = -5494178507342571697L;
}

View File

@@ -2,12 +2,12 @@ package org.briarproject.api.event;
import org.briarproject.api.sync.Group;
/** An event that is broadcast when the user subscribes to a group. */
public class SubscriptionAddedEvent extends Event {
/** An event that is broadcast when a group is added. */
public class GroupAddedEvent extends Event {
private final Group group;
public SubscriptionAddedEvent(Group group) {
public GroupAddedEvent(Group group) {
this.group = group;
}

View File

@@ -2,12 +2,12 @@ package org.briarproject.api.event;
import org.briarproject.api.sync.Group;
/** An event that is broadcast when the user unsubscribes from a group. */
public class SubscriptionRemovedEvent extends Event {
/** An event that is broadcast when a group is removed. */
public class GroupRemovedEvent extends Event {
private final Group group;
public SubscriptionRemovedEvent(Group group) {
public GroupRemovedEvent(Group group) {
this.group = group;
}

View File

@@ -4,15 +4,12 @@ import org.briarproject.api.contact.ContactId;
import java.util.Collection;
/**
* An event that is broadcast when the set of subscriptions visible to one or
* more contacts is updated.
*/
public class LocalSubscriptionsUpdatedEvent extends Event {
/** An event that is broadcast when the visibility of a group is updated. */
public class GroupVisibilityUpdatedEvent extends Event {
private final Collection<ContactId> affected;
public LocalSubscriptionsUpdatedEvent(Collection<ContactId> affected) {
public GroupVisibilityUpdatedEvent(Collection<ContactId> affected) {
this.affected = affected;
}

View File

@@ -1,17 +0,0 @@
package org.briarproject.api.event;
import org.briarproject.api.contact.ContactId;
/** An event that is broadcast when a contact's subscriptions are updated. */
public class RemoteSubscriptionsUpdatedEvent extends Event {
private final ContactId contactId;
public RemoteSubscriptionsUpdatedEvent(ContactId contactId) {
this.contactId = contactId;
}
public ContactId getContactId() {
return contactId;
}
}

View File

@@ -17,11 +17,8 @@ public interface ForumManager {
/** Creates a forum with the given name. */
Forum createForum(String name);
/**
* Subscribes to a forum, or returns false if the user already has the
* maximum number of forum subscriptions.
*/
boolean addForum(Forum f) throws DbException;
/** Subscribes to a forum. */
void addForum(Forum f) throws DbException;
/** Stores a local forum post. */
void addLocalPost(ForumPost p) throws DbException;
@@ -29,7 +26,7 @@ public interface ForumManager {
/** Returns all forums to which the user could subscribe. */
Collection<Forum> getAvailableForums() throws DbException;
/** Returns the forum with the given ID, if the user subscribes to it. */
/** Returns the forum with the given ID. */
Forum getForum(GroupId g) throws DbException;
/** Returns all forums to which the user subscribes. */
@@ -47,10 +44,7 @@ public interface ForumManager {
/** Returns the IDs of all contacts to which the given forum is visible. */
Collection<ContactId> getVisibility(GroupId g) throws DbException;
/**
* Unsubscribes from a forum. Any messages belonging to the forum are
* deleted.
*/
/** Unsubscribes from a forum. */
void removeForum(Forum f) throws DbException;
/** Marks a forum post as read or unread. */

View File

@@ -2,7 +2,6 @@ package org.briarproject.api.sync;
import static org.briarproject.api.sync.SyncConstants.MAX_GROUP_DESCRIPTOR_LENGTH;
/** A group to which users may subscribe. */
public class Group {
private final GroupId id;

View File

@@ -13,11 +13,8 @@ public interface SyncConstants {
/** The maximum length of the packet payload in bytes. */
int MAX_PACKET_PAYLOAD_LENGTH = 32 * 1024; // 32 KiB
/** The maximum number of groups a user may subscribe to. */
int MAX_SUBSCRIPTIONS = 200; // TODO: Remove
/** The maximum length of a group descriptor in bytes. */
int MAX_GROUP_DESCRIPTOR_LENGTH = 100; // TODO: Remove
int MAX_GROUP_DESCRIPTOR_LENGTH = 1000; // TODO: Remove
/** The maximum length of a message in bytes. */
int MAX_MESSAGE_LENGTH = MAX_PACKET_PAYLOAD_LENGTH - PACKET_HEADER_LENGTH;

View File

@@ -84,12 +84,11 @@ interface Database<T> {
throws DbException;
/**
* Subscribes to a group, or returns false if the user already has the
* maximum number of subscriptions.
* Stores a group.
* <p>
* Locking: write.
*/
boolean addGroup(T txn, Group g) throws DbException;
void addGroup(T txn, Group g) throws DbException;
/**
* Stores a local pseudonym.
@@ -164,7 +163,7 @@ interface Database<T> {
boolean containsContact(T txn, ContactId c) throws DbException;
/**
* Returns true if the user subscribes to the given group.
* Returns true if the database contains the given group.
* <p>
* Locking: read.
*/
@@ -192,7 +191,7 @@ interface Database<T> {
boolean containsTransport(T txn, TransportId t) throws DbException;
/**
* Returns true if the user subscribes to the given group and the group is
* Returns true if the database contains the given group and the group is
* visible to the given contact.
* <p>
* Locking: read.
@@ -259,7 +258,7 @@ interface Database<T> {
long getFreeSpace() throws DbException;
/**
* Returns the group with the given ID, if the user subscribes to it.
* Returns the group with the given ID.
* <p>
* Locking: read.
*/
@@ -273,8 +272,7 @@ interface Database<T> {
Metadata getGroupMetadata(T txn, GroupId g) throws DbException;
/**
* Returns all groups belonging to the given client to which the user
* subscribes.
* Returns all groups belonging to the given client.
* <p>
* Locking: read.
*/
@@ -500,16 +498,14 @@ interface Database<T> {
void removeContact(T txn, ContactId c) throws DbException;
/**
* Unsubscribes from a group. Any messages belonging to the group are
* deleted from the database.
* Removes a group (and all associated state) from the database.
* <p>
* Locking: write.
*/
void removeGroup(T txn, GroupId g) throws DbException;
/**
* Removes a local pseudonym (and all associated contacts) from the
* database.
* Removes a local pseudonym (and all associated state) from the database.
* <p>
* Locking: write.
*/

View File

@@ -11,13 +11,15 @@ import org.briarproject.api.db.LocalAuthorExistsException;
import org.briarproject.api.db.MessageExistsException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchContactException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.event.GroupVisibilityUpdatedEvent;
import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageSharedEvent;
@@ -27,8 +29,6 @@ import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.MessagesAckedEvent;
import org.briarproject.api.event.MessagesSentEvent;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.event.TransportAddedEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.identity.Author;
@@ -161,14 +161,16 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
}
}
public boolean addGroup(Group g) throws DbException {
public void addGroup(Group g) throws DbException {
boolean added = false;
lock.writeLock().lock();
try {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g.getId()))
added = db.addGroup(txn, g);
if (!db.containsGroup(txn, g.getId())) {
added = true;
db.addGroup(txn, g);
}
db.commitTransaction(txn);
} catch (DbException e) {
db.abortTransaction(txn);
@@ -177,8 +179,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
if (added) eventBus.broadcast(new SubscriptionAddedEvent(g));
return added;
if (added) eventBus.broadcast(new GroupAddedEvent(g));
}
public void addLocalAuthor(LocalAuthor a) throws DbException {
@@ -208,7 +209,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (db.containsMessage(txn, m.getId()))
throw new MessageExistsException();
if (!db.containsGroup(txn, m.getGroupId()))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
addMessage(txn, m, VALID, shared, null);
db.mergeMessageMetadata(txn, m.getId(), meta);
db.commitTransaction(txn);
@@ -493,7 +494,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Group group = db.getGroup(txn, g);
db.commitTransaction(txn);
return group;
@@ -512,7 +513,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Metadata metadata = db.getGroupMetadata(txn, g);
db.commitTransaction(txn);
return metadata;
@@ -622,7 +623,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Map<MessageId, Metadata> metadata =
db.getMessageMetadata(txn, g);
db.commitTransaction(txn);
@@ -664,7 +665,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
if (!db.containsContact(txn, c))
throw new NoSuchContactException();
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Collection<MessageStatus> statuses =
db.getMessageStatus(txn, c, g);
db.commitTransaction(txn);
@@ -763,7 +764,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
Collection<ContactId> visible = db.getVisibility(txn, g);
db.commitTransaction(txn);
return visible;
@@ -804,7 +805,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
db.mergeGroupMetadata(txn, g, meta);
db.commitTransaction(txn);
} catch (DbException e) {
@@ -998,7 +999,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
try {
GroupId id = g.getId();
if (!db.containsGroup(txn, id))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
affected = db.getVisibility(txn, id);
db.removeGroup(txn, id);
db.commitTransaction(txn);
@@ -1009,8 +1010,8 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
} finally {
lock.writeLock().unlock();
}
eventBus.broadcast(new SubscriptionRemovedEvent(g));
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupRemovedEvent(g));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void removeLocalAuthor(AuthorId a) throws DbException {
@@ -1157,7 +1158,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
// Use HashSets for O(1) lookups, O(n) overall running time
HashSet<ContactId> now = new HashSet<ContactId>(visible);
Collection<ContactId> before = db.getVisibility(txn, g);
@@ -1185,7 +1186,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
lock.writeLock().unlock();
}
if (!affected.isEmpty())
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void setVisibleToAll(GroupId g, boolean all) throws DbException {
@@ -1195,7 +1196,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
T txn = db.startTransaction();
try {
if (!db.containsGroup(txn, g))
throw new NoSuchSubscriptionException();
throw new NoSuchGroupException();
// Make the group visible or invisible to future contacts
db.setVisibleToAll(txn, g, all);
if (all) {
@@ -1218,7 +1219,7 @@ class DatabaseComponentImpl<T> implements DatabaseComponent {
lock.writeLock().unlock();
}
if (!affected.isEmpty())
eventBus.broadcast(new LocalSubscriptionsUpdatedEvent(affected));
eventBus.broadcast(new GroupVisibilityUpdatedEvent(affected));
}
public void updateTransportKeys(Map<ContactId, TransportKeys> keys)

View File

@@ -50,7 +50,6 @@ import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.db.Metadata.REMOVE;
import static org.briarproject.api.db.StorageStatus.ADDING;
import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.sync.ValidationManager.Validity.INVALID;
import static org.briarproject.api.sync.ValidationManager.Validity.UNKNOWN;
import static org.briarproject.api.sync.ValidationManager.Validity.VALID;
@@ -544,21 +543,10 @@ abstract class JdbcDatabase implements Database<Connection> {
}
}
public boolean addGroup(Connection txn, Group g) throws DbException {
public void addGroup(Connection txn, Group g) throws DbException {
PreparedStatement ps = null;
ResultSet rs = null;
try {
String sql = "SELECT COUNT (groupId) FROM groups";
ps = txn.prepareStatement(sql);
rs = ps.executeQuery();
if (!rs.next()) throw new DbStateException();
int count = rs.getInt(1);
if (rs.next()) throw new DbStateException();
rs.close();
ps.close();
if (count > MAX_SUBSCRIPTIONS) throw new DbStateException();
if (count == MAX_SUBSCRIPTIONS) return false;
sql = "INSERT INTO groups"
String sql = "INSERT INTO groups"
+ " (groupId, clientId, descriptor, visibleToAll)"
+ " VALUES (?, ?, ?, FALSE)";
ps = txn.prepareStatement(sql);
@@ -568,9 +556,7 @@ abstract class JdbcDatabase implements Database<Connection> {
int affected = ps.executeUpdate();
if (affected != 1) throw new DbStateException();
ps.close();
return true;
} catch (SQLException e) {
tryToClose(rs);
tryToClose(ps);
throw new DbException(e);
}

View File

@@ -113,8 +113,8 @@ class ForumManagerImpl implements ForumManager {
}
@Override
public boolean addForum(Forum f) throws DbException {
return db.addGroup(f.getGroup());
public void addForum(Forum f) throws DbException {
db.addGroup(f.getGroup());
}
@Override

View File

@@ -73,7 +73,7 @@ class MessagingManagerImpl implements MessagingManager, AddContactHook,
try {
// Create the conversation group
Group g = getConversationGroup(db.getContact(c));
// Subscribe to the group and share it with the contact
// Store the group and share it with the contact
db.addGroup(g);
db.setVisibility(g.getId(), Collections.singletonList(c));
// Attach the contact ID to the group

View File

@@ -19,7 +19,7 @@ import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ClientId;
@@ -96,7 +96,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
try {
// Create a group to share with the contact
Group g = getContactGroup(db.getContact(c));
// Subscribe to the group and share it with the contact
// Store the group and share it with the contact
db.addGroup(g);
db.setVisibility(g.getId(), Collections.singletonList(c));
// Copy the latest local properties into the group
@@ -197,7 +197,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
local.put(e.getKey(), decodeProperties(raw));
}
return Collections.unmodifiableMap(local);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Local group doesn't exist - there are no local properties
return Collections.emptyMap();
} catch (IOException e) {
@@ -254,7 +254,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
if (latest == null) return null;
// Retrieve and decode the latest local properties
return decodeProperties(db.getRawMessage(latest.messageId));
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
// Local group doesn't exist - there are no local properties
return null;
} catch (IOException e) {

View File

@@ -8,13 +8,12 @@ import org.briarproject.api.event.ContactRemovedEvent;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.GroupVisibilityUpdatedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageSharedEvent;
import org.briarproject.api.event.MessageToAckEvent;
import org.briarproject.api.event.MessageToRequestEvent;
import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.RemoteSubscriptionsUpdatedEvent;
import org.briarproject.api.event.ShutdownEvent;
import org.briarproject.api.event.TransportRemovedEvent;
import org.briarproject.api.sync.Ack;
@@ -155,10 +154,9 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
} else if (e instanceof MessageValidatedEvent) {
if (((MessageValidatedEvent) e).isValid())
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof LocalSubscriptionsUpdatedEvent) {
LocalSubscriptionsUpdatedEvent l =
(LocalSubscriptionsUpdatedEvent) e;
if (l.getAffectedContacts().contains(contactId))
} else if (e instanceof GroupVisibilityUpdatedEvent) {
GroupVisibilityUpdatedEvent g = (GroupVisibilityUpdatedEvent) e;
if (g.getAffectedContacts().contains(contactId))
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof MessageRequestedEvent) {
if (((MessageRequestedEvent) e).getContactId().equals(contactId))
@@ -169,11 +167,6 @@ class DuplexOutgoingSession implements SyncSession, EventListener {
} else if (e instanceof MessageToRequestEvent) {
if (((MessageToRequestEvent) e).getContactId().equals(contactId))
dbExecutor.execute(new GenerateRequest());
} else if (e instanceof RemoteSubscriptionsUpdatedEvent) {
RemoteSubscriptionsUpdatedEvent r =
(RemoteSubscriptionsUpdatedEvent) e;
if (r.getContactId().equals(contactId))
dbExecutor.execute(new GenerateOffer());
} else if (e instanceof ShutdownEvent) {
interrupt();
} else if (e instanceof TransportRemovedEvent) {

View File

@@ -8,8 +8,8 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.MessageAddedEvent;
@@ -158,7 +158,7 @@ class ValidationManagerImpl implements ValidationManager, Service,
try {
ClientId c = db.getGroup(m.getGroupId()).getClientId();
validateMessage(m, c);
} catch (NoSuchSubscriptionException e) {
} catch (NoSuchGroupException e) {
LOG.info("Group removed before validation");
} catch (DbException e) {
if (LOG.isLoggable(WARNING))

View File

@@ -10,13 +10,15 @@ import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.MessageExistsException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchContactException;
import org.briarproject.api.db.NoSuchGroupException;
import org.briarproject.api.db.NoSuchLocalAuthorException;
import org.briarproject.api.db.NoSuchMessageException;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.db.NoSuchTransportException;
import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.LocalSubscriptionsUpdatedEvent;
import org.briarproject.api.event.GroupAddedEvent;
import org.briarproject.api.event.GroupRemovedEvent;
import org.briarproject.api.event.GroupVisibilityUpdatedEvent;
import org.briarproject.api.event.MessageAddedEvent;
import org.briarproject.api.event.MessageRequestedEvent;
import org.briarproject.api.event.MessageToAckEvent;
@@ -25,8 +27,6 @@ import org.briarproject.api.event.MessageValidatedEvent;
import org.briarproject.api.event.MessagesAckedEvent;
import org.briarproject.api.event.MessagesSentEvent;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.event.SubscriptionAddedEvent;
import org.briarproject.api.event.SubscriptionRemovedEvent;
import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor;
@@ -146,8 +146,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).containsGroup(txn, groupId);
will(returnValue(false));
oneOf(database).addGroup(txn, group);
will(returnValue(true));
oneOf(eventBus).broadcast(with(any(SubscriptionAddedEvent.class)));
oneOf(eventBus).broadcast(with(any(GroupAddedEvent.class)));
// addGroup() again
oneOf(database).containsGroup(txn, groupId);
will(returnValue(true));
@@ -160,10 +159,9 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).getVisibility(txn, groupId);
will(returnValue(Collections.emptyList()));
oneOf(database).removeGroup(txn, groupId);
oneOf(eventBus).broadcast(with(any(GroupRemovedEvent.class)));
oneOf(eventBus).broadcast(with(any(
SubscriptionRemovedEvent.class)));
oneOf(eventBus).broadcast(with(any(
LocalSubscriptionsUpdatedEvent.class)));
GroupVisibilityUpdatedEvent.class)));
// removeContact()
oneOf(database).containsContact(txn, contactId);
will(returnValue(true));
@@ -222,7 +220,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
}
@Test
public void testLocalMessagesAreNotStoredUnlessSubscribed()
public void testLocalMessagesAreNotStoredUnlessGroupExists()
throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
@@ -244,7 +242,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
try {
db.addLocalMessage(message, clientId, metadata, true);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
@@ -446,7 +444,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
}
@Test
public void testVariousMethodsThrowExceptionIfSubscriptionIsMissing()
public void testVariousMethodsThrowExceptionIfGroupIsMissing()
throws Exception {
Mockery context = new Mockery();
@SuppressWarnings("unchecked")
@@ -454,7 +452,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
final ShutdownManager shutdown = context.mock(ShutdownManager.class);
final EventBus eventBus = context.mock(EventBus.class);
context.checking(new Expectations() {{
// Check whether the subscription is in the DB (which it's not)
// Check whether the group is in the DB (which it's not)
exactly(7).of(database).startTransaction();
will(returnValue(txn));
exactly(7).of(database).containsGroup(txn, groupId);
@@ -470,49 +468,49 @@ public class DatabaseComponentImplTest extends BriarTestCase {
try {
db.getGroup(groupId);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.getGroupMetadata(groupId);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.getMessageStatus(contactId, groupId);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.getVisibility(groupId);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.mergeGroupMetadata(groupId, metadata);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.removeGroup(group);
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
try {
db.setVisibility(groupId, Collections.<ContactId>emptyList());
fail();
} catch (NoSuchSubscriptionException expected) {
} catch (NoSuchGroupException expected) {
// Expected
}
@@ -1039,7 +1037,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).setVisibleToAll(txn, groupId, false);
oneOf(database).commitTransaction(txn);
oneOf(eventBus).broadcast(with(any(
LocalSubscriptionsUpdatedEvent.class)));
GroupVisibilityUpdatedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);
@@ -1103,7 +1101,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).setVisibleToAll(txn, groupId, false);
oneOf(database).commitTransaction(txn);
oneOf(eventBus).broadcast(with(any(
LocalSubscriptionsUpdatedEvent.class)));
GroupVisibilityUpdatedEvent.class)));
// setVisibleToAll()
oneOf(database).startTransaction();
will(returnValue(txn));
@@ -1117,7 +1115,7 @@ public class DatabaseComponentImplTest extends BriarTestCase {
oneOf(database).addVisibility(txn, contactId1, groupId);
oneOf(database).commitTransaction(txn);
oneOf(eventBus).broadcast(with(any(
LocalSubscriptionsUpdatedEvent.class)));
GroupVisibilityUpdatedEvent.class)));
}});
DatabaseComponent db = createDatabaseComponent(database, eventBus,
shutdown);

View File

@@ -146,15 +146,15 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testUnsubscribingRemovesMessage() throws Exception {
public void testRemovingGroupRemovesMessage() throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Subscribe to a group and store a message
// Add a group and a message
db.addGroup(txn, group);
db.addMessage(txn, message, VALID, true);
// Unsubscribing from the group should remove the message
// Removing the group should remove the message
assertTrue(db.containsMessage(txn, messageId));
db.removeGroup(txn, groupId);
assertFalse(db.containsMessage(txn, messageId));
@@ -168,7 +168,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -281,7 +281,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -307,14 +307,14 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
db.addMessage(txn, message, VALID, true);
db.addStatus(txn, contactId, messageId, false, false);
// The subscription is not visible to the contact, so the message
// The group is not visible to the contact, so the message
// should not be sendable
Collection<MessageId> ids = db.getMessagesToSend(txn, contactId,
ONE_MEGABYTE);
@@ -322,7 +322,7 @@ public class H2DatabaseTest extends BriarTestCase {
ids = db.getMessagesToOffer(txn, contactId, 100);
assertTrue(ids.isEmpty());
// Making the subscription visible should make the message sendable
// Making the group visible should make the message sendable
db.addVisibility(txn, contactId, groupId);
ids = db.getMessagesToSend(txn, contactId, ONE_MEGABYTE);
assertEquals(Collections.singletonList(messageId), ids);
@@ -345,7 +345,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
// Add a contact and a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -381,7 +381,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -545,7 +545,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
// Add a contact and a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -559,7 +559,7 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testContainsVisibleMessageRequiresLocalSubscription()
public void testContainsVisibleMessageRequiresGroupInDatabase()
throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
@@ -568,7 +568,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
// There's no local subscription for the group
// The group is not in the database
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
db.commitTransaction(txn);
@@ -576,19 +576,19 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testContainsVisibleMessageRequiresVisibileSubscription()
public void testContainsVisibleMessageRequiresVisibileGroup()
throws Exception {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact, subscribe to a group and store a message
// Add a contact, a group and a message
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
db.addMessage(txn, message, VALID, true);
db.addStatus(txn, contactId, messageId, false, false);
// The subscription is not visible
// The group is not visible
assertFalse(db.containsVisibleMessage(txn, contactId, messageId));
db.commitTransaction(txn);
@@ -600,7 +600,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to a group
// Add a contact and a group
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
db.addGroup(txn, group);
@@ -622,7 +622,7 @@ public class H2DatabaseTest extends BriarTestCase {
}
@Test
public void testMultipleSubscriptionsAndUnsubscriptions() throws Exception {
public void testMultipleGroupChanges() throws Exception {
// Create some groups
List<Group> groups = new ArrayList<Group>();
for (int i = 0; i < 100; i++) {
@@ -635,7 +635,7 @@ public class H2DatabaseTest extends BriarTestCase {
Database<Connection> db = open(false);
Connection txn = db.startTransaction();
// Add a contact and subscribe to the groups
// Add a contact and the groups
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
for (Group g : groups) db.addGroup(txn, g);
@@ -951,7 +951,7 @@ public class H2DatabaseTest extends BriarTestCase {
db.addLocalAuthor(txn, localAuthor);
assertEquals(contactId, db.addContact(txn, author, localAuthorId));
// Subscribe to a group and make it visible to the contact
// Add a group and make it visible to the contact
db.addGroup(txn, group);
db.addVisibility(txn, contactId, groupId);