mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-19 14:19:53 +01:00
Addressing second round of review issues
This commit is contained in:
@@ -34,7 +34,7 @@ import static android.widget.Toast.LENGTH_SHORT;
|
|||||||
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
import static org.briarproject.api.forum.ForumConstants.MAX_FORUM_POST_BODY_LENGTH;
|
||||||
|
|
||||||
public class ForumActivity extends
|
public class ForumActivity extends
|
||||||
ThreadListActivity<Forum, ForumEntry, ForumPostHeader, NestedForumAdapter> {
|
ThreadListActivity<Forum, ForumItem, ForumPostHeader, NestedForumAdapter> {
|
||||||
|
|
||||||
private static final int REQUEST_FORUM_SHARED = 3;
|
private static final int REQUEST_FORUM_SHARED = 3;
|
||||||
|
|
||||||
@@ -47,7 +47,7 @@ public class ForumActivity extends
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ThreadListController<Forum, ForumEntry, ForumPostHeader> getController() {
|
protected ThreadListController<Forum, ForumItem, ForumPostHeader> getController() {
|
||||||
return forumController;
|
return forumController;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
package org.briarproject.android.forum;
|
package org.briarproject.android.forum;
|
||||||
|
|
||||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
|
||||||
import org.briarproject.android.threaded.ThreadListController;
|
import org.briarproject.android.threaded.ThreadListController;
|
||||||
import org.briarproject.api.db.DbException;
|
|
||||||
import org.briarproject.api.forum.Forum;
|
import org.briarproject.api.forum.Forum;
|
||||||
import org.briarproject.api.forum.ForumPostHeader;
|
import org.briarproject.api.forum.ForumPostHeader;
|
||||||
|
|
||||||
public interface ForumController
|
public interface ForumController
|
||||||
extends ThreadListController<Forum, ForumEntry, ForumPostHeader> {
|
extends ThreadListController<Forum, ForumItem, ForumPostHeader> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.support.annotation.Nullable;
|
|||||||
|
|
||||||
import org.briarproject.android.api.AndroidNotificationManager;
|
import org.briarproject.android.api.AndroidNotificationManager;
|
||||||
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.crypto.CryptoExecutor;
|
import org.briarproject.api.crypto.CryptoExecutor;
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
@@ -14,20 +15,20 @@ import org.briarproject.api.forum.Forum;
|
|||||||
import org.briarproject.api.forum.ForumManager;
|
import org.briarproject.api.forum.ForumManager;
|
||||||
import org.briarproject.api.forum.ForumPost;
|
import org.briarproject.api.forum.ForumPost;
|
||||||
import org.briarproject.api.forum.ForumPostHeader;
|
import org.briarproject.api.forum.ForumPostHeader;
|
||||||
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
public class ForumControllerImpl
|
public class ForumControllerImpl
|
||||||
extends ThreadListControllerImpl<Forum, ForumEntry, ForumPostHeader, ForumPost>
|
extends ThreadListControllerImpl<Forum, ForumItem, ForumPostHeader, ForumPost>
|
||||||
implements ForumController {
|
implements ForumController {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
@@ -37,12 +38,12 @@ public class ForumControllerImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ForumControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
ForumControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager, IdentityManager identityManager,
|
||||||
@CryptoExecutor Executor cryptoExecutor,
|
@CryptoExecutor Executor cryptoExecutor,
|
||||||
ForumManager forumManager, EventBus eventBus,
|
ForumManager forumManager, EventBus eventBus,
|
||||||
AndroidNotificationManager notificationManager) {
|
AndroidNotificationManager notificationManager) {
|
||||||
super(dbExecutor, lifecycleManager, cryptoExecutor, eventBus,
|
super(dbExecutor, lifecycleManager, identityManager, cryptoExecutor,
|
||||||
notificationManager);
|
eventBus, notificationManager);
|
||||||
this.forumManager = forumManager;
|
this.forumManager = forumManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,7 +73,7 @@ public class ForumControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Forum loadGroupItem() throws DbException {
|
protected Forum loadNamedGroup() throws DbException {
|
||||||
return forumManager.getForum(getGroupId());
|
return forumManager.getForum(getGroupId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,18 +83,8 @@ public class ForumControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<MessageId, String> loadBodies(
|
protected String loadMessageBody(MessageId id) throws DbException {
|
||||||
Collection<ForumPostHeader> headers)
|
return StringUtils.fromUtf8(forumManager.getPostBody(id));
|
||||||
throws DbException {
|
|
||||||
Map<MessageId, String> bodies = new HashMap<>();
|
|
||||||
for (ForumPostHeader header : headers) {
|
|
||||||
if (!bodyCache.containsKey(header.getId())) {
|
|
||||||
String body = StringUtils
|
|
||||||
.fromUtf8(forumManager.getPostBody(header.getId()));
|
|
||||||
bodies.put(header.getId(), body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bodies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -102,9 +93,17 @@ public class ForumControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ForumPost createLocalMessage(String body,
|
protected long getLatestTimestamp() throws DbException {
|
||||||
@Nullable MessageId parentId) throws DbException {
|
GroupCount count = forumManager.getGroupCount(getGroupId());
|
||||||
return forumManager.createLocalPost(getGroupId(), body, parentId);
|
return count.getLatestMsgTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ForumPost createLocalMessage(String body, long timestamp,
|
||||||
|
@Nullable MessageId parentId, LocalAuthor author) {
|
||||||
|
return forumManager
|
||||||
|
.createLocalPost(getGroupId(), body, timestamp, parentId,
|
||||||
|
author);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -114,13 +113,13 @@ public class ForumControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteGroupItem(Forum forum) throws DbException {
|
protected void deleteNamedGroup(Forum forum) throws DbException {
|
||||||
forumManager.removeForum(forum);
|
forumManager.removeForum(forum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ForumEntry buildItem(ForumPostHeader header, String body) {
|
protected ForumItem buildItem(ForumPostHeader header, String body) {
|
||||||
return new ForumEntry(header, body);
|
return new ForumItem(header, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,17 @@ import org.briarproject.api.identity.Author;
|
|||||||
import org.briarproject.api.identity.Author.Status;
|
import org.briarproject.api.identity.Author.Status;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
/* This class is not thread safe */
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
public class ForumEntry extends ThreadItem {
|
|
||||||
|
|
||||||
ForumEntry(ForumPostHeader h, String text) {
|
@NotThreadSafe
|
||||||
super(h.getId(), h.getParentId(), text, h.getTimestamp(), h.getAuthor(),
|
public class ForumItem extends ThreadItem {
|
||||||
|
|
||||||
|
ForumItem(ForumPostHeader h, String body) {
|
||||||
|
super(h.getId(), h.getParentId(), body, h.getTimestamp(), h.getAuthor(),
|
||||||
h.getAuthorStatus(), h.isRead());
|
h.getAuthorStatus(), h.isRead());
|
||||||
}
|
}
|
||||||
|
|
||||||
public ForumEntry(MessageId messageId, MessageId parentId, String text,
|
public ForumItem(MessageId messageId, MessageId parentId, String text,
|
||||||
long timestamp, Author author, Status status) {
|
long timestamp, Author author, Status status) {
|
||||||
super(messageId, parentId, text, timestamp, author, status, true);
|
super(messageId, parentId, text, timestamp, author, status, true);
|
||||||
}
|
}
|
||||||
@@ -10,9 +10,9 @@ import org.briarproject.R;
|
|||||||
import org.briarproject.android.threaded.ThreadItemAdapter;
|
import org.briarproject.android.threaded.ThreadItemAdapter;
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
public class NestedForumAdapter extends ThreadItemAdapter<ForumEntry> {
|
public class NestedForumAdapter extends ThreadItemAdapter<ForumItem> {
|
||||||
|
|
||||||
public NestedForumAdapter(ThreadItemListener<ForumEntry> listener,
|
public NestedForumAdapter(ThreadItemListener<ForumItem> listener,
|
||||||
LinearLayoutManager layoutManager) {
|
LinearLayoutManager layoutManager) {
|
||||||
super(listener, layoutManager);
|
super(listener, layoutManager);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import android.view.View;
|
|||||||
|
|
||||||
import org.briarproject.android.threaded.ThreadItemViewHolder;
|
import org.briarproject.android.threaded.ThreadItemViewHolder;
|
||||||
|
|
||||||
public class NestedForumHolder extends ThreadItemViewHolder<ForumEntry> {
|
public class NestedForumHolder extends ThreadItemViewHolder<ForumItem> {
|
||||||
|
|
||||||
public NestedForumHolder(View v) {
|
public NestedForumHolder(View v) {
|
||||||
super(v);
|
super(v);
|
||||||
|
|||||||
@@ -4,12 +4,15 @@ import android.support.annotation.Nullable;
|
|||||||
|
|
||||||
import org.briarproject.android.api.AndroidNotificationManager;
|
import org.briarproject.android.api.AndroidNotificationManager;
|
||||||
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
import org.briarproject.android.threaded.ThreadListControllerImpl;
|
||||||
|
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||||
import org.briarproject.api.crypto.CryptoExecutor;
|
import org.briarproject.api.crypto.CryptoExecutor;
|
||||||
import org.briarproject.api.db.DatabaseExecutor;
|
import org.briarproject.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.event.Event;
|
import org.briarproject.api.event.Event;
|
||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.api.event.GroupMessageAddedEvent;
|
import org.briarproject.api.event.GroupMessageAddedEvent;
|
||||||
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.privategroup.GroupMessage;
|
import org.briarproject.api.privategroup.GroupMessage;
|
||||||
import org.briarproject.api.privategroup.GroupMessageHeader;
|
import org.briarproject.api.privategroup.GroupMessageHeader;
|
||||||
@@ -18,8 +21,6 @@ import org.briarproject.api.privategroup.PrivateGroupManager;
|
|||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -36,19 +37,19 @@ public class GroupControllerImpl
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
GroupControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
GroupControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager, IdentityManager identityManager,
|
||||||
@CryptoExecutor Executor cryptoExecutor,
|
@CryptoExecutor Executor cryptoExecutor,
|
||||||
PrivateGroupManager privateGroupManager, EventBus eventBus,
|
PrivateGroupManager privateGroupManager, EventBus eventBus,
|
||||||
AndroidNotificationManager notificationManager) {
|
AndroidNotificationManager notificationManager) {
|
||||||
super(dbExecutor, lifecycleManager, cryptoExecutor, eventBus,
|
super(dbExecutor, lifecycleManager, identityManager, cryptoExecutor,
|
||||||
notificationManager);
|
eventBus, notificationManager);
|
||||||
this.privateGroupManager = privateGroupManager;
|
this.privateGroupManager = privateGroupManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResume() {
|
public void onActivityResume() {
|
||||||
super.onActivityResume();
|
super.onActivityResume();
|
||||||
notificationManager.clearForumPostNotification(getGroupId());
|
// TODO: Add new notification manager methods for private groups
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -56,7 +57,7 @@ public class GroupControllerImpl
|
|||||||
super.eventOccurred(e);
|
super.eventOccurred(e);
|
||||||
|
|
||||||
if (e instanceof GroupMessageAddedEvent) {
|
if (e instanceof GroupMessageAddedEvent) {
|
||||||
final GroupMessageAddedEvent gmae = (GroupMessageAddedEvent) e;
|
GroupMessageAddedEvent gmae = (GroupMessageAddedEvent) e;
|
||||||
if (!gmae.isLocal() && gmae.getGroupId().equals(getGroupId())) {
|
if (!gmae.isLocal() && gmae.getGroupId().equals(getGroupId())) {
|
||||||
LOG.info("Group message received, adding...");
|
LOG.info("Group message received, adding...");
|
||||||
final GroupMessageHeader h = gmae.getHeader();
|
final GroupMessageHeader h = gmae.getHeader();
|
||||||
@@ -71,7 +72,7 @@ public class GroupControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PrivateGroup loadGroupItem() throws DbException {
|
protected PrivateGroup loadNamedGroup() throws DbException {
|
||||||
return privateGroupManager.getPrivateGroup(getGroupId());
|
return privateGroupManager.getPrivateGroup(getGroupId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,18 +82,8 @@ public class GroupControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Map<MessageId, String> loadBodies(
|
protected String loadMessageBody(MessageId id) throws DbException {
|
||||||
Collection<GroupMessageHeader> headers)
|
return privateGroupManager.getMessageBody(id);
|
||||||
throws DbException {
|
|
||||||
Map<MessageId, String> bodies = new HashMap<>();
|
|
||||||
for (GroupMessageHeader header : headers) {
|
|
||||||
if (!bodyCache.containsKey(header.getId())) {
|
|
||||||
String body =
|
|
||||||
privateGroupManager.getMessageBody(header.getId());
|
|
||||||
bodies.put(header.getId(), body);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bodies;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,10 +92,17 @@ public class GroupControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GroupMessage createLocalMessage(String body,
|
protected long getLatestTimestamp() throws DbException {
|
||||||
@Nullable MessageId parentId) throws DbException {
|
GroupCount count = privateGroupManager.getGroupCount(getGroupId());
|
||||||
|
return count.getLatestMsgTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GroupMessage createLocalMessage(String body, long timestamp,
|
||||||
|
@Nullable MessageId parentId, LocalAuthor author) {
|
||||||
return privateGroupManager
|
return privateGroupManager
|
||||||
.createLocalMessage(getGroupId(), body, parentId);
|
.createLocalMessage(getGroupId(), body, timestamp, parentId,
|
||||||
|
author);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -114,7 +112,7 @@ public class GroupControllerImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void deleteGroupItem(PrivateGroup group) throws DbException {
|
protected void deleteNamedGroup(PrivateGroup group) throws DbException {
|
||||||
privateGroupManager.removePrivateGroup(group.getId());
|
privateGroupManager.removePrivateGroup(group.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ class GroupListAdapter extends BriarAdapter<GroupItem, GroupViewHolder> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(GroupViewHolder ui, int position) {
|
public void onBindViewHolder(GroupViewHolder ui, int position) {
|
||||||
ui.bindView(ctx, getItemAt(position), listener);
|
ui.bindView(ctx, items.get(position), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public class GroupListControllerImpl extends DbControllerImpl
|
|||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"GroupListListener needs to be attached");
|
"GroupListListener needs to be attached");
|
||||||
eventBus.addListener(this);
|
eventBus.addListener(this);
|
||||||
|
// TODO: Add new notification manager methods for private groups
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package org.briarproject.android.privategroup.list;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v4.app.ActivityOptionsCompat;
|
import android.support.v4.app.ActivityOptionsCompat;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import android.support.v7.widget.RecyclerView;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -51,7 +50,7 @@ class GroupViewHolder extends RecyclerView.ViewHolder {
|
|||||||
remove = (Button) v.findViewById(R.id.removeButton);
|
remove = (Button) v.findViewById(R.id.removeButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void bindView(final Context ctx, @Nullable final GroupItem group,
|
void bindView(final Context ctx, final GroupItem group,
|
||||||
@NotNull final OnGroupRemoveClickListener listener) {
|
@NotNull final OnGroupRemoveClickListener listener) {
|
||||||
if (group == null) return;
|
if (group == null) return;
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import android.support.v7.widget.RecyclerView;
|
|||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -56,7 +57,7 @@ public abstract class ThreadItemAdapter<I extends ThreadItem>
|
|||||||
return replyItem;
|
return replyItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setItems(List<I> items) {
|
public void setItems(Collection<I> items) {
|
||||||
this.items.clear();
|
this.items.clear();
|
||||||
this.items.addAll(items);
|
this.items.addAll(items);
|
||||||
notifyDataSetChanged();
|
notifyDataSetChanged();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ public abstract class ThreadItemViewHolder<I extends ThreadItem>
|
|||||||
|
|
||||||
// TODO improve encapsulation, so we don't need to pass the adapter here
|
// TODO improve encapsulation, so we don't need to pass the adapter here
|
||||||
public void bind(final ThreadItemAdapter<I> adapter,
|
public void bind(final ThreadItemAdapter<I> adapter,
|
||||||
final ThreadItemListener listener, final I item, int pos) {
|
final ThreadItemListener<I> listener, final I item, int pos) {
|
||||||
|
|
||||||
textView.setText(StringUtils.trim(item.getText()));
|
textView.setText(StringUtils.trim(item.getText()));
|
||||||
|
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ import org.briarproject.api.clients.PostHeader;
|
|||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
|
import org.briarproject.util.StringUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static android.support.design.widget.Snackbar.make;
|
import static android.support.design.widget.Snackbar.make;
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
@@ -75,7 +74,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
|||||||
list.setAdapter(adapter);
|
list.setAdapter(adapter);
|
||||||
|
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
replyId = new MessageId(state.getByteArray(KEY_REPLY_ID));
|
byte[] replyIdBytes = state.getByteArray(KEY_REPLY_ID);
|
||||||
|
if(replyIdBytes != null) replyId = new MessageId(replyIdBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadItems();
|
loadItems();
|
||||||
@@ -110,9 +110,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
|||||||
new UiResultExceptionHandler<Collection<I>, DbException>(
|
new UiResultExceptionHandler<Collection<I>, DbException>(
|
||||||
this) {
|
this) {
|
||||||
@Override
|
@Override
|
||||||
public void onResultUi(Collection<I> result) {
|
public void onResultUi(Collection<I> items) {
|
||||||
// FIXME What's the benefit of copying the collection?
|
|
||||||
List<I> items = new ArrayList<>(result);
|
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
list.showData();
|
list.showData();
|
||||||
} else {
|
} else {
|
||||||
@@ -225,7 +223,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
|||||||
public void onSendClick(String text) {
|
public void onSendClick(String text) {
|
||||||
if (text.trim().length() == 0)
|
if (text.trim().length() == 0)
|
||||||
return;
|
return;
|
||||||
if (text.length() > getMaxBodyLength()) {
|
if (StringUtils.isTooLong(text, getMaxBodyLength())) {
|
||||||
displaySnackbarShort(R.string.text_too_long);
|
displaySnackbarShort(R.string.text_too_long);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -243,12 +241,8 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (replyItem == null) {
|
getController().createAndStoreMessage(text,
|
||||||
// root post
|
replyItem != null ? replyItem.getId() : null, handler);
|
||||||
getController().send(text, handler);
|
|
||||||
} else {
|
|
||||||
getController().send(text, replyItem.getId(), handler);
|
|
||||||
}
|
|
||||||
textInput.hideSoftKeyboard();
|
textInput.hideSoftKeyboard();
|
||||||
textInput.setVisibility(GONE);
|
textInput.setVisibility(GONE);
|
||||||
adapter.setReplyItem(null);
|
adapter.setReplyItem(null);
|
||||||
@@ -268,6 +262,7 @@ public abstract class ThreadListActivity<G extends NamedGroup, I extends ThreadI
|
|||||||
@Override
|
@Override
|
||||||
public void onExceptionUi(DbException exception) {
|
public void onExceptionUi(DbException exception) {
|
||||||
// TODO add proper exception handling
|
// TODO add proper exception handling
|
||||||
|
finish();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ public interface ThreadListController<G extends NamedGroup, I extends ThreadItem
|
|||||||
|
|
||||||
void markItemsRead(Collection<I> items);
|
void markItemsRead(Collection<I> items);
|
||||||
|
|
||||||
void send(String body, ResultExceptionHandler<I, DbException> handler);
|
void createAndStoreMessage(String body, @Nullable MessageId parentId,
|
||||||
|
|
||||||
void send(String body, @Nullable MessageId parentId,
|
|
||||||
ResultExceptionHandler<I, DbException> handler);
|
ResultExceptionHandler<I, DbException> handler);
|
||||||
|
|
||||||
void deleteNamedGroup(ResultExceptionHandler<Void, DbException> handler);
|
void deleteNamedGroup(ResultExceptionHandler<Void, DbException> handler);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import org.briarproject.api.event.Event;
|
|||||||
import org.briarproject.api.event.EventBus;
|
import org.briarproject.api.event.EventBus;
|
||||||
import org.briarproject.api.event.EventListener;
|
import org.briarproject.api.event.EventListener;
|
||||||
import org.briarproject.api.event.GroupRemovedEvent;
|
import org.briarproject.api.event.GroupRemovedEvent;
|
||||||
|
import org.briarproject.api.identity.IdentityManager;
|
||||||
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.lifecycle.LifecycleManager;
|
import org.briarproject.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
@@ -40,11 +42,12 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(ThreadListControllerImpl.class.getName());
|
Logger.getLogger(ThreadListControllerImpl.class.getName());
|
||||||
|
|
||||||
protected final Executor cryptoExecutor;
|
private final IdentityManager identityManager;
|
||||||
|
private final Executor cryptoExecutor;
|
||||||
protected final AndroidNotificationManager notificationManager;
|
protected final AndroidNotificationManager notificationManager;
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
|
|
||||||
protected final Map<MessageId, String> bodyCache =
|
private final Map<MessageId, String> bodyCache =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private volatile GroupId groupId;
|
private volatile GroupId groupId;
|
||||||
@@ -52,10 +55,11 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
protected ThreadListListener<H> listener;
|
protected ThreadListListener<H> listener;
|
||||||
|
|
||||||
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
protected ThreadListControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||||
LifecycleManager lifecycleManager,
|
LifecycleManager lifecycleManager, IdentityManager identityManager,
|
||||||
@CryptoExecutor Executor cryptoExecutor, EventBus eventBus,
|
@CryptoExecutor Executor cryptoExecutor, EventBus eventBus,
|
||||||
AndroidNotificationManager notificationManager) {
|
AndroidNotificationManager notificationManager) {
|
||||||
super(dbExecutor, lifecycleManager);
|
super(dbExecutor, lifecycleManager);
|
||||||
|
this.identityManager = identityManager;
|
||||||
this.cryptoExecutor = cryptoExecutor;
|
this.cryptoExecutor = cryptoExecutor;
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.notificationManager = notificationManager;
|
this.notificationManager = notificationManager;
|
||||||
@@ -76,15 +80,14 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
@CallSuper
|
@CallSuper
|
||||||
@Override
|
@Override
|
||||||
public void onActivityResume() {
|
public void onActivityResume() {
|
||||||
checkGroupId();
|
notificationManager.blockNotification(getGroupId());
|
||||||
notificationManager.blockNotification(groupId);
|
|
||||||
eventBus.addListener(this);
|
eventBus.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@CallSuper
|
@CallSuper
|
||||||
@Override
|
@Override
|
||||||
public void onActivityPause() {
|
public void onActivityPause() {
|
||||||
notificationManager.unblockNotification(groupId);
|
notificationManager.unblockNotification(getGroupId());
|
||||||
eventBus.removeListener(this);
|
eventBus.removeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,7 +100,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
public void eventOccurred(Event e) {
|
public void eventOccurred(Event e) {
|
||||||
if (e instanceof GroupRemovedEvent) {
|
if (e instanceof GroupRemovedEvent) {
|
||||||
GroupRemovedEvent s = (GroupRemovedEvent) e;
|
GroupRemovedEvent s = (GroupRemovedEvent) e;
|
||||||
if (s.getGroup().getId().equals(groupId)) {
|
if (s.getGroup().getId().equals(getGroupId())) {
|
||||||
LOG.info("Group removed");
|
LOG.info("Group removed");
|
||||||
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
listener.runOnUiThreadUnlessDestroyed(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
@@ -118,7 +121,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
G groupItem = loadGroupItem();
|
G groupItem = loadNamedGroup();
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info(
|
LOG.info(
|
||||||
@@ -134,7 +137,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
protected abstract G loadGroupItem() throws DbException;
|
protected abstract G loadNamedGroup() throws DbException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadItems(
|
public void loadItems(
|
||||||
@@ -152,10 +155,14 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Loading headers took " + duration + " ms");
|
LOG.info("Loading headers took " + duration + " ms");
|
||||||
|
|
||||||
// Load bodies
|
// Load bodies into cache
|
||||||
now = System.currentTimeMillis();
|
now = System.currentTimeMillis();
|
||||||
Map<MessageId, String> bodies = loadBodies(headers);
|
for (H header : headers) {
|
||||||
bodyCache.putAll(bodies);
|
if (!bodyCache.containsKey(header.getId())) {
|
||||||
|
bodyCache.put(header.getId(),
|
||||||
|
loadMessageBody(header.getId()));
|
||||||
|
}
|
||||||
|
}
|
||||||
duration = System.currentTimeMillis() - now;
|
duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Loading bodies took " + duration + " ms");
|
LOG.info("Loading bodies took " + duration + " ms");
|
||||||
@@ -175,8 +182,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
protected abstract Collection<H> loadHeaders() throws DbException;
|
protected abstract Collection<H> loadHeaders() throws DbException;
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
protected abstract Map<MessageId, String> loadBodies(Collection<H> headers)
|
protected abstract String loadMessageBody(MessageId id) throws DbException;
|
||||||
throws DbException;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void loadItem(final H header,
|
public void loadItem(final H header,
|
||||||
@@ -186,9 +192,13 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
public void run() {
|
public void run() {
|
||||||
LOG.info("Loading item...");
|
LOG.info("Loading item...");
|
||||||
try {
|
try {
|
||||||
String body = loadBodies(Collections.singletonList(header))
|
String body;
|
||||||
.get(header.getId());
|
if (!bodyCache.containsKey(header.getId())) {
|
||||||
bodyCache.put(header.getId(), body);
|
body = loadMessageBody(header.getId());
|
||||||
|
bodyCache.put(header.getId(), body);
|
||||||
|
} else {
|
||||||
|
body = bodyCache.get(header.getId());
|
||||||
|
}
|
||||||
I item = buildItem(header, body);
|
I item = buildItem(header, body);
|
||||||
handler.onResult(item);
|
handler.onResult(item);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
@@ -230,21 +240,19 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
protected abstract void markRead(MessageId id) throws DbException;
|
protected abstract void markRead(MessageId id) throws DbException;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send(String body,
|
public void createAndStoreMessage(final String body,
|
||||||
ResultExceptionHandler<I, DbException> resultHandler) {
|
@Nullable final MessageId parentId,
|
||||||
send(body, null, resultHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(final String body, @Nullable final MessageId parentId,
|
|
||||||
final ResultExceptionHandler<I, DbException> handler) {
|
final ResultExceptionHandler<I, DbException> handler) {
|
||||||
cryptoExecutor.execute(new Runnable() {
|
runOnDbThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
LOG.info("Creating message...");
|
|
||||||
try {
|
try {
|
||||||
M msg = createLocalMessage(body, parentId);
|
LocalAuthor author = identityManager.getLocalAuthor();
|
||||||
storePost(msg, body, handler);
|
long timestamp = getLatestTimestamp();
|
||||||
|
timestamp =
|
||||||
|
Math.max(timestamp, System.currentTimeMillis());
|
||||||
|
createMessage(body, timestamp, parentId, author,
|
||||||
|
handler);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
if (LOG.isLoggable(WARNING))
|
if (LOG.isLoggable(WARNING))
|
||||||
LOG.log(WARNING, e.toString(), e);
|
LOG.log(WARNING, e.toString(), e);
|
||||||
@@ -255,8 +263,24 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
protected abstract M createLocalMessage(String body,
|
protected abstract long getLatestTimestamp() throws DbException;
|
||||||
@Nullable MessageId parentId) throws DbException;
|
|
||||||
|
private void createMessage(final String body, final long timestamp,
|
||||||
|
final @Nullable MessageId parentId, final LocalAuthor author,
|
||||||
|
final ResultExceptionHandler<I, DbException> handler) {
|
||||||
|
cryptoExecutor.execute(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
LOG.info("Creating message...");
|
||||||
|
M msg = createLocalMessage(body, timestamp, parentId, author);
|
||||||
|
storePost(msg, body, handler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@CryptoExecutor
|
||||||
|
protected abstract M createLocalMessage(String body, long timestamp,
|
||||||
|
@Nullable MessageId parentId, LocalAuthor author);
|
||||||
|
|
||||||
private void storePost(final M msg, final String body,
|
private void storePost(final M msg, final String body,
|
||||||
final ResultExceptionHandler<I, DbException> resultHandler) {
|
final ResultExceptionHandler<I, DbException> resultHandler) {
|
||||||
@@ -292,8 +316,8 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
G groupItem = loadGroupItem();
|
G groupItem = loadNamedGroup();
|
||||||
deleteGroupItem(groupItem);
|
deleteNamedGroup(groupItem);
|
||||||
long duration = System.currentTimeMillis() - now;
|
long duration = System.currentTimeMillis() - now;
|
||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Removing group took " + duration + " ms");
|
LOG.info("Removing group took " + duration + " ms");
|
||||||
@@ -309,7 +333,7 @@ public abstract class ThreadListControllerImpl<G extends NamedGroup, I extends T
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
protected abstract void deleteGroupItem(G groupItem) throws DbException;
|
protected abstract void deleteNamedGroup(G groupItem) throws DbException;
|
||||||
|
|
||||||
private List<I> buildItems(Collection<H> headers) {
|
private List<I> buildItems(Collection<H> headers) {
|
||||||
List<I> entries = new ArrayList<>();
|
List<I> entries = new ArrayList<>();
|
||||||
|
|||||||
@@ -11,14 +11,12 @@ import org.briarproject.android.controller.handler.UiResultExceptionHandler;
|
|||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.identity.Author;
|
import org.briarproject.api.identity.Author;
|
||||||
import org.briarproject.api.identity.AuthorId;
|
import org.briarproject.api.identity.AuthorId;
|
||||||
import org.briarproject.api.sync.GroupId;
|
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.Captor;
|
import org.mockito.Captor;
|
||||||
import org.mockito.Mockito;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricGradleTestRunner;
|
import org.robolectric.RobolectricGradleTestRunner;
|
||||||
@@ -82,7 +80,7 @@ public class ForumActivityTest {
|
|||||||
|
|
||||||
private TestForumActivity forumActivity;
|
private TestForumActivity forumActivity;
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<UiResultExceptionHandler<Collection<ForumEntry>, DbException>>
|
private ArgumentCaptor<UiResultExceptionHandler<Collection<ForumItem>, DbException>>
|
||||||
rc;
|
rc;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
@@ -94,14 +92,14 @@ public class ForumActivityTest {
|
|||||||
.withIntent(intent).create().resume().get();
|
.withIntent(intent).create().resume().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ForumEntry> getDummyData() {
|
private List<ForumItem> getDummyData() {
|
||||||
ForumEntry[] forumEntries = new ForumEntry[6];
|
ForumItem[] forumEntries = new ForumItem[6];
|
||||||
for (int i = 0; i < forumEntries.length; i++) {
|
for (int i = 0; i < forumEntries.length; i++) {
|
||||||
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
AuthorId authorId = new AuthorId(TestUtils.getRandomId());
|
||||||
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
byte[] publicKey = TestUtils.getRandomBytes(MAX_PUBLIC_KEY_LENGTH);
|
||||||
Author author = new Author(authorId, AUTHORS[i], publicKey);
|
Author author = new Author(authorId, AUTHORS[i], publicKey);
|
||||||
forumEntries[i] =
|
forumEntries[i] =
|
||||||
new ForumEntry(AUTHOR_IDS[i], PARENT_AUTHOR_IDS[i],
|
new ForumItem(AUTHOR_IDS[i], PARENT_AUTHOR_IDS[i],
|
||||||
AUTHORS[i], System.currentTimeMillis(), author,
|
AUTHORS[i], System.currentTimeMillis(), author,
|
||||||
UNKNOWN);
|
UNKNOWN);
|
||||||
forumEntries[i].setLevel(LEVELS[i]);
|
forumEntries[i].setLevel(LEVELS[i]);
|
||||||
@@ -112,7 +110,7 @@ public class ForumActivityTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testNestedEntries() {
|
public void testNestedEntries() {
|
||||||
ForumController mc = forumActivity.getController();
|
ForumController mc = forumActivity.getController();
|
||||||
List<ForumEntry> dummyData = getDummyData();
|
List<ForumItem> dummyData = getDummyData();
|
||||||
verify(mc, times(1)).loadItems(rc.capture());
|
verify(mc, times(1)).loadItems(rc.capture());
|
||||||
rc.getValue().onResult(dummyData);
|
rc.getValue().onResult(dummyData);
|
||||||
NestedForumAdapter adapter = forumActivity.getAdapter();
|
NestedForumAdapter adapter = forumActivity.getAdapter();
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ import org.briarproject.api.sharing.Shareable;
|
|||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@ThreadSafe
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class Blog extends BaseGroup implements Shareable {
|
public class Blog extends BaseGroup implements Shareable {
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import org.briarproject.api.sync.Group;
|
|||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@ThreadSafe
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public abstract class BaseGroup {
|
public abstract class BaseGroup {
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import org.briarproject.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@ThreadSafe
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public abstract class NamedGroup extends BaseGroup {
|
public abstract class NamedGroup extends BaseGroup {
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ import org.briarproject.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.api.sharing.Shareable;
|
import org.briarproject.api.sharing.Shareable;
|
||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@ThreadSafe
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class Forum extends NamedGroup implements Shareable {
|
public class Forum extends NamedGroup implements Shareable {
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package org.briarproject.api.forum;
|
package org.briarproject.api.forum;
|
||||||
|
|
||||||
import org.briarproject.api.clients.MessageTracker;
|
import org.briarproject.api.clients.MessageTracker;
|
||||||
|
import org.briarproject.api.crypto.CryptoExecutor;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.sync.ClientId;
|
import org.briarproject.api.sync.ClientId;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
@@ -22,8 +24,9 @@ public interface ForumManager extends MessageTracker {
|
|||||||
void removeForum(Forum f) throws DbException;
|
void removeForum(Forum f) throws DbException;
|
||||||
|
|
||||||
/** Creates a local forum post. */
|
/** Creates a local forum post. */
|
||||||
ForumPost createLocalPost(GroupId groupId, String text,
|
@CryptoExecutor
|
||||||
@Nullable MessageId parentId) throws DbException;
|
ForumPost createLocalPost(GroupId groupId, String body, long timestamp,
|
||||||
|
@Nullable MessageId parentId, LocalAuthor author);
|
||||||
|
|
||||||
/** Stores a local forum post. */
|
/** Stores a local forum post. */
|
||||||
ForumPostHeader addLocalPost(ForumPost p) throws DbException;
|
ForumPostHeader addLocalPost(ForumPost p) throws DbException;
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ import org.briarproject.api.nullsafety.NotNullByDefault;
|
|||||||
import org.briarproject.api.sync.Group;
|
import org.briarproject.api.sync.Group;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.concurrent.ThreadSafe;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
@ThreadSafe
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
public class PrivateGroup extends NamedGroup {
|
public class PrivateGroup extends NamedGroup {
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package org.briarproject.api.privategroup;
|
|||||||
import org.briarproject.api.clients.MessageTracker;
|
import org.briarproject.api.clients.MessageTracker;
|
||||||
import org.briarproject.api.db.DbException;
|
import org.briarproject.api.db.DbException;
|
||||||
import org.briarproject.api.db.Transaction;
|
import org.briarproject.api.db.Transaction;
|
||||||
|
import org.briarproject.api.identity.LocalAuthor;
|
||||||
import org.briarproject.api.sync.ClientId;
|
import org.briarproject.api.sync.ClientId;
|
||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
@@ -21,8 +22,8 @@ public interface PrivateGroupManager extends MessageTracker {
|
|||||||
void removePrivateGroup(GroupId g) throws DbException;
|
void removePrivateGroup(GroupId g) throws DbException;
|
||||||
|
|
||||||
/** Creates a local group message. */
|
/** Creates a local group message. */
|
||||||
GroupMessage createLocalMessage(GroupId groupId, String text,
|
GroupMessage createLocalMessage(GroupId groupId, String body,
|
||||||
@Nullable MessageId parentId) throws DbException;
|
long timestamp, @Nullable MessageId parentId, LocalAuthor author);
|
||||||
|
|
||||||
/** Stores (and sends) a local group message. */
|
/** Stores (and sends) a local group message. */
|
||||||
GroupMessageHeader addLocalMessage(GroupMessage p) throws DbException;
|
GroupMessageHeader addLocalMessage(GroupMessage p) throws DbException;
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ import org.briarproject.api.sync.Group;
|
|||||||
import org.briarproject.api.sync.GroupId;
|
import org.briarproject.api.sync.GroupId;
|
||||||
import org.briarproject.api.sync.Message;
|
import org.briarproject.api.sync.Message;
|
||||||
import org.briarproject.api.sync.MessageId;
|
import org.briarproject.api.sync.MessageId;
|
||||||
import org.briarproject.api.system.Clock;
|
|
||||||
import org.briarproject.clients.BdfIncomingMessageHook;
|
import org.briarproject.clients.BdfIncomingMessageHook;
|
||||||
import org.briarproject.util.StringUtils;
|
import org.briarproject.util.StringUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
@@ -64,20 +63,17 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
|||||||
private final IdentityManager identityManager;
|
private final IdentityManager identityManager;
|
||||||
private final ForumFactory forumFactory;
|
private final ForumFactory forumFactory;
|
||||||
private final ForumPostFactory forumPostFactory;
|
private final ForumPostFactory forumPostFactory;
|
||||||
private final Clock clock;
|
|
||||||
private final List<RemoveForumHook> removeHooks;
|
private final List<RemoveForumHook> removeHooks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ForumManagerImpl(DatabaseComponent db, IdentityManager identityManager,
|
ForumManagerImpl(DatabaseComponent db, IdentityManager identityManager,
|
||||||
ClientHelper clientHelper, MetadataParser metadataParser,
|
ClientHelper clientHelper, MetadataParser metadataParser,
|
||||||
ForumFactory forumFactory, ForumPostFactory forumPostFactory,
|
ForumFactory forumFactory, ForumPostFactory forumPostFactory) {
|
||||||
Clock clock) {
|
|
||||||
super(db, clientHelper, metadataParser);
|
super(db, clientHelper, metadataParser);
|
||||||
|
|
||||||
this.identityManager = identityManager;
|
this.identityManager = identityManager;
|
||||||
this.forumFactory = forumFactory;
|
this.forumFactory = forumFactory;
|
||||||
this.forumPostFactory = forumPostFactory;
|
this.forumPostFactory = forumPostFactory;
|
||||||
this.clock = clock;
|
|
||||||
removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
|
removeHooks = new CopyOnWriteArrayList<RemoveForumHook>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,23 +125,9 @@ class ForumManagerImpl extends BdfIncomingMessageHook implements ForumManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ForumPost createLocalPost(final GroupId groupId,
|
public ForumPost createLocalPost(final GroupId groupId, final String body,
|
||||||
final String body, final @Nullable MessageId parentId)
|
final long timestamp, final @Nullable MessageId parentId,
|
||||||
throws DbException {
|
final LocalAuthor author) {
|
||||||
|
|
||||||
LocalAuthor author;
|
|
||||||
GroupCount count;
|
|
||||||
Transaction txn = db.startTransaction(true);
|
|
||||||
try {
|
|
||||||
author = identityManager.getLocalAuthor(txn);
|
|
||||||
count = getGroupCount(txn, groupId);
|
|
||||||
txn.setComplete();
|
|
||||||
} finally {
|
|
||||||
db.endTransaction(txn);
|
|
||||||
}
|
|
||||||
long timestamp = clock.currentTimeMillis();
|
|
||||||
timestamp = Math.max(timestamp, count.getLatestMsgTime());
|
|
||||||
|
|
||||||
ForumPost p;
|
ForumPost p;
|
||||||
try {
|
try {
|
||||||
p = forumPostFactory
|
p = forumPostFactory
|
||||||
|
|||||||
@@ -77,16 +77,13 @@ public class PrivateGroupManagerImpl extends BdfIncomingMessageHook implements
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupMessage createLocalMessage(GroupId groupId, String body,
|
public GroupMessage createLocalMessage(GroupId groupId, String body,
|
||||||
@Nullable MessageId parentId) throws DbException {
|
long timestamp, @Nullable MessageId parentId, LocalAuthor author) {
|
||||||
|
|
||||||
long timestamp = clock.currentTimeMillis();
|
|
||||||
LocalAuthor author = identityManager.getLocalAuthor();
|
|
||||||
try {
|
try {
|
||||||
return groupMessageFactory
|
return groupMessageFactory
|
||||||
.createGroupMessage(groupId, timestamp, parentId, author,
|
.createGroupMessage(groupId, timestamp, parentId, author,
|
||||||
body);
|
body);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new RuntimeException(e);
|
||||||
} catch (GeneralSecurityException e) {
|
} catch (GeneralSecurityException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,4 +86,11 @@ public class StringUtils {
|
|||||||
public static String trim(String s) {
|
public static String trim(String s) {
|
||||||
return s.trim();
|
return s.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the string is longer than maxLength
|
||||||
|
*/
|
||||||
|
public static boolean isTooLong(String s, int maxLength) {
|
||||||
|
return toUtf8(s).length > maxLength;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user