mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Introduce client layer events for forums
The forum UI depended on sync layer events such as MessageStateChangedEvent. Now, the forum client broadcasts its own high-level event (`ForumPostReceivedEvent`) with the information the UI needs (`ForumPostHeader`). Closes #310
This commit is contained in:
@@ -14,8 +14,9 @@ import java.util.Map;
|
||||
public class MessageTreeImpl<T extends MessageTree.MessageNode>
|
||||
implements MessageTree<T> {
|
||||
|
||||
Map<MessageId, List<T>> nodeMap = new HashMap<MessageId, List<T>>();
|
||||
List<T> roots = new ArrayList<T>();
|
||||
private final Map<MessageId, List<T>> nodeMap = new HashMap<MessageId, List<T>>();
|
||||
private final List<T> roots = new ArrayList<T>();
|
||||
private final List<List<T>> unsortedLists = new ArrayList<List<T>>();
|
||||
|
||||
private Comparator<T> comparator = new Comparator<T>() {
|
||||
@Override
|
||||
@@ -38,26 +39,44 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
|
||||
}
|
||||
// parse the nodes for dependencies
|
||||
for (T node : nodes) {
|
||||
if (node.getParentId() == null) {
|
||||
roots.add(node);
|
||||
}
|
||||
else {
|
||||
// retrieve the parent's children
|
||||
List<T> pChildren = nodeMap.get(node.getParentId());
|
||||
pChildren.add(node);
|
||||
}
|
||||
parseNode(node);
|
||||
}
|
||||
sortAll();
|
||||
sortUnsorted();
|
||||
}
|
||||
|
||||
private void sortAll() {
|
||||
Collections.sort(roots, comparator);
|
||||
// Sort all the sub-lists
|
||||
for (Map.Entry<MessageId, List<T>> entry: nodeMap.entrySet()) {
|
||||
Collections.sort(entry.getValue(), comparator);
|
||||
@Override
|
||||
public void add(T node) {
|
||||
add(Collections.singletonList(node));
|
||||
}
|
||||
|
||||
private void markAsUnsorted(List<T> list) {
|
||||
if (!unsortedLists.contains(list))
|
||||
unsortedLists.add(list);
|
||||
}
|
||||
|
||||
private void parseNode(T node) {
|
||||
if (node.getParentId() == null) {
|
||||
roots.add(node);
|
||||
markAsUnsorted(roots);
|
||||
} else {
|
||||
// retrieve the parent's children
|
||||
List<T> pChildren = nodeMap.get(node.getParentId());
|
||||
pChildren.add(node);
|
||||
markAsUnsorted(pChildren);
|
||||
}
|
||||
}
|
||||
|
||||
private void sortUnsorted() {
|
||||
// leave unsorted if there is no comparator
|
||||
if (comparator != null) {
|
||||
for (List<T> list : unsortedLists) {
|
||||
Collections.sort(list, comparator);
|
||||
}
|
||||
unsortedLists.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void traverse(List<T> list, T node) {
|
||||
list.add(node);
|
||||
for (T child : nodeMap.get(node.getId())) {
|
||||
@@ -65,6 +84,16 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComparator(Comparator<T> comparator) {
|
||||
this.comparator = comparator;
|
||||
// Sort all lists with the new comparator
|
||||
Collections.sort(roots, comparator);
|
||||
for (Map.Entry<MessageId, List<T>> entry: nodeMap.entrySet()) {
|
||||
Collections.sort(entry.getValue(), comparator);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<T> depthFirstOrder() {
|
||||
List<T> orderedList = new ArrayList<T>();
|
||||
@@ -74,9 +103,4 @@ public class MessageTreeImpl<T extends MessageTree.MessageNode>
|
||||
return Collections.unmodifiableList(orderedList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setComparator(Comparator<T> comparator) {
|
||||
this.comparator = comparator;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import org.briarproject.api.FormatException;
|
||||
import org.briarproject.api.clients.ClientHelper;
|
||||
import org.briarproject.api.data.BdfDictionary;
|
||||
import org.briarproject.api.data.BdfList;
|
||||
import org.briarproject.api.data.MetadataParser;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.Transaction;
|
||||
import org.briarproject.api.event.ForumPostReceivedEvent;
|
||||
import org.briarproject.api.forum.Forum;
|
||||
import org.briarproject.api.forum.ForumFactory;
|
||||
import org.briarproject.api.forum.ForumManager;
|
||||
@@ -19,7 +21,9 @@ import org.briarproject.api.identity.IdentityManager;
|
||||
import org.briarproject.api.sync.ClientId;
|
||||
import org.briarproject.api.sync.Group;
|
||||
import org.briarproject.api.sync.GroupId;
|
||||
import org.briarproject.api.sync.Message;
|
||||
import org.briarproject.api.sync.MessageId;
|
||||
import org.briarproject.clients.BdfIncomingMessageHook;
|
||||
import org.briarproject.util.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -44,7 +48,7 @@ import static org.briarproject.api.forum.ForumConstants.KEY_READ;
|
||||
import static org.briarproject.api.forum.ForumConstants.KEY_TIMESTAMP;
|
||||
import static org.briarproject.api.identity.Author.Status.ANONYMOUS;
|
||||
|
||||
class ForumManagerImpl implements ForumManager {
|
||||
class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
||||
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ForumManagerImpl.class.getName());
|
||||
@@ -55,21 +59,31 @@ class ForumManagerImpl implements ForumManager {
|
||||
|
||||
private final DatabaseComponent db;
|
||||
private final IdentityManager identityManager;
|
||||
private final ClientHelper clientHelper;
|
||||
private final ForumFactory forumFactory;
|
||||
private final List<RemoveForumHook> removeHooks;
|
||||
|
||||
@Inject
|
||||
ForumManagerImpl(DatabaseComponent db, IdentityManager identityManager,
|
||||
ClientHelper clientHelper, ForumFactory forumFactory) {
|
||||
ClientHelper clientHelper, MetadataParser metadataParser,
|
||||
ForumFactory forumFactory) {
|
||||
|
||||
super(clientHelper, metadataParser);
|
||||
this.db = db;
|
||||
this.identityManager = identityManager;
|
||||
this.clientHelper = clientHelper;
|
||||
this.forumFactory = forumFactory;
|
||||
removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void incomingMessage(Transaction txn, Message m, BdfList body,
|
||||
BdfDictionary meta) throws DbException, FormatException {
|
||||
|
||||
ForumPostHeader post = getForumPostHeader(txn, m.getId(), meta);
|
||||
ForumPostReceivedEvent event =
|
||||
new ForumPostReceivedEvent(post, m.getGroupId());
|
||||
txn.attach(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientId getClientId() {
|
||||
return CLIENT_ID;
|
||||
@@ -193,25 +207,7 @@ class ForumManagerImpl implements ForumManager {
|
||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||
try {
|
||||
BdfDictionary meta = entry.getValue();
|
||||
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
||||
Author author = null;
|
||||
Status authorStatus = ANONYMOUS;
|
||||
MessageId parentId = null;
|
||||
if (meta.containsKey(KEY_PARENT))
|
||||
parentId = new MessageId(meta.getRaw(KEY_PARENT));
|
||||
BdfDictionary d1 = meta.getDictionary(KEY_AUTHOR, null);
|
||||
if (d1 != null) {
|
||||
AuthorId authorId = new AuthorId(d1.getRaw(KEY_ID));
|
||||
String name = d1.getString(KEY_NAME);
|
||||
byte[] publicKey = d1.getRaw(KEY_PUBLIC_NAME);
|
||||
author = new Author(authorId, name, publicKey);
|
||||
authorStatus =
|
||||
identityManager.getAuthorStatus(author.getId());
|
||||
}
|
||||
String contentType = meta.getString(KEY_CONTENT_TYPE);
|
||||
boolean read = meta.getBoolean(KEY_READ);
|
||||
headers.add(new ForumPostHeader(entry.getKey(), parentId,
|
||||
timestamp, author, authorStatus, contentType, read));
|
||||
headers.add(getForumPostHeader(entry.getKey(), meta));
|
||||
} catch (FormatException e) {
|
||||
throw new DbException(e);
|
||||
}
|
||||
@@ -242,4 +238,39 @@ class ForumManagerImpl implements ForumManager {
|
||||
return new Forum(g, forum.getString(0), forum.getRaw(1));
|
||||
}
|
||||
|
||||
private ForumPostHeader getForumPostHeader(Transaction txn, MessageId id,
|
||||
BdfDictionary meta) throws DbException, FormatException {
|
||||
|
||||
long timestamp = meta.getLong(KEY_TIMESTAMP);
|
||||
Author author = null;
|
||||
Status authorStatus = ANONYMOUS;
|
||||
MessageId parentId = null;
|
||||
if (meta.containsKey(KEY_PARENT))
|
||||
parentId = new MessageId(meta.getRaw(KEY_PARENT));
|
||||
BdfDictionary d1 = meta.getDictionary(KEY_AUTHOR, null);
|
||||
if (d1 != null) {
|
||||
AuthorId authorId = new AuthorId(d1.getRaw(KEY_ID));
|
||||
String name = d1.getString(KEY_NAME);
|
||||
byte[] publicKey = d1.getRaw(KEY_PUBLIC_NAME);
|
||||
author = new Author(authorId, name, publicKey);
|
||||
if (txn == null) {
|
||||
authorStatus = identityManager.getAuthorStatus(author.getId());
|
||||
} else {
|
||||
authorStatus =
|
||||
identityManager.getAuthorStatus(txn, author.getId());
|
||||
}
|
||||
}
|
||||
String contentType = meta.getString(KEY_CONTENT_TYPE);
|
||||
boolean read = meta.getBoolean(KEY_READ);
|
||||
|
||||
return new ForumPostHeader(id, parentId, timestamp, author,
|
||||
authorStatus, contentType, read);
|
||||
}
|
||||
|
||||
private ForumPostHeader getForumPostHeader(MessageId id,
|
||||
BdfDictionary meta) throws DbException, FormatException {
|
||||
|
||||
return getForumPostHeader(null, id, meta);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,7 +29,13 @@ public class ForumModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
ForumManager provideForumManager(ForumManagerImpl forumManager) {
|
||||
ForumManager provideForumManager(ForumManagerImpl forumManager,
|
||||
ValidationManager validationManager) {
|
||||
|
||||
validationManager
|
||||
.registerIncomingMessageHook(forumManager.getClientId(),
|
||||
forumManager);
|
||||
|
||||
return forumManager;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user