From 64b596d0f9af182be3533685e223d9319563c176 Mon Sep 17 00:00:00 2001 From: Torsten Grote <t@grobox.de> Date: Thu, 28 Jul 2016 19:10:59 -0300 Subject: [PATCH] Show Responses to Forum Invitations in Private Conversation Closes #472 --- .../ForumSharingIntegrationTest.java | 93 ++++++++++++------- briar-android/res/values/strings.xml | 4 + .../android/contact/ContactListFragment.java | 22 ++++- .../android/contact/ConversationActivity.java | 30 ++++-- .../android/contact/ConversationAdapter.java | 4 +- .../ConversationForumInvitationInItem.java | 4 +- .../ConversationForumInvitationItem.java | 8 +- .../ConversationForumInvitationOutItem.java | 4 +- .../android/contact/ConversationItem.java | 41 +++++++- ...essage.java => BlogInvitationRequest.java} | 5 +- .../api/blogs/BlogSharingManager.java | 4 +- ...ssage.java => ForumInvitationRequest.java} | 7 +- .../api/forum/ForumInvitationResponse.java | 17 ++++ .../api/forum/ForumSharingManager.java | 5 +- .../api/sharing/InvitationMessage.java | 15 +-- .../api/sharing/InvitationRequest.java | 30 ++++++ .../api/sharing/InvitationResponse.java | 22 +++++ .../api/sharing/SharingMessage.java | 1 - .../sharing/BlogSharingManagerImpl.java | 31 ++++--- .../sharing/ForumSharerSessionState.java | 8 +- .../sharing/ForumSharingManagerImpl.java | 33 ++++--- .../briarproject/sharing/SharerEngine.java | 2 +- .../sharing/SharingManagerImpl.java | 60 ++++++++---- 23 files changed, 318 insertions(+), 132 deletions(-) rename briar-api/src/org/briarproject/api/blogs/{BlogInvitationMessage.java => BlogInvitationRequest.java} (76%) rename briar-api/src/org/briarproject/api/forum/{ForumInvitationMessage.java => ForumInvitationRequest.java} (70%) create mode 100644 briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java create mode 100644 briar-api/src/org/briarproject/api/sharing/InvitationRequest.java create mode 100644 briar-api/src/org/briarproject/api/sharing/InvitationResponse.java diff --git a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java index 444f2f4c8d..2221f635b4 100644 --- a/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java +++ b/briar-android-tests/src/test/java/org/briarproject/ForumSharingIntegrationTest.java @@ -25,7 +25,8 @@ import org.briarproject.api.event.ForumInvitationReceivedEvent; import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.event.MessageStateChangedEvent; import org.briarproject.api.forum.Forum; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumPost; import org.briarproject.api.forum.ForumPostFactory; @@ -35,6 +36,7 @@ import org.briarproject.api.identity.AuthorFactory; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.SyncSession; @@ -187,18 +189,29 @@ public class ForumSharingIntegrationTest extends BriarTestCase { assertEquals(1, forumManager1.getForums().size()); // invitee has one invitation message from sharer - List<ForumInvitationMessage> list = + List<InvitationMessage> list = new ArrayList<>(forumSharingManager1 .getInvitationMessages(contactId0)); - assertEquals(1, list.size()); + assertEquals(2, list.size()); // check other things are alright with the forum message - ForumInvitationMessage invitation = list.get(0); - assertFalse(invitation.isAvailable()); - assertEquals(forum0.getName(), invitation.getForumName()); - assertEquals(contactId1, invitation.getContactId()); - assertEquals("Hi!", invitation.getMessage()); - // sharer has own invitation message - assertEquals(1, + for (InvitationMessage m : list) { + if (m instanceof ForumInvitationRequest) { + ForumInvitationRequest invitation = + (ForumInvitationRequest) m; + assertFalse(invitation.isAvailable()); + assertEquals(forum0.getName(), invitation.getForumName()); + assertEquals(contactId1, invitation.getContactId()); + assertEquals("Hi!", invitation.getMessage()); + } else { + ForumInvitationResponse response = + (ForumInvitationResponse) m; + assertEquals(contactId0, response.getContactId()); + assertTrue(response.wasAccepted()); + assertTrue(response.isLocal()); + } + } + // sharer has own invitation message and response + assertEquals(2, forumSharingManager0.getInvitationMessages(contactId1) .size()); // forum can not be shared again @@ -238,19 +251,30 @@ public class ForumSharingIntegrationTest extends BriarTestCase { // forum is no longer available to invitee who declined assertEquals(0, forumSharingManager1.getInvited().size()); - // invitee has one invitation message from sharer - List<ForumInvitationMessage> list = + // invitee has one invitation message from sharer and one response + List<InvitationMessage> list = new ArrayList<>(forumSharingManager1 .getInvitationMessages(contactId0)); - assertEquals(1, list.size()); - // check other things are alright with the forum message - ForumInvitationMessage invitation = list.get(0); - assertFalse(invitation.isAvailable()); - assertEquals(forum0.getName(), invitation.getForumName()); - assertEquals(contactId1, invitation.getContactId()); - assertEquals(null, invitation.getMessage()); - // sharer has own invitation message - assertEquals(1, + assertEquals(2, list.size()); + // check things are alright with the forum message + for (InvitationMessage m : list) { + if (m instanceof ForumInvitationRequest) { + ForumInvitationRequest invitation = + (ForumInvitationRequest) m; + assertFalse(invitation.isAvailable()); + assertEquals(forum0.getName(), invitation.getForumName()); + assertEquals(contactId1, invitation.getContactId()); + assertEquals(null, invitation.getMessage()); + } else { + ForumInvitationResponse response = + (ForumInvitationResponse) m; + assertEquals(contactId0, response.getContactId()); + assertFalse(response.wasAccepted()); + assertTrue(response.isLocal()); + } + } + // sharer has own invitation message and response + assertEquals(2, forumSharingManager0.getInvitationMessages(contactId1) .size()); // forum can be shared again @@ -438,12 +462,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase { listener1.requestReceived = false; // get SessionId from invitation - List<ForumInvitationMessage> list = new ArrayList<>( + List<InvitationMessage> list = new ArrayList<>( forumSharingManager1 .getInvitationMessages(contactId0)); - assertEquals(1, list.size()); - ForumInvitationMessage msg = list.get(0); + assertEquals(2, list.size()); + InvitationMessage msg = list.get(0); SessionId sessionId = msg.getSessionId(); + assertEquals(sessionId, list.get(1).getSessionId()); // get all sorts of stuff needed to send a message DatabaseComponent db = t0.getDatabaseComponent(); @@ -501,6 +526,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase { // forum was added successfully assertEquals(1, forumManager1.getForums().size()); + assertEquals(2, + forumSharingManager0.getInvitationMessages(contactId1) + .size()); // invitee now shares same forum back forumSharingManager1.sendInvitation(forum0.getId(), @@ -512,7 +540,7 @@ public class ForumSharingIntegrationTest extends BriarTestCase { // make sure that no new request was received assertFalse(listener0.requestReceived); - assertEquals(1, + assertEquals(2, forumSharingManager0.getInvitationMessages(contactId1) .size()); } finally { @@ -566,9 +594,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase { eventWaiter.await(TIMEOUT, 1); assertTrue(listener0.responseReceived); - assertEquals(1, forumSharingManager0 + assertEquals(2, forumSharingManager0 .getInvitationMessages(contactId1).size()); - assertEquals(2, forumSharingManager1 + assertEquals(3, forumSharingManager1 .getInvitationMessages(contactId0).size()); } else { eventWaiter.await(TIMEOUT, 1); @@ -579,9 +607,9 @@ public class ForumSharingIntegrationTest extends BriarTestCase { eventWaiter.await(TIMEOUT, 1); assertTrue(listener1.responseReceived); - assertEquals(2, forumSharingManager0 + assertEquals(3, forumSharingManager0 .getInvitationMessages(contactId1).size()); - assertEquals(1, forumSharingManager1 + assertEquals(2, forumSharingManager1 .getInvitationMessages(contactId0).size()); } } finally { @@ -616,12 +644,13 @@ public class ForumSharingIntegrationTest extends BriarTestCase { forumSharingManager0.getSharedWith(forum0.getId()).size()); // remember SessionId from invitation - List<ForumInvitationMessage> list = new ArrayList<>( + List<InvitationMessage> list = new ArrayList<>( forumSharingManager1 .getInvitationMessages(contactId0)); - assertEquals(1, list.size()); - ForumInvitationMessage msg = list.get(0); + assertEquals(2, list.size()); + InvitationMessage msg = list.get(0); SessionId sessionId = msg.getSessionId(); + assertEquals(sessionId, list.get(1).getSessionId()); // contacts now remove each other contactManager0.removeContact(contactId1); diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 3c2084bd75..646f277780 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -222,6 +222,10 @@ <string name="forum_new_message_hint">New Entry</string> <string name="forum_message_reply_hint">New Reply</string> <string name="forum_invitation_already_sharing">Already sharing</string> + <string name="forum_invitation_response_accepted_sent">You accepted the forum invitation from %s.</string> + <string name="forum_invitation_response_declined_sent">You declined the forum invitation from %s.</string> + <string name="forum_invitation_response_accepted_received">%s accepted the forum invitation.</string> + <string name="forum_invitation_response_declined_received">%s declined the forum invitation.</string> <!-- Dialogs --> <string name="dialog_title_lost_password">Lost Password</string> diff --git a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java index e113a9a085..27618e422d 100644 --- a/briar-android/src/org/briarproject/android/contact/ContactListFragment.java +++ b/briar-android/src/org/briarproject/android/contact/ContactListFragment.java @@ -34,10 +34,12 @@ import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; import org.briarproject.api.event.ForumInvitationReceivedEvent; +import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.event.IntroductionRequestReceivedEvent; import org.briarproject.api.event.IntroductionResponseReceivedEvent; import org.briarproject.api.event.PrivateMessageReceivedEvent; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.identity.IdentityManager; import org.briarproject.api.identity.LocalAuthor; @@ -48,6 +50,7 @@ import org.briarproject.api.introduction.IntroductionResponse; import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.plugins.ConnectionRegistry; +import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sync.GroupId; import java.util.ArrayList; @@ -277,6 +280,11 @@ public class ContactListFragment extends BaseFragment implements EventListener { LOG.info("Forum Invitation received, reloading conversation..."); ForumInvitationReceivedEvent m = (ForumInvitationReceivedEvent) e; reloadConversation(m.getContactId()); + } else if (e instanceof ForumInvitationResponseReceivedEvent) { + LOG.info("Forum Invitation Response received, reloading ..."); + ForumInvitationResponseReceivedEvent m = + (ForumInvitationResponseReceivedEvent) e; + reloadConversation(m.getContactId()); } } @@ -394,10 +402,16 @@ public class ContactListFragment extends BaseFragment implements EventListener { LOG.info("Loading introduction messages took " + duration + " ms"); now = System.currentTimeMillis(); - Collection<ForumInvitationMessage> invitations = + Collection<InvitationMessage> invitations = forumSharingManager.getInvitationMessages(id); - for (ForumInvitationMessage i : invitations) { - messages.add(ConversationItem.from(i)); + for (InvitationMessage i : invitations) { + if (i instanceof ForumInvitationRequest) { + ForumInvitationRequest r = (ForumInvitationRequest) i; + messages.add(ConversationItem.from(r)); + } else if (i instanceof ForumInvitationResponse) { + ForumInvitationResponse r = (ForumInvitationResponse) i; + messages.add(ConversationItem.from(getActivity(), "", r)); + } } duration = System.currentTimeMillis() - now; if (LOG.isLoggable(INFO)) diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index c85e84d8c4..a2dad23f42 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -45,12 +45,14 @@ import org.briarproject.api.event.Event; import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventListener; import org.briarproject.api.event.ForumInvitationReceivedEvent; +import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.event.IntroductionRequestReceivedEvent; import org.briarproject.api.event.IntroductionResponseReceivedEvent; import org.briarproject.api.event.MessagesAckedEvent; import org.briarproject.api.event.MessagesSentEvent; import org.briarproject.api.event.PrivateMessageReceivedEvent; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.introduction.IntroductionManager; import org.briarproject.api.introduction.IntroductionMessage; @@ -61,6 +63,7 @@ import org.briarproject.api.messaging.PrivateMessage; import org.briarproject.api.messaging.PrivateMessageFactory; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.api.plugins.ConnectionRegistry; +import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; import org.briarproject.util.StringUtils; @@ -330,7 +333,7 @@ public class ConversationActivity extends BriarActivity Collection<IntroductionMessage> introductions = introductionManager .getIntroductionMessages(contactId); - Collection<ForumInvitationMessage> invitations = + Collection<InvitationMessage> invitations = forumSharingManager .getInvitationMessages(contactId); long duration = System.currentTimeMillis() - now; @@ -349,7 +352,7 @@ public class ConversationActivity extends BriarActivity private void displayMessages(final Collection<PrivateMessageHeader> headers, final Collection<IntroductionMessage> introductions, - final Collection<ForumInvitationMessage> invitations) { + final Collection<InvitationMessage> invitations) { runOnUiThread(new Runnable() { @Override public void run() { @@ -383,9 +386,18 @@ public class ConversationActivity extends BriarActivity } items.add(item); } - for (ForumInvitationMessage i : invitations) { - ConversationItem item = ConversationItem.from(i); - items.add(item); + for (InvitationMessage i : invitations) { + if (i instanceof ForumInvitationRequest) { + ForumInvitationRequest r = + (ForumInvitationRequest) i; + items.add(ConversationItem.from(r)); + } else if (i instanceof ForumInvitationResponse) { + ForumInvitationResponse r = + (ForumInvitationResponse) i; + items.add(ConversationItem + .from(ConversationActivity.this, + contactName, r)); + } } adapter.addAll(items); // Scroll to the bottom @@ -547,6 +559,12 @@ public class ConversationActivity extends BriarActivity if (event.getContactId().equals(contactId)) { loadMessages(); } + } else if (e instanceof ForumInvitationResponseReceivedEvent) { + ForumInvitationResponseReceivedEvent event = + (ForumInvitationResponseReceivedEvent) e; + if (event.getContactId().equals(contactId)) { + loadMessages(); + } } } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java index 2884350ea9..15b9059089 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationAdapter.java @@ -16,7 +16,7 @@ import org.briarproject.R; import org.briarproject.android.forum.ForumInvitationsActivity; import org.briarproject.android.util.AndroidUtils; import org.briarproject.api.clients.SessionId; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; import org.briarproject.api.introduction.IntroductionRequest; import org.briarproject.api.messaging.PrivateMessageHeader; import org.briarproject.util.StringUtils; @@ -278,7 +278,7 @@ class ConversationAdapter extends RecyclerView.Adapter { private void bindInvitation(InvitationHolder ui, final ConversationForumInvitationItem item) { - ForumInvitationMessage fim = item.getForumInvitationMessage(); + ForumInvitationRequest fim = item.getForumInvitationMessage(); String message = fim.getMessage(); if (StringUtils.isNullOrEmpty(message)) { diff --git a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationInItem.java b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationInItem.java index b082fe4d6a..bfa5da5457 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationInItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationInItem.java @@ -1,6 +1,6 @@ package org.briarproject.android.contact; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; // This class is not thread-safe public class ConversationForumInvitationInItem @@ -9,7 +9,7 @@ public class ConversationForumInvitationInItem private boolean read; - public ConversationForumInvitationInItem(ForumInvitationMessage fim) { + public ConversationForumInvitationInItem(ForumInvitationRequest fim) { super(fim); this.read = fim.isRead(); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationItem.java b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationItem.java index eb303d16b5..50c5c64d2c 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationItem.java @@ -1,18 +1,18 @@ package org.briarproject.android.contact; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; abstract class ConversationForumInvitationItem extends ConversationItem { - private final ForumInvitationMessage fim; + private final ForumInvitationRequest fim; - public ConversationForumInvitationItem(ForumInvitationMessage fim) { + public ConversationForumInvitationItem(ForumInvitationRequest fim) { super(fim.getId(), fim.getTimestamp()); this.fim = fim; } - public ForumInvitationMessage getForumInvitationMessage() { + public ForumInvitationRequest getForumInvitationMessage() { return fim; } } diff --git a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationOutItem.java b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationOutItem.java index 202023dda2..5551fa60c5 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationOutItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationForumInvitationOutItem.java @@ -1,6 +1,6 @@ package org.briarproject.android.contact; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; /** * This class is needed and can not be replaced by an ConversationNoticeOutItem, @@ -15,7 +15,7 @@ public class ConversationForumInvitationOutItem private boolean sent, seen; - public ConversationForumInvitationOutItem(ForumInvitationMessage fim) { + public ConversationForumInvitationOutItem(ForumInvitationRequest fim) { super(fim); this.sent = fim.isSent(); this.seen = fim.isSeen(); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationItem.java b/briar-android/src/org/briarproject/android/contact/ConversationItem.java index 7b75cb13a6..18cfbd742a 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationItem.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationItem.java @@ -3,7 +3,8 @@ package org.briarproject.android.contact; import android.content.Context; import org.briarproject.R; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.introduction.IntroductionMessage; import org.briarproject.api.introduction.IntroductionRequest; import org.briarproject.api.introduction.IntroductionResponse; @@ -95,7 +96,7 @@ public abstract class ConversationItem { } } - public static ConversationItem from(ForumInvitationMessage fim) { + public static ConversationItem from(ForumInvitationRequest fim) { if (fim.isLocal()) { return new ConversationForumInvitationOutItem(fim); } else { @@ -103,6 +104,38 @@ public abstract class ConversationItem { } } + public static ConversationItem from(Context ctx, String contactName, + ForumInvitationResponse fir) { + + if (fir.isLocal()) { + String text; + if (fir.wasAccepted()) { + text = ctx.getString( + R.string.forum_invitation_response_accepted_sent, + contactName); + } else { + text = ctx.getString( + R.string.forum_invitation_response_declined_sent, + contactName); + } + return new ConversationNoticeOutItem(fir.getId(), text, + fir.getTimestamp(), fir.isSent(), fir.isSeen()); + } else { + String text; + if (fir.wasAccepted()) { + text = ctx.getString( + R.string.forum_invitation_response_accepted_received, + contactName); + } else { + text = ctx.getString( + R.string.forum_invitation_response_declined_received, + contactName); + } + return new ConversationNoticeInItem(fir.getId(), text, + fir.getTimestamp(), fir.isRead()); + } + } + /** * This method should not be used to get user-facing objects, * Its purpose is to provider data for the contact list. @@ -115,7 +148,7 @@ public abstract class ConversationItem { im.getTimestamp(), im.isRead()); } - protected interface OutgoingItem { + interface OutgoingItem { MessageId getId(); @@ -128,7 +161,7 @@ public abstract class ConversationItem { void setSeen(boolean seen); } - protected interface IncomingItem { + interface IncomingItem { MessageId getId(); diff --git a/briar-api/src/org/briarproject/api/blogs/BlogInvitationMessage.java b/briar-api/src/org/briarproject/api/blogs/BlogInvitationRequest.java similarity index 76% rename from briar-api/src/org/briarproject/api/blogs/BlogInvitationMessage.java rename to briar-api/src/org/briarproject/api/blogs/BlogInvitationRequest.java index 9306da5726..473955960a 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogInvitationMessage.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogInvitationRequest.java @@ -3,13 +3,14 @@ package org.briarproject.api.blogs; import org.briarproject.api.clients.SessionId; import org.briarproject.api.contact.ContactId; import org.briarproject.api.sharing.InvitationMessage; +import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sync.MessageId; -public class BlogInvitationMessage extends InvitationMessage { +public class BlogInvitationRequest extends InvitationRequest { private final String blogTitle; - public BlogInvitationMessage(MessageId id, SessionId sessionId, + public BlogInvitationRequest(MessageId id, SessionId sessionId, ContactId contactId, String blogTitle, String message, boolean available, long time, boolean local, boolean sent, boolean seen, boolean read) { diff --git a/briar-api/src/org/briarproject/api/blogs/BlogSharingManager.java b/briar-api/src/org/briarproject/api/blogs/BlogSharingManager.java index 6fed69e19f..59e06c712f 100644 --- a/briar-api/src/org/briarproject/api/blogs/BlogSharingManager.java +++ b/briar-api/src/org/briarproject/api/blogs/BlogSharingManager.java @@ -10,7 +10,7 @@ import org.briarproject.api.sync.GroupId; import java.util.Collection; public interface BlogSharingManager - extends SharingManager<Blog, BlogInvitationMessage> { + extends SharingManager<Blog, BlogInvitationRequest> { /** * Returns the unique ID of the blog sharing client. @@ -34,7 +34,7 @@ public interface BlogSharingManager * Returns all blogs sharing messages sent by the Contact * identified by contactId. */ - Collection<BlogInvitationMessage> getInvitationMessages( + Collection<BlogInvitationRequest> getInvitationMessages( ContactId contactId) throws DbException; /** diff --git a/briar-api/src/org/briarproject/api/forum/ForumInvitationMessage.java b/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java similarity index 70% rename from briar-api/src/org/briarproject/api/forum/ForumInvitationMessage.java rename to briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java index fd2d6b0d8c..f043ca2011 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumInvitationMessage.java +++ b/briar-api/src/org/briarproject/api/forum/ForumInvitationRequest.java @@ -2,15 +2,14 @@ package org.briarproject.api.forum; import org.briarproject.api.clients.SessionId; import org.briarproject.api.contact.ContactId; -import org.briarproject.api.messaging.BaseMessage; -import org.briarproject.api.sharing.InvitationMessage; +import org.briarproject.api.sharing.InvitationRequest; import org.briarproject.api.sync.MessageId; -public class ForumInvitationMessage extends InvitationMessage { +public class ForumInvitationRequest extends InvitationRequest { private final String forumName; - public ForumInvitationMessage(MessageId id, SessionId sessionId, + public ForumInvitationRequest(MessageId id, SessionId sessionId, ContactId contactId, String forumName, String message, boolean available, long time, boolean local, boolean sent, boolean seen, boolean read) { diff --git a/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java b/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java new file mode 100644 index 0000000000..00a15eac2e --- /dev/null +++ b/briar-api/src/org/briarproject/api/forum/ForumInvitationResponse.java @@ -0,0 +1,17 @@ +package org.briarproject.api.forum; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.sharing.InvitationResponse; +import org.briarproject.api.sync.MessageId; + +public class ForumInvitationResponse extends InvitationResponse { + + public ForumInvitationResponse(MessageId id, SessionId sessionId, + ContactId contactId, boolean accept, long time, boolean local, + boolean sent, boolean seen, boolean read) { + + super(id, sessionId, contactId, accept, time, local, sent, seen, read); + } + +} diff --git a/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java b/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java index 365cf18e75..2ad3228dd9 100644 --- a/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java +++ b/briar-api/src/org/briarproject/api/forum/ForumSharingManager.java @@ -3,13 +3,14 @@ package org.briarproject.api.forum; import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.ContactId; import org.briarproject.api.db.DbException; +import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sharing.SharingManager; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.GroupId; import java.util.Collection; -public interface ForumSharingManager extends SharingManager<Forum, ForumInvitationMessage> { +public interface ForumSharingManager extends SharingManager<Forum, InvitationMessage> { /** Returns the unique ID of the forum sharing client. */ ClientId getClientId(); @@ -31,7 +32,7 @@ public interface ForumSharingManager extends SharingManager<Forum, ForumInvitati * Returns all forum sharing messages sent by the Contact * identified by contactId. */ - Collection<ForumInvitationMessage> getInvitationMessages( + Collection<InvitationMessage> getInvitationMessages( ContactId contactId) throws DbException; /** Returns all forums to which the user has been invited. */ diff --git a/briar-api/src/org/briarproject/api/sharing/InvitationMessage.java b/briar-api/src/org/briarproject/api/sharing/InvitationMessage.java index 4d3c12e261..181a04059e 100644 --- a/briar-api/src/org/briarproject/api/sharing/InvitationMessage.java +++ b/briar-api/src/org/briarproject/api/sharing/InvitationMessage.java @@ -9,19 +9,14 @@ public abstract class InvitationMessage extends BaseMessage { private final SessionId sessionId; private final ContactId contactId; - private final String message; - private final boolean available; public InvitationMessage(MessageId id, SessionId sessionId, - ContactId contactId, String message, - boolean available, long time, boolean local, boolean sent, + ContactId contactId, long time, boolean local, boolean sent, boolean seen, boolean read) { super(id, time, local, read, sent, seen); this.sessionId = sessionId; this.contactId = contactId; - this.message = message; - this.available = available; } public SessionId getSessionId() { @@ -32,12 +27,4 @@ public abstract class InvitationMessage extends BaseMessage { return contactId; } - public String getMessage() { - return message; - } - - public boolean isAvailable() { - return available; - } - } diff --git a/briar-api/src/org/briarproject/api/sharing/InvitationRequest.java b/briar-api/src/org/briarproject/api/sharing/InvitationRequest.java new file mode 100644 index 0000000000..6d5f07d35e --- /dev/null +++ b/briar-api/src/org/briarproject/api/sharing/InvitationRequest.java @@ -0,0 +1,30 @@ +package org.briarproject.api.sharing; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.sync.MessageId; + +public abstract class InvitationRequest extends InvitationMessage { + + private final String message; + private final boolean available; + + public InvitationRequest(MessageId id, SessionId sessionId, + ContactId contactId, String message, + boolean available, long time, boolean local, boolean sent, + boolean seen, boolean read) { + + super(id, sessionId, contactId, time, local, read, sent, seen); + this.message = message; + this.available = available; + } + + public String getMessage() { + return message; + } + + public boolean isAvailable() { + return available; + } + +} diff --git a/briar-api/src/org/briarproject/api/sharing/InvitationResponse.java b/briar-api/src/org/briarproject/api/sharing/InvitationResponse.java new file mode 100644 index 0000000000..cf4d53774e --- /dev/null +++ b/briar-api/src/org/briarproject/api/sharing/InvitationResponse.java @@ -0,0 +1,22 @@ +package org.briarproject.api.sharing; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.sync.MessageId; + +public abstract class InvitationResponse extends InvitationMessage { + + private final boolean accept; + + public InvitationResponse(MessageId id, SessionId sessionId, + ContactId contactId, boolean accept, long time, boolean local, + boolean sent, boolean seen, boolean read) { + + super(id, sessionId, contactId, time, local, read, sent, seen); + this.accept = accept; + } + + public boolean wasAccepted() { + return accept; + } +} diff --git a/briar-api/src/org/briarproject/api/sharing/SharingMessage.java b/briar-api/src/org/briarproject/api/sharing/SharingMessage.java index 2b14cefde4..be0cac328d 100644 --- a/briar-api/src/org/briarproject/api/sharing/SharingMessage.java +++ b/briar-api/src/org/briarproject/api/sharing/SharingMessage.java @@ -23,7 +23,6 @@ public interface SharingMessage { private final SessionId sessionId; BaseMessage(GroupId groupId, SessionId sessionId) { - this.groupId = groupId; this.sessionId = sessionId; } diff --git a/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java index a8bd64b2aa..5632ea9940 100644 --- a/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/BlogSharingManagerImpl.java @@ -3,7 +3,7 @@ package org.briarproject.sharing; import org.briarproject.api.FormatException; import org.briarproject.api.blogs.Blog; import org.briarproject.api.blogs.BlogFactory; -import org.briarproject.api.blogs.BlogInvitationMessage; +import org.briarproject.api.blogs.BlogInvitationRequest; import org.briarproject.api.blogs.BlogManager; import org.briarproject.api.blogs.BlogManager.RemoveBlogHook; import org.briarproject.api.blogs.BlogSharingManager; @@ -40,15 +40,13 @@ import static org.briarproject.api.blogs.BlogConstants.BLOG_PUBLIC_KEY; import static org.briarproject.api.blogs.BlogConstants.BLOG_TITLE; class BlogSharingManagerImpl extends - SharingManagerImpl<Blog, BlogInvitation, BlogInvitationMessage, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent> + SharingManagerImpl<Blog, BlogInvitation, BlogInvitationRequest, BlogInviteeSessionState, BlogSharerSessionState, BlogInvitationReceivedEvent, BlogInvitationResponseReceivedEvent> implements BlogSharingManager, RemoveBlogHook { static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( "bee438b5de0b3a685badc4e49d76e72d" + "21e01c4b569a775112756bdae267a028")); - private final BlogManager blogManager; - private final SFactory sFactory; private final IFactory iFactory; private final ISFactory isFactory; @@ -65,7 +63,6 @@ class BlogSharingManagerImpl extends super(db, messageQueueManager, clientHelper, metadataParser, metadataEncoder, random, privateGroupFactory, clock); - this.blogManager = blogManager; sFactory = new SFactory(authorFactory, blogFactory, blogManager); iFactory = new IFactory(); @@ -81,15 +78,23 @@ class BlogSharingManagerImpl extends } @Override - protected BlogInvitationMessage createInvitationMessage(MessageId id, + protected BlogInvitationRequest createInvitationRequest(MessageId id, BlogInvitation msg, ContactId contactId, boolean available, long time, boolean local, boolean sent, boolean seen, boolean read) { - return new BlogInvitationMessage(id, msg.getSessionId(), contactId, + return new BlogInvitationRequest(id, msg.getSessionId(), contactId, msg.getBlogTitle(), msg.getMessage(), available, time, local, sent, seen, read); } + @Override + protected BlogInvitationRequest createInvitationResponse(MessageId id, + SessionId sessionId, ContactId contactId, boolean accept, long time, + boolean local, boolean sent, boolean seen, boolean read) { + // TODO implement when doing blog sharing + return null; + } + @Override protected ShareableFactory<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState> getSFactory() { return sFactory; @@ -125,7 +130,7 @@ class BlogSharingManagerImpl extends removingShareable(txn, b); } - static class SFactory implements + private static class SFactory implements ShareableFactory<Blog, BlogInvitation, BlogInviteeSessionState, BlogSharerSessionState> { private final AuthorFactory authorFactory; @@ -190,7 +195,7 @@ class BlogSharingManagerImpl extends } } - static class IFactory implements + private static class IFactory implements InvitationFactory<BlogInvitation, BlogSharerSessionState> { @Override public BlogInvitation build(GroupId groupId, BdfDictionary d) @@ -207,7 +212,7 @@ class BlogSharingManagerImpl extends } } - static class ISFactory implements + private static class ISFactory implements InviteeSessionStateFactory<Blog, BlogInviteeSessionState> { @Override public BlogInviteeSessionState build(SessionId sessionId, @@ -235,7 +240,7 @@ class BlogSharingManagerImpl extends } } - static class SSFactory implements + private static class SSFactory implements SharerSessionStateFactory<Blog, BlogSharerSessionState> { @Override public BlogSharerSessionState build(SessionId sessionId, @@ -263,7 +268,7 @@ class BlogSharingManagerImpl extends } } - static class IRFactory implements + private static class IRFactory implements InvitationReceivedEventFactory<BlogInviteeSessionState, BlogInvitationReceivedEvent> { private final SFactory sFactory; @@ -281,7 +286,7 @@ class BlogSharingManagerImpl extends } } - static class IRRFactory implements + private static class IRRFactory implements InvitationResponseReceivedEventFactory<BlogSharerSessionState, BlogInvitationResponseReceivedEvent> { @Override public BlogInvitationResponseReceivedEvent build( diff --git a/briar-core/src/org/briarproject/sharing/ForumSharerSessionState.java b/briar-core/src/org/briarproject/sharing/ForumSharerSessionState.java index cfc0c231c7..4e0fd05049 100644 --- a/briar-core/src/org/briarproject/sharing/ForumSharerSessionState.java +++ b/briar-core/src/org/briarproject/sharing/ForumSharerSessionState.java @@ -9,12 +9,12 @@ import org.briarproject.api.sync.MessageId; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; -public class ForumSharerSessionState extends SharerSessionState { +class ForumSharerSessionState extends SharerSessionState { private final String forumName; private final byte[] forumSalt; - public ForumSharerSessionState(SessionId sessionId, MessageId storageId, + ForumSharerSessionState(SessionId sessionId, MessageId storageId, GroupId groupId, State state, ContactId contactId, GroupId forumId, String forumName, byte[] forumSalt) { super(sessionId, storageId, groupId, state, contactId, forumId); @@ -30,11 +30,11 @@ public class ForumSharerSessionState extends SharerSessionState { return d; } - public String getForumName() { + String getForumName() { return forumName; } - public byte[] getForumSalt() { + byte[] getForumSalt() { return forumSalt; } } diff --git a/briar-core/src/org/briarproject/sharing/ForumSharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/ForumSharingManagerImpl.java index 9cee634636..95f9f0ef5e 100644 --- a/briar-core/src/org/briarproject/sharing/ForumSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/ForumSharingManagerImpl.java @@ -17,10 +17,12 @@ import org.briarproject.api.event.ForumInvitationReceivedEvent; import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.ForumFactory; -import org.briarproject.api.forum.ForumInvitationMessage; +import org.briarproject.api.forum.ForumInvitationRequest; +import org.briarproject.api.forum.ForumInvitationResponse; import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumSharingManager; import org.briarproject.api.forum.ForumSharingMessage.ForumInvitation; +import org.briarproject.api.sharing.InvitationMessage; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.MessageId; @@ -35,15 +37,13 @@ import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; class ForumSharingManagerImpl extends - SharingManagerImpl<Forum, ForumInvitation, ForumInvitationMessage, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent> + SharingManagerImpl<Forum, ForumInvitation, InvitationMessage, ForumInviteeSessionState, ForumSharerSessionState, ForumInvitationReceivedEvent, ForumInvitationResponseReceivedEvent> implements ForumSharingManager, ForumManager.RemoveForumHook { static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString( "cd11a5d04dccd9e2931d6fc3df456313" + "63bb3e9d9d0e9405fccdb051f41f5449")); - private final ForumManager forumManager; - private final SFactory sFactory; private final IFactory iFactory; private final ISFactory isFactory; @@ -63,7 +63,6 @@ class ForumSharingManagerImpl extends SecureRandom random) { super(db, messageQueueManager, clientHelper, metadataParser, metadataEncoder, random, privateGroupFactory, clock); - this.forumManager = forumManager; sFactory = new SFactory(forumFactory, forumManager); iFactory = new IFactory(); @@ -79,15 +78,23 @@ class ForumSharingManagerImpl extends } @Override - protected ForumInvitationMessage createInvitationMessage(MessageId id, + protected InvitationMessage createInvitationRequest(MessageId id, ForumInvitation msg, ContactId contactId, boolean available, long time, boolean local, boolean sent, boolean seen, boolean read) { - return new ForumInvitationMessage(id, msg.getSessionId(), contactId, + return new ForumInvitationRequest(id, msg.getSessionId(), contactId, msg.getForumName(), msg.getMessage(), available, time, local, sent, seen, read); } + @Override + protected InvitationMessage createInvitationResponse(MessageId id, + SessionId sessionId, ContactId contactId, boolean accept, + long time, boolean local, boolean sent, boolean seen, boolean read) { + return new ForumInvitationResponse(id, sessionId, contactId, accept, + time, local, sent, seen, read); + } + @Override protected ShareableFactory<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState> getSFactory() { return sFactory; @@ -123,7 +130,7 @@ class ForumSharingManagerImpl extends removingShareable(txn, f); } - static class SFactory implements + private static class SFactory implements ShareableFactory<Forum, ForumInvitation, ForumInviteeSessionState, ForumSharerSessionState> { private final ForumFactory forumFactory; @@ -169,7 +176,7 @@ class ForumSharingManagerImpl extends } } - static class IFactory implements + private static class IFactory implements InvitationFactory<ForumInvitation, ForumSharerSessionState> { @Override public ForumInvitation build(GroupId groupId, BdfDictionary d) @@ -185,7 +192,7 @@ class ForumSharingManagerImpl extends } } - static class ISFactory implements + private static class ISFactory implements InviteeSessionStateFactory<Forum, ForumInviteeSessionState> { @Override public ForumInviteeSessionState build(SessionId sessionId, @@ -209,7 +216,7 @@ class ForumSharingManagerImpl extends } } - static class SSFactory implements + private static class SSFactory implements SharerSessionStateFactory<Forum, ForumSharerSessionState> { @Override public ForumSharerSessionState build(SessionId sessionId, @@ -233,7 +240,7 @@ class ForumSharingManagerImpl extends } } - static class IRFactory implements + private static class IRFactory implements InvitationReceivedEventFactory<ForumInviteeSessionState, ForumInvitationReceivedEvent> { private final SFactory sFactory; @@ -251,7 +258,7 @@ class ForumSharingManagerImpl extends } } - static class IRRFactory implements + private static class IRRFactory implements InvitationResponseReceivedEventFactory<ForumSharerSessionState, ForumInvitationResponseReceivedEvent> { @Override public ForumInvitationResponseReceivedEvent build( diff --git a/briar-core/src/org/briarproject/sharing/SharerEngine.java b/briar-core/src/org/briarproject/sharing/SharerEngine.java index 7b09727c50..4f7d23f83b 100644 --- a/briar-core/src/org/briarproject/sharing/SharerEngine.java +++ b/briar-core/src/org/briarproject/sharing/SharerEngine.java @@ -23,7 +23,7 @@ import static org.briarproject.api.sharing.SharingMessage.BaseMessage; import static org.briarproject.api.sharing.SharingMessage.Invitation; import static org.briarproject.api.sharing.SharingMessage.SimpleMessage; -public class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> +class SharerEngine<I extends Invitation, SS extends SharerSessionState, IRR extends InvitationResponseReceivedEvent> implements ProtocolEngine<SharerSessionState.Action, SS, BaseMessage> { private static final Logger LOG = diff --git a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java index 9df89ceb6d..ce34826ec4 100644 --- a/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java +++ b/briar-core/src/org/briarproject/sharing/SharingManagerImpl.java @@ -117,10 +117,14 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IM public abstract ClientId getClientId(); - protected abstract IM createInvitationMessage(MessageId id, I msg, + protected abstract IM createInvitationRequest(MessageId id, I msg, ContactId contactId, boolean available, long time, boolean local, boolean sent, boolean seen, boolean read); + protected abstract IM createInvitationResponse(MessageId id, + SessionId sessionId, ContactId contactId, boolean accept, long time, + boolean local, boolean sent, boolean seen, boolean read); + protected abstract ShareableFactory<S, I, IS, SS> getSFactory(); protected abstract InvitationFactory<I, SS> getIFactory(); @@ -325,11 +329,6 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IM public Collection<IM> getInvitationMessages(ContactId contactId) throws DbException { - // query for all invitations - BdfDictionary query = BdfDictionary.of( - new BdfEntry(TYPE, SHARE_MSG_TYPE_INVITATION) - ); - Transaction txn = db.startTransaction(true); try { Contact contact = db.getContact(txn, contactId); @@ -337,30 +336,51 @@ abstract class SharingManagerImpl<S extends Shareable, I extends Invitation, IM Collection<IM> list = new ArrayList<IM>(); Map<MessageId, BdfDictionary> map = clientHelper - .getMessageMetadataAsDictionary(txn, group.getId(), query); + .getMessageMetadataAsDictionary(txn, group.getId()); for (Map.Entry<MessageId, BdfDictionary> m : map.entrySet()) { BdfDictionary d = m.getValue(); + long type = d.getLong(TYPE); + if (type == SHARE_MSG_TYPE_LEAVE || + type == SHARE_MSG_TYPE_ABORT) continue; try { - I msg = getIFactory().build(group.getId(), d); MessageStatus status = db.getMessageStatus(txn, contactId, m.getKey()); long time = d.getLong(TIME); boolean local = d.getBoolean(LOCAL); boolean read = d.getBoolean(READ, false); boolean available = false; - if (!local) { - // figure out whether the shareable is still available - SharingSessionState s = - getSessionState(txn, msg.getSessionId(), true); - if (!(s instanceof InviteeSessionState)) - continue; - available = ((InviteeSessionState) s).getState() == - AWAIT_LOCAL_RESPONSE; + + if (type == SHARE_MSG_TYPE_INVITATION) { + I msg = getIFactory().build(group.getId(), d); + if (!local) { + // figure out whether the shareable is still available + SharingSessionState s = + getSessionState(txn, msg.getSessionId(), + true); + if (!(s instanceof InviteeSessionState)) + continue; + available = ((InviteeSessionState) s).getState() == + AWAIT_LOCAL_RESPONSE; + } + IM im = createInvitationRequest(m.getKey(), msg, + contactId, available, time, local, + status.isSent(), status.isSeen(), read); + list.add(im); + } + else if (type == SHARE_MSG_TYPE_ACCEPT || + type == SHARE_MSG_TYPE_DECLINE) { + boolean accept = type == SHARE_MSG_TYPE_ACCEPT; + BaseMessage msg = BaseMessage + .from(getIFactory(), group.getId(), d); + SessionId sessionId = msg.getSessionId(); + IM im = createInvitationResponse(m.getKey(), sessionId, + contactId, accept, time, local, + status.isSent(), status.isSeen(), read); + list.add(im); + } + else { + throw new RuntimeException("Unexpected Message Type"); } - IM im = createInvitationMessage(m.getKey(), msg, contactId, - available, time, local, status.isSent(), - status.isSeen(), read); - list.add(im); } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); -- GitLab