From d2722eed92ba305cc1ded927ea82069b737a3239 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Wed, 11 May 2016 19:23:54 -0300 Subject: [PATCH 1/3] Turn local session state into its own class instead of BdfDictionary --- .../briarproject/api/forum/InviteeAction.java | 34 --- .../api/forum/InviteeProtocolState.java | 62 ----- .../briarproject/api/forum/SharerAction.java | 34 --- .../api/forum/SharerProtocolState.java | 62 ----- .../forum/ForumSharingManagerImpl.java | 245 ++++++++++-------- .../forum/ForumSharingSessionState.java | 119 +++++++++ .../org/briarproject/forum/InviteeEngine.java | 124 ++++----- .../forum/InviteeSessionState.java | 130 ++++++++++ .../org/briarproject/forum/SharerEngine.java | 130 +++++----- .../forum/SharerSessionState.java | 130 ++++++++++ 10 files changed, 631 insertions(+), 439 deletions(-) delete mode 100644 briar-api/src/org/briarproject/api/forum/InviteeAction.java delete mode 100644 briar-api/src/org/briarproject/api/forum/InviteeProtocolState.java delete mode 100644 briar-api/src/org/briarproject/api/forum/SharerAction.java delete mode 100644 briar-api/src/org/briarproject/api/forum/SharerProtocolState.java create mode 100644 briar-core/src/org/briarproject/forum/ForumSharingSessionState.java create mode 100644 briar-core/src/org/briarproject/forum/InviteeSessionState.java create mode 100644 briar-core/src/org/briarproject/forum/SharerSessionState.java diff --git a/briar-api/src/org/briarproject/api/forum/InviteeAction.java b/briar-api/src/org/briarproject/api/forum/InviteeAction.java deleted file mode 100644 index 212f0861c..000000000 --- a/briar-api/src/org/briarproject/api/forum/InviteeAction.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.briarproject.api.forum; - -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; - -public enum InviteeAction { - - LOCAL_ACCEPT, - LOCAL_DECLINE, - LOCAL_LEAVE, - LOCAL_ABORT, - REMOTE_INVITATION, - REMOTE_LEAVE, - REMOTE_ABORT; - - public static InviteeAction getLocal(long type) { - if (type == SHARE_MSG_TYPE_ACCEPT) return LOCAL_ACCEPT; - if (type == SHARE_MSG_TYPE_DECLINE) return LOCAL_DECLINE; - if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; - return null; - } - - public static InviteeAction getRemote(long type) { - if (type == SHARE_MSG_TYPE_INVITATION) return REMOTE_INVITATION; - if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT; - return null; - } - -} diff --git a/briar-api/src/org/briarproject/api/forum/InviteeProtocolState.java b/briar-api/src/org/briarproject/api/forum/InviteeProtocolState.java deleted file mode 100644 index 35d6a880a..000000000 --- a/briar-api/src/org/briarproject/api/forum/InviteeProtocolState.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.briarproject.api.forum; - -import static org.briarproject.api.forum.InviteeAction.LOCAL_ACCEPT; -import static org.briarproject.api.forum.InviteeAction.LOCAL_DECLINE; -import static org.briarproject.api.forum.InviteeAction.LOCAL_LEAVE; -import static org.briarproject.api.forum.InviteeAction.REMOTE_INVITATION; -import static org.briarproject.api.forum.InviteeAction.REMOTE_LEAVE; - -public enum InviteeProtocolState { - - ERROR(0), - AWAIT_INVITATION(1) { - @Override - public InviteeProtocolState next(InviteeAction a) { - if (a == REMOTE_INVITATION) return AWAIT_LOCAL_RESPONSE; - return ERROR; - } - }, - AWAIT_LOCAL_RESPONSE(2) { - @Override - public InviteeProtocolState next(InviteeAction a) { - if (a == LOCAL_ACCEPT || a == LOCAL_DECLINE) return FINISHED; - if (a == REMOTE_LEAVE) return LEFT; - return ERROR; - } - }, - FINISHED(3) { - @Override - public InviteeProtocolState next(InviteeAction a) { - if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT; - return FINISHED; - } - }, - LEFT(4) { - @Override - public InviteeProtocolState next(InviteeAction a) { - if (a == LOCAL_LEAVE) return ERROR; - return LEFT; - } - }; - - private final int value; - - InviteeProtocolState(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public static InviteeProtocolState fromValue(int value) { - for (InviteeProtocolState s : values()) { - if (s.value == value) return s; - } - throw new IllegalArgumentException(); - } - - public InviteeProtocolState next(InviteeAction a) { - return this; - } -} diff --git a/briar-api/src/org/briarproject/api/forum/SharerAction.java b/briar-api/src/org/briarproject/api/forum/SharerAction.java deleted file mode 100644 index 39796f2c8..000000000 --- a/briar-api/src/org/briarproject/api/forum/SharerAction.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.briarproject.api.forum; - -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; - -public enum SharerAction { - - LOCAL_INVITATION, - LOCAL_LEAVE, - LOCAL_ABORT, - REMOTE_ACCEPT, - REMOTE_DECLINE, - REMOTE_LEAVE, - REMOTE_ABORT; - - public static SharerAction getLocal(long type) { - if (type == SHARE_MSG_TYPE_INVITATION) return LOCAL_INVITATION; - if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; - return null; - } - - public static SharerAction getRemote(long type) { - if (type == SHARE_MSG_TYPE_ACCEPT) return REMOTE_ACCEPT; - if (type == SHARE_MSG_TYPE_DECLINE) return REMOTE_DECLINE; - if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT; - return null; - } - -} diff --git a/briar-api/src/org/briarproject/api/forum/SharerProtocolState.java b/briar-api/src/org/briarproject/api/forum/SharerProtocolState.java deleted file mode 100644 index b948a9483..000000000 --- a/briar-api/src/org/briarproject/api/forum/SharerProtocolState.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.briarproject.api.forum; - -import static org.briarproject.api.forum.SharerAction.LOCAL_INVITATION; -import static org.briarproject.api.forum.SharerAction.LOCAL_LEAVE; -import static org.briarproject.api.forum.SharerAction.REMOTE_ACCEPT; -import static org.briarproject.api.forum.SharerAction.REMOTE_DECLINE; -import static org.briarproject.api.forum.SharerAction.REMOTE_LEAVE; - -public enum SharerProtocolState { - - ERROR(0), - PREPARE_INVITATION(1) { - @Override - public SharerProtocolState next(SharerAction a) { - if (a == LOCAL_INVITATION) return AWAIT_RESPONSE; - return ERROR; - } - }, - AWAIT_RESPONSE(2) { - @Override - public SharerProtocolState next(SharerAction a) { - if (a == REMOTE_ACCEPT || a == REMOTE_DECLINE) return FINISHED; - if (a == LOCAL_LEAVE) return LEFT; - return ERROR; - } - }, - FINISHED(3) { - @Override - public SharerProtocolState next(SharerAction a) { - if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT; - return FINISHED; - } - }, - LEFT(4) { - @Override - public SharerProtocolState next(SharerAction a) { - if (a == LOCAL_LEAVE) return ERROR; - return LEFT; - } - }; - - private final int value; - - SharerProtocolState(int value) { - this.value = value; - } - - public int getValue() { - return value; - } - - public static SharerProtocolState fromValue(int value) { - for (SharerProtocolState s : values()) { - if (s.value == value) return s; - } - throw new IllegalArgumentException(); - } - - public SharerProtocolState next(SharerAction a) { - return this; - } -} diff --git a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java index a157dbe8a..74e977ac3 100644 --- a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java @@ -27,10 +27,6 @@ import org.briarproject.api.forum.ForumFactory; import org.briarproject.api.forum.ForumInvitationMessage; import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumSharingManager; -import org.briarproject.api.forum.InviteeAction; -import org.briarproject.api.forum.InviteeProtocolState; -import org.briarproject.api.forum.SharerAction; -import org.briarproject.api.forum.SharerProtocolState; import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.Group; import org.briarproject.api.sync.GroupId; @@ -59,7 +55,6 @@ import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.api.clients.ProtocolEngine.StateUpdate; import static org.briarproject.api.forum.ForumConstants.CONTACT_ID; -import static org.briarproject.api.forum.ForumConstants.FORUM_ID; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH; @@ -76,11 +71,8 @@ import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; -import static org.briarproject.api.forum.ForumConstants.STATE; -import static org.briarproject.api.forum.ForumConstants.STORAGE_ID; -import static org.briarproject.api.forum.ForumConstants.TASK; -import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_SHARED_WITH_US; +import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_SHARED_FORUM; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_TO_BE_SHARED_BY_US; @@ -91,9 +83,8 @@ import static org.briarproject.api.forum.ForumConstants.TIME; import static org.briarproject.api.forum.ForumConstants.TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TYPE; import static org.briarproject.api.forum.ForumManager.RemoveForumHook; -import static org.briarproject.api.forum.InviteeProtocolState.AWAIT_INVITATION; -import static org.briarproject.api.forum.InviteeProtocolState.AWAIT_LOCAL_RESPONSE; -import static org.briarproject.api.forum.SharerProtocolState.PREPARE_INVITATION; +import static org.briarproject.forum.ForumSharingSessionState.fromBdfDictionary; +import static org.briarproject.forum.SharerSessionState.Action; class ForumSharingManagerImpl extends BdfIncomingMessageHook implements ForumSharingManager, Client, RemoveForumHook, @@ -214,10 +205,10 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook throw new FormatException(); // initialize state and process invitation - BdfDictionary state = + InviteeSessionState state = initializeInviteeState(txn, contactId, msg); InviteeEngine engine = new InviteeEngine(forumFactory); - processStateUpdate(txn, m.getId(), + processInviteeStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -226,23 +217,25 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } else if (type == SHARE_MSG_TYPE_ACCEPT || type == SHARE_MSG_TYPE_DECLINE) { // we are a sharer who just received a response - BdfDictionary state = getSessionState(txn, sessionId, true); + SharerSessionState state = getSessionStateForSharer(txn, sessionId); SharerEngine engine = new SharerEngine(); - processStateUpdate(txn, m.getId(), + processSharerStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); } else if (type == SHARE_MSG_TYPE_LEAVE || type == SHARE_MSG_TYPE_ABORT) { // we don't know who we are, so figure it out - BdfDictionary state = getSessionState(txn, sessionId, true); - if (state.getBoolean(IS_SHARER)) { + ForumSharingSessionState s = getSessionState(txn, sessionId, true); + if (s instanceof SharerSessionState) { // we are a sharer and the invitee wants to leave or abort + SharerSessionState state = (SharerSessionState) s; SharerEngine engine = new SharerEngine(); - processStateUpdate(txn, m.getId(), + processSharerStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); } else { // we are an invitee and the sharer wants to leave or abort + InviteeSessionState state = (InviteeSessionState) s; InviteeEngine engine = new InviteeEngine(forumFactory); - processStateUpdate(txn, m.getId(), + processInviteeStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); } } else { @@ -264,7 +257,8 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook try { // initialize local state for sharer Forum f = forumManager.getForum(txn, groupId); - BdfDictionary localState = initializeSharerState(txn, f, contactId); + SharerSessionState localState = + initializeSharerState(txn, f, contactId); // define action BdfDictionary localAction = new BdfDictionary(); @@ -275,7 +269,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook // start engine and process its state update SharerEngine engine = new SharerEngine(); - processStateUpdate(txn, null, + processSharerStateUpdate(txn, null, engine.onLocalAction(localState, localAction)); txn.setComplete(); @@ -293,7 +287,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook Transaction txn = db.startTransaction(false); try { // find session state based on forum - BdfDictionary localState = getSessionStateForResponse(txn, f); + InviteeSessionState localState = getSessionStateForResponse(txn, f); // define action BdfDictionary localAction = new BdfDictionary(); @@ -305,7 +299,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook // start engine and process its state update InviteeEngine engine = new InviteeEngine(forumFactory); - processStateUpdate(txn, null, + processInviteeStateUpdate(txn, null, engine.onLocalAction(localState, localAction)); txn.setComplete(); @@ -346,12 +340,12 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook boolean available = false; if (!local) { // figure out whether the forum is still available - BdfDictionary sessionState = + ForumSharingSessionState s = getSessionState(txn, sessionId, true); - InviteeProtocolState state = InviteeProtocolState - .fromValue( - sessionState.getLong(STATE).intValue()); - available = state == AWAIT_LOCAL_RESPONSE; + if (!(s instanceof InviteeSessionState)) + continue; + available = ((InviteeSessionState) s).getState() == + InviteeSessionState.State.AWAIT_LOCAL_RESPONSE; } ForumInvitationMessage im = new ForumInvitationMessage(m.getKey(), sessionId, @@ -490,7 +484,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } } - private BdfDictionary initializeSharerState(Transaction txn, Forum f, + private SharerSessionState initializeSharerState(Transaction txn, Forum f, ContactId contactId) throws FormatException, DbException { Contact c = db.getContact(txn, contactId); @@ -502,26 +496,20 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook random.nextBytes(salt.getBytes()); Message m = clientHelper.createMessage(localGroup.getId(), now, BdfList.of(salt)); - MessageId sessionId = m.getId(); + SessionId sessionId = new SessionId(m.getId().getBytes()); - BdfDictionary d = new BdfDictionary(); - d.put(SESSION_ID, sessionId); - d.put(STORAGE_ID, sessionId); - d.put(GROUP_ID, group.getId()); - d.put(IS_SHARER, true); - d.put(STATE, PREPARE_INVITATION.getValue()); - d.put(CONTACT_ID, contactId.getInt()); - d.put(FORUM_ID, f.getId()); - d.put(FORUM_NAME, f.getName()); - d.put(FORUM_SALT, f.getSalt()); + SharerSessionState s = new SharerSessionState(sessionId, sessionId, + group.getId(), SharerSessionState.State.PREPARE_INVITATION, + contactId, f.getId(), f.getName(), f.getSalt()); // save local state to database + BdfDictionary d = s.toBdfDictionary(); clientHelper.addLocalMessage(txn, m, getClientId(), d, false); - return d; + return s; } - private BdfDictionary initializeInviteeState(Transaction txn, + private InviteeSessionState initializeInviteeState(Transaction txn, ContactId contactId, BdfDictionary msg) throws FormatException, DbException { @@ -538,29 +526,25 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook Message m = clientHelper.createMessage(localGroup.getId(), now, BdfList.of(mSalt)); - BdfDictionary d = new BdfDictionary(); - d.put(SESSION_ID, msg.getRaw(SESSION_ID)); - d.put(STORAGE_ID, m.getId()); - d.put(GROUP_ID, group.getId()); - d.put(IS_SHARER, false); - d.put(STATE, AWAIT_INVITATION.getValue()); - d.put(CONTACT_ID, contactId.getInt()); - d.put(FORUM_ID, f.getId()); - d.put(FORUM_NAME, name); - d.put(FORUM_SALT, salt); + SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID)); + + InviteeSessionState s = new InviteeSessionState(sessionId, m.getId(), + group.getId(), InviteeSessionState.State.AWAIT_INVITATION, + contactId, f.getId(), f.getName(), f.getSalt()); // save local state to database + BdfDictionary d = s.toBdfDictionary(); clientHelper.addLocalMessage(txn, m, getClientId(), d, false); - return d; + return s; } - private BdfDictionary getSessionState(Transaction txn, SessionId sessionId, - boolean warn) throws DbException, FormatException { + private ForumSharingSessionState getSessionState(Transaction txn, + SessionId sessionId, boolean warn) + throws DbException, FormatException { try { - // we should be able to get the sharer state directly from sessionId - return clientHelper.getMessageMetadataAsDictionary(txn, sessionId); + return getSessionStateForSharer(txn, sessionId); } catch (NoSuchMessageException e) { // State not found directly, so iterate over all states // to find state for invitee @@ -570,7 +554,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook BdfDictionary state = m.getValue(); if (Arrays.equals(state.getRaw(SESSION_ID), sessionId.getBytes())) { - return state; + return fromBdfDictionary(state); } } if (warn && LOG.isLoggable(WARNING)) { @@ -582,23 +566,37 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } } - private BdfDictionary getSessionStateForResponse(Transaction txn, Forum f) + private SharerSessionState getSessionStateForSharer(Transaction txn, + SessionId sessionId) throws DbException, FormatException { + // we should be able to get the sharer state directly from sessionId + BdfDictionary d = + clientHelper.getMessageMetadataAsDictionary(txn, sessionId); + + if (!d.getBoolean(IS_SHARER)) throw new FormatException(); + + return (SharerSessionState) fromBdfDictionary(d); + } + + private InviteeSessionState getSessionStateForResponse(Transaction txn, + Forum f) throws DbException, FormatException { + Map map = clientHelper .getMessageMetadataAsDictionary(txn, localGroup.getId()); for (Map.Entry m : map.entrySet()) { BdfDictionary d = m.getValue(); try { - InviteeProtocolState state = InviteeProtocolState - .fromValue(d.getLong(STATE).intValue()); - if (state == AWAIT_LOCAL_RESPONSE) { - byte[] id = d.getRaw(FORUM_ID); - if (Arrays.equals(f.getId().getBytes(), id)) { - // Note that there should always be only one session - // in this state for the same forum - return d; - } + ForumSharingSessionState s = fromBdfDictionary(d); + if (!(s instanceof InviteeSessionState)) continue; + if (!f.getId().equals(s.getForumId())) continue; + + InviteeSessionState state = (InviteeSessionState) s; + if (state.getState() == + InviteeSessionState.State.AWAIT_LOCAL_RESPONSE) { + // Note that there should always be only one session + // in this state for the same forum + return state; } } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -607,36 +605,40 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook throw new DbException(); } - private BdfDictionary getSessionStateForLeaving(Transaction txn, Forum f, - ContactId c) throws DbException, FormatException { + private ForumSharingSessionState getSessionStateForLeaving(Transaction txn, + Forum f, ContactId c) throws DbException, FormatException { Map map = clientHelper .getMessageMetadataAsDictionary(txn, localGroup.getId()); for (Map.Entry m : map.entrySet()) { BdfDictionary d = m.getValue(); try { + ForumSharingSessionState s = fromBdfDictionary(d); + // check that this session is with the right contact - if (c.getInt() != d.getLong(CONTACT_ID)) continue; - // check that a forum get be left in current session - int intState = d.getLong(STATE).intValue(); - if (d.getBoolean(IS_SHARER)) { - SharerProtocolState state = - SharerProtocolState.fromValue(intState); - if (state.next(SharerAction.LOCAL_LEAVE) == - SharerProtocolState.ERROR) continue; - } else { - InviteeProtocolState state = InviteeProtocolState - .fromValue(intState); - if (state.next(InviteeAction.LOCAL_LEAVE) == - InviteeProtocolState.ERROR) continue; - } + if (!c.equals(s.getContactId())) continue; + // check that this state actually concerns this forum - String name = d.getString(FORUM_NAME); - byte[] salt = d.getRaw(FORUM_SALT); - if (name.equals(f.getName()) && - Arrays.equals(salt, f.getSalt())) { - // TODO what happens when there is more than one invitation? - return d; + if (!s.getForumName().equals(f.getName()) || + !Arrays.equals(s.getForumSalt(), f.getSalt())) { + continue; + } + + // check that a forum get be left in current session + if (s instanceof SharerSessionState) { + SharerSessionState state = (SharerSessionState) s; + SharerSessionState.State nextState = + state.getState().next(Action.LOCAL_LEAVE); + if (nextState != SharerSessionState.State.ERROR) { + return state; + } + } else { + InviteeSessionState state = (InviteeSessionState) s; + InviteeSessionState.State nextState = state.getState() + .next(InviteeSessionState.Action.LOCAL_LEAVE); + if (nextState != InviteeSessionState.State.ERROR) { + return state; + } } } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); @@ -646,16 +648,16 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } private void processStateUpdate(Transaction txn, MessageId messageId, - StateUpdate result) + StateUpdate result) throws DbException, FormatException { // perform actions based on new local state performTasks(txn, result.localState); // save new local state - MessageId storageId = - new MessageId(result.localState.getRaw(STORAGE_ID)); - clientHelper.mergeMessageMetadata(txn, storageId, result.localState); + MessageId storageId = result.localState.getStorageId(); + clientHelper.mergeMessageMetadata(txn, storageId, + result.localState.toBdfDictionary()); // send messages for (BdfDictionary d : result.toSend) { @@ -677,24 +679,47 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } } - private void performTasks(Transaction txn, BdfDictionary localState) + private void processSharerStateUpdate(Transaction txn, MessageId messageId, + StateUpdate result) + throws DbException, FormatException { + + StateUpdate r = + new StateUpdate( + result.deleteMessage, result.deleteState, + result.localState, result.toSend, result.toBroadcast); + + processStateUpdate(txn, messageId, r); + } + + private void processInviteeStateUpdate(Transaction txn, MessageId messageId, + StateUpdate result) + throws DbException, FormatException { + + StateUpdate r = + new StateUpdate( + result.deleteMessage, result.deleteState, + result.localState, result.toSend, result.toBroadcast); + + processStateUpdate(txn, messageId, r); + } + + private void performTasks(Transaction txn, ForumSharingSessionState localState) throws FormatException, DbException { - if (!localState.containsKey(TASK)) return; + if (localState.getTask() == -1) return; // remember task and remove it from localState - long task = localState.getLong(TASK); - localState.put(TASK, BdfDictionary.NULL_VALUE); + long task = localState.getTask(); + localState.setTask(-1); // get group ID for later - GroupId groupId = new GroupId(localState.getRaw(GROUP_ID)); + GroupId groupId = localState.getGroupId(); // get contact ID for later - ContactId contactId = - new ContactId(localState.getLong(CONTACT_ID).intValue()); + ContactId contactId = localState.getContactId(); // get forum for later - String name = localState.getString(FORUM_NAME); - byte[] salt = localState.getRaw(FORUM_SALT); + String name = localState.getForumName(); + byte[] salt = localState.getForumSalt(); Forum f = forumFactory.createForum(name, salt); // perform tasks @@ -786,17 +811,17 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook private void leaveForum(Transaction txn, ContactId c, Forum f) throws DbException, FormatException { - BdfDictionary state = getSessionStateForLeaving(txn, f, c); + ForumSharingSessionState state = getSessionStateForLeaving(txn, f, c); BdfDictionary action = new BdfDictionary(); action.put(TYPE, SHARE_MSG_TYPE_LEAVE); - if (state.getBoolean(IS_SHARER)) { + if (state instanceof SharerSessionState) { SharerEngine engine = new SharerEngine(); - processStateUpdate(txn, null, - engine.onLocalAction(state, action)); + processSharerStateUpdate(txn, null, + engine.onLocalAction((SharerSessionState) state, action)); } else { InviteeEngine engine = new InviteeEngine(forumFactory); - processStateUpdate(txn, null, - engine.onLocalAction(state, action)); + processInviteeStateUpdate(txn, null, + engine.onLocalAction((InviteeSessionState) state, action)); } } diff --git a/briar-core/src/org/briarproject/forum/ForumSharingSessionState.java b/briar-core/src/org/briarproject/forum/ForumSharingSessionState.java new file mode 100644 index 000000000..dc2e69bfb --- /dev/null +++ b/briar-core/src/org/briarproject/forum/ForumSharingSessionState.java @@ -0,0 +1,119 @@ +package org.briarproject.forum; + +import org.briarproject.api.FormatException; +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; + +import static org.briarproject.api.forum.ForumConstants.CONTACT_ID; +import static org.briarproject.api.forum.ForumConstants.FORUM_ID; +import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; +import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; +import static org.briarproject.api.forum.ForumConstants.GROUP_ID; +import static org.briarproject.api.forum.ForumConstants.IS_SHARER; +import static org.briarproject.api.forum.ForumConstants.SESSION_ID; +import static org.briarproject.api.forum.ForumConstants.STATE; +import static org.briarproject.api.forum.ForumConstants.STORAGE_ID; + +// This class is not thread-safe +public abstract class ForumSharingSessionState { + + private final SessionId sessionId; + private final MessageId storageId; + private final GroupId groupId; + private final ContactId contactId; + private final GroupId forumId; + private final String forumName; + private final byte[] forumSalt; + private int task = -1; // TODO get rid of task, see #376 + + public ForumSharingSessionState(SessionId sessionId, MessageId storageId, + GroupId groupId, ContactId contactId, GroupId forumId, + String forumName, byte[] forumSalt) { + + this.sessionId = sessionId; + this.storageId = storageId; + this.groupId = groupId; + this.contactId = contactId; + this.forumId = forumId; + this.forumName = forumName; + this.forumSalt = forumSalt; + } + + public static ForumSharingSessionState fromBdfDictionary(BdfDictionary d) + throws FormatException{ + + SessionId sessionId = new SessionId(d.getRaw(SESSION_ID)); + MessageId messageId = new MessageId(d.getRaw(STORAGE_ID)); + GroupId groupId = new GroupId(d.getRaw(GROUP_ID)); + ContactId contactId = new ContactId(d.getLong(CONTACT_ID).intValue()); + GroupId forumId = new GroupId(d.getRaw(FORUM_ID)); + String forumName = d.getString(FORUM_NAME); + byte[] forumSalt = d.getRaw(FORUM_SALT); + + int intState = d.getLong(STATE).intValue(); + if (d.getBoolean(IS_SHARER)) { + SharerSessionState.State state = + SharerSessionState.State.fromValue(intState); + return new SharerSessionState(sessionId, messageId, groupId, state, + contactId, forumId, forumName, forumSalt); + } else { + InviteeSessionState.State state = + InviteeSessionState.State.fromValue(intState); + return new InviteeSessionState(sessionId, messageId, groupId, state, + contactId, forumId, forumName, forumSalt); + } + } + + public BdfDictionary toBdfDictionary() { + BdfDictionary d = new BdfDictionary(); + d.put(SESSION_ID, getSessionId()); + d.put(STORAGE_ID, getStorageId()); + d.put(GROUP_ID, getGroupId()); + d.put(CONTACT_ID, getContactId().getInt()); + d.put(FORUM_ID, getForumId()); + d.put(FORUM_NAME, getForumName()); + d.put(FORUM_SALT, getForumSalt()); + + return d; + } + + public SessionId getSessionId() { + return sessionId; + } + + public MessageId getStorageId() { + return storageId; + } + + public GroupId getGroupId() { + return groupId; + } + + public ContactId getContactId() { + return contactId; + } + + public GroupId getForumId() { + return forumId; + } + + public String getForumName() { + return forumName; + } + + public byte[] getForumSalt() { + return forumSalt; + } + + public void setTask(int task) { + this.task = task; + } + + public int getTask() { + return task; + } + +} \ No newline at end of file diff --git a/briar-core/src/org/briarproject/forum/InviteeEngine.java b/briar-core/src/org/briarproject/forum/InviteeEngine.java index 70e9a24cb..81d4cf766 100644 --- a/briar-core/src/org/briarproject/forum/InviteeEngine.java +++ b/briar-core/src/org/briarproject/forum/InviteeEngine.java @@ -9,8 +9,6 @@ import org.briarproject.api.event.Event; import org.briarproject.api.event.ForumInvitationReceivedEvent; import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.ForumFactory; -import org.briarproject.api.forum.InviteeAction; -import org.briarproject.api.forum.InviteeProtocolState; import java.util.Arrays; import java.util.Collections; @@ -19,9 +17,6 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.forum.ForumConstants.CONTACT_ID; -import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; -import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.GROUP_ID; import static org.briarproject.api.forum.ForumConstants.SESSION_ID; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; @@ -29,25 +24,25 @@ import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; -import static org.briarproject.api.forum.ForumConstants.STATE; -import static org.briarproject.api.forum.ForumConstants.TASK; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_SHARED_WITH_US; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_SHARED_FORUM; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US; import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_WITH_US; import static org.briarproject.api.forum.ForumConstants.TYPE; -import static org.briarproject.api.forum.InviteeAction.LOCAL_ABORT; -import static org.briarproject.api.forum.InviteeAction.LOCAL_ACCEPT; -import static org.briarproject.api.forum.InviteeAction.LOCAL_DECLINE; -import static org.briarproject.api.forum.InviteeAction.LOCAL_LEAVE; -import static org.briarproject.api.forum.InviteeAction.REMOTE_INVITATION; -import static org.briarproject.api.forum.InviteeAction.REMOTE_LEAVE; -import static org.briarproject.api.forum.InviteeProtocolState.ERROR; -import static org.briarproject.api.forum.InviteeProtocolState.FINISHED; -import static org.briarproject.api.forum.InviteeProtocolState.LEFT; +import static org.briarproject.forum.InviteeSessionState.Action; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ABORT; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ACCEPT; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_DECLINE; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_LEAVE; +import static org.briarproject.forum.InviteeSessionState.Action.REMOTE_INVITATION; +import static org.briarproject.forum.InviteeSessionState.Action.REMOTE_LEAVE; +import static org.briarproject.forum.InviteeSessionState.State; +import static org.briarproject.forum.InviteeSessionState.State.ERROR; +import static org.briarproject.forum.InviteeSessionState.State.FINISHED; +import static org.briarproject.forum.InviteeSessionState.State.LEFT; public class InviteeEngine - implements ProtocolEngine { + implements ProtocolEngine { private final ForumFactory forumFactory; private static final Logger LOG = @@ -58,16 +53,15 @@ public class InviteeEngine } @Override - public StateUpdate onLocalAction( - BdfDictionary localState, BdfDictionary localAction) { + public StateUpdate onLocalAction( + InviteeSessionState localState, BdfDictionary localAction) { try { - InviteeProtocolState currentState = - getState(localState.getLong(STATE)); + State currentState = localState.getState(); long type = localAction.getLong(TYPE); - InviteeAction action = InviteeAction.getLocal(type); - InviteeProtocolState nextState = currentState.next(action); - localState.put(STATE, nextState.getValue()); + Action action = Action.getLocal(type); + State nextState = currentState.next(action); + localState.setState(nextState); if (action == LOCAL_ABORT && currentState != ERROR) { return abortSession(currentState, localState); @@ -85,14 +79,14 @@ public class InviteeEngine if (action == LOCAL_ACCEPT || action == LOCAL_DECLINE) { BdfDictionary msg = BdfDictionary.of( - new BdfEntry(SESSION_ID, localState.getRaw(SESSION_ID)), - new BdfEntry(GROUP_ID, localState.getRaw(GROUP_ID)) + new BdfEntry(SESSION_ID, localState.getSessionId()), + new BdfEntry(GROUP_ID, localState.getGroupId()) ); if (action == LOCAL_ACCEPT) { - localState.put(TASK, TASK_ADD_SHARED_FORUM); + localState.setTask(TASK_ADD_SHARED_FORUM); msg.put(TYPE, SHARE_MSG_TYPE_ACCEPT); } else { - localState.put(TASK, + localState.setTask( TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US); msg.put(TYPE, SHARE_MSG_TYPE_DECLINE); } @@ -102,15 +96,15 @@ public class InviteeEngine else if (action == LOCAL_LEAVE) { BdfDictionary msg = new BdfDictionary(); msg.put(TYPE, SHARE_MSG_TYPE_LEAVE); - msg.put(SESSION_ID, localState.getRaw(SESSION_ID)); - msg.put(GROUP_ID, localState.getRaw(GROUP_ID)); + msg.put(SESSION_ID, localState.getSessionId()); + msg.put(GROUP_ID, localState.getGroupId()); messages = Collections.singletonList(msg); logLocalAction(currentState, localState, msg); } else { throw new IllegalArgumentException("Unknown Local Action"); } - return new StateUpdate(false, + return new StateUpdate(false, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -118,16 +112,15 @@ public class InviteeEngine } @Override - public StateUpdate onMessageReceived( - BdfDictionary localState, BdfDictionary msg) { + public StateUpdate onMessageReceived( + InviteeSessionState localState, BdfDictionary msg) { try { - InviteeProtocolState currentState = - getState(localState.getLong(STATE)); + State currentState = localState.getState(); long type = msg.getLong(TYPE); - InviteeAction action = InviteeAction.getRemote(type); - InviteeProtocolState nextState = currentState.next(action); - localState.put(STATE, nextState.getValue()); + Action action = Action.getRemote(type); + State nextState = currentState.next(action); + localState.setState(nextState); logMessageReceived(currentState, nextState, type, msg); @@ -149,7 +142,7 @@ public class InviteeEngine } // the sharer left the forum she had shared with us else if (action == REMOTE_LEAVE && currentState == FINISHED) { - localState.put(TASK, TASK_UNSHARE_FORUM_SHARED_WITH_US); + localState.setTask(TASK_UNSHARE_FORUM_SHARED_WITH_US); } else if (currentState == FINISHED) { // ignore and delete messages coming in while in that state @@ -158,31 +151,30 @@ public class InviteeEngine } // the sharer left the forum before we couldn't even respond else if (action == REMOTE_LEAVE) { - localState.put(TASK, TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US); + localState.setTask(TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US); } // we have just received our invitation else if (action == REMOTE_INVITATION) { - localState.put(TASK, TASK_ADD_FORUM_TO_LIST_SHARED_WITH_US); Forum forum = forumFactory - .createForum(localState.getString(FORUM_NAME), - localState.getRaw(FORUM_SALT)); - ContactId contactId = new ContactId( - localState.getLong(CONTACT_ID).intValue()); + .createForum(localState.getForumName(), + localState.getForumSalt()); + localState.setTask(TASK_ADD_FORUM_TO_LIST_SHARED_WITH_US); + ContactId contactId = localState.getContactId(); Event event = new ForumInvitationReceivedEvent(forum, contactId); events = Collections.singletonList(event); } else { throw new IllegalArgumentException("Bad state"); } - return new StateUpdate(deleteMsg, + return new StateUpdate(deleteMsg, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); } } - private void logLocalAction(InviteeProtocolState state, - BdfDictionary localState, BdfDictionary msg) { + private void logLocalAction(State state, + InviteeSessionState localState, BdfDictionary msg) { if (!LOG.isLoggable(INFO)) return; @@ -194,16 +186,16 @@ public class InviteeEngine " with session ID " + Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + - getState(localState.getLong(STATE)).name() + "Moving on to state " + localState.getState().name() ); } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } } - private void logMessageReceived(InviteeProtocolState currentState, - InviteeProtocolState nextState, long type, BdfDictionary msg) { + private void logMessageReceived(State currentState, State nextState, + long type, BdfDictionary msg) { + if (!LOG.isLoggable(INFO)) return; try { @@ -224,8 +216,8 @@ public class InviteeEngine } @Override - public StateUpdate onMessageDelivered( - BdfDictionary localState, BdfDictionary delivered) { + public StateUpdate onMessageDelivered( + InviteeSessionState localState, BdfDictionary delivered) { try { return noUpdate(localState, false); } catch (FormatException e) { @@ -234,37 +226,33 @@ public class InviteeEngine } } - private InviteeProtocolState getState(Long state) { - return InviteeProtocolState.fromValue(state.intValue()); - } - - private StateUpdate abortSession( - InviteeProtocolState currentState, BdfDictionary localState) + private StateUpdate abortSession( + State currentState, InviteeSessionState localState) throws FormatException { if (LOG.isLoggable(WARNING)) { LOG.warning("Aborting protocol session " + - Arrays.hashCode(localState.getRaw(SESSION_ID)) + + localState.getSessionId().hashCode() + " in state " + currentState.name()); } - localState.put(STATE, ERROR.getValue()); + localState.setState(ERROR); BdfDictionary msg = new BdfDictionary(); msg.put(TYPE, SHARE_MSG_TYPE_ABORT); - msg.put(SESSION_ID, localState.getRaw(SESSION_ID)); - msg.put(GROUP_ID, localState.getRaw(GROUP_ID)); + msg.put(SESSION_ID, localState.getSessionId()); + msg.put(GROUP_ID, localState.getGroupId()); List messages = Collections.singletonList(msg); List events = Collections.emptyList(); - return new StateUpdate(false, false, + return new StateUpdate(false, false, localState, messages, events); } - private StateUpdate noUpdate( - BdfDictionary localState, boolean delete) throws FormatException { + private StateUpdate noUpdate( + InviteeSessionState localState, boolean delete) throws FormatException { - return new StateUpdate(delete, false, + return new StateUpdate(delete, false, localState, Collections.emptyList(), Collections.emptyList()); } diff --git a/briar-core/src/org/briarproject/forum/InviteeSessionState.java b/briar-core/src/org/briarproject/forum/InviteeSessionState.java new file mode 100644 index 000000000..cc4e1c404 --- /dev/null +++ b/briar-core/src/org/briarproject/forum/InviteeSessionState.java @@ -0,0 +1,130 @@ +package org.briarproject.forum; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; + +import static org.briarproject.api.forum.ForumConstants.IS_SHARER; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; +import static org.briarproject.api.forum.ForumConstants.STATE; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ACCEPT; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_DECLINE; +import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_LEAVE; +import static org.briarproject.forum.InviteeSessionState.Action.REMOTE_INVITATION; +import static org.briarproject.forum.InviteeSessionState.Action.REMOTE_LEAVE; + +// This class is not thread-safe +public class InviteeSessionState extends ForumSharingSessionState { + + private State state; + + public InviteeSessionState(SessionId sessionId, MessageId storageId, + GroupId groupId, State state, ContactId contactId, GroupId forumId, + String forumName, byte[] forumSalt) { + + super(sessionId, storageId, groupId, contactId, forumId, forumName, + forumSalt); + this.state = state; + } + + public BdfDictionary toBdfDictionary() { + BdfDictionary d = super.toBdfDictionary(); + d.put(STATE, getState().getValue()); + d.put(IS_SHARER, false); + return d; + } + + public void setState(State state) { + this.state = state; + } + + public State getState() { + return state; + } + + public enum State { + ERROR(0), + AWAIT_INVITATION(1) { + @Override + public State next(Action a) { + if (a == REMOTE_INVITATION) return AWAIT_LOCAL_RESPONSE; + return ERROR; + } + }, + AWAIT_LOCAL_RESPONSE(2) { + @Override + public State next(Action a) { + if (a == LOCAL_ACCEPT || a == LOCAL_DECLINE) return FINISHED; + if (a == REMOTE_LEAVE) return LEFT; + return ERROR; + } + }, + FINISHED(3) { + @Override + public State next(Action a) { + if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT; + return FINISHED; + } + }, + LEFT(4) { + @Override + public State next(Action a) { + if (a == LOCAL_LEAVE) return ERROR; + return LEFT; + } + }; + + private final int value; + + State(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static State fromValue(int value) { + for (State s : values()) { + if (s.value == value) return s; + } + throw new IllegalArgumentException(); + } + + public State next(Action a) { + return this; + } + } + + public enum Action { + LOCAL_ACCEPT, + LOCAL_DECLINE, + LOCAL_LEAVE, + LOCAL_ABORT, + REMOTE_INVITATION, + REMOTE_LEAVE, + REMOTE_ABORT; + + public static Action getLocal(long type) { + if (type == SHARE_MSG_TYPE_ACCEPT) return LOCAL_ACCEPT; + if (type == SHARE_MSG_TYPE_DECLINE) return LOCAL_DECLINE; + if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; + if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; + return null; + } + + public static Action getRemote(long type) { + if (type == SHARE_MSG_TYPE_INVITATION) return REMOTE_INVITATION; + if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE; + if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT; + return null; + } + } + +} \ No newline at end of file diff --git a/briar-core/src/org/briarproject/forum/SharerEngine.java b/briar-core/src/org/briarproject/forum/SharerEngine.java index 05db965b8..3e81470ae 100644 --- a/briar-core/src/org/briarproject/forum/SharerEngine.java +++ b/briar-core/src/org/briarproject/forum/SharerEngine.java @@ -6,8 +6,7 @@ import org.briarproject.api.contact.ContactId; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.event.Event; import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; -import org.briarproject.api.forum.SharerAction; -import org.briarproject.api.forum.SharerProtocolState; +import static org.briarproject.forum.SharerSessionState.Action; import java.util.Arrays; import java.util.Collections; @@ -16,7 +15,6 @@ import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.forum.ForumConstants.CONTACT_ID; import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.GROUP_ID; @@ -27,40 +25,38 @@ import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; -import static org.briarproject.api.forum.ForumConstants.STATE; -import static org.briarproject.api.forum.ForumConstants.TASK; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_SHARE_FORUM; import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TYPE; -import static org.briarproject.api.forum.SharerAction.LOCAL_ABORT; -import static org.briarproject.api.forum.SharerAction.LOCAL_INVITATION; -import static org.briarproject.api.forum.SharerAction.LOCAL_LEAVE; -import static org.briarproject.api.forum.SharerAction.REMOTE_ACCEPT; -import static org.briarproject.api.forum.SharerAction.REMOTE_DECLINE; -import static org.briarproject.api.forum.SharerAction.REMOTE_LEAVE; -import static org.briarproject.api.forum.SharerProtocolState.ERROR; -import static org.briarproject.api.forum.SharerProtocolState.FINISHED; -import static org.briarproject.api.forum.SharerProtocolState.LEFT; +import static org.briarproject.forum.SharerSessionState.Action.LOCAL_ABORT; +import static org.briarproject.forum.SharerSessionState.Action.LOCAL_INVITATION; +import static org.briarproject.forum.SharerSessionState.Action.LOCAL_LEAVE; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_ACCEPT; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_DECLINE; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_LEAVE; +import static org.briarproject.forum.SharerSessionState.State; +import static org.briarproject.forum.SharerSessionState.State.ERROR; +import static org.briarproject.forum.SharerSessionState.State.FINISHED; +import static org.briarproject.forum.SharerSessionState.State.LEFT; public class SharerEngine - implements ProtocolEngine { + implements ProtocolEngine { private static final Logger LOG = Logger.getLogger(SharerEngine.class.getName()); @Override - public StateUpdate onLocalAction( - BdfDictionary localState, BdfDictionary localAction) { + public StateUpdate onLocalAction( + SharerSessionState localState, BdfDictionary localAction) { try { - SharerProtocolState currentState = - getState(localState.getLong(STATE)); + State currentState = localState.getState(); long type = localAction.getLong(TYPE); - SharerAction action = SharerAction.getLocal(type); - SharerProtocolState nextState = currentState.next(action); - localState.put(STATE, nextState.getValue()); + Action action = Action.getLocal(type); + State nextState = currentState.next(action); + localState.setState(nextState); if (action == LOCAL_ABORT && currentState != ERROR) { return abortSession(currentState, localState); @@ -79,32 +75,32 @@ public class SharerEngine if (action == LOCAL_INVITATION) { BdfDictionary msg = new BdfDictionary(); msg.put(TYPE, SHARE_MSG_TYPE_INVITATION); - msg.put(SESSION_ID, localState.getRaw(SESSION_ID)); - msg.put(GROUP_ID, localState.getRaw(GROUP_ID)); - msg.put(FORUM_NAME, localState.getString(FORUM_NAME)); - msg.put(FORUM_SALT, localState.getRaw(FORUM_SALT)); + msg.put(SESSION_ID, localState.getSessionId()); + msg.put(GROUP_ID, localState.getGroupId()); + msg.put(FORUM_NAME, localState.getForumName()); + msg.put(FORUM_SALT, localState.getForumSalt()); if (localAction.containsKey(INVITATION_MSG)) { msg.put(INVITATION_MSG, localAction.getString(INVITATION_MSG)); } messages = Collections.singletonList(msg); - logLocalAction(currentState, localState, msg); + logLocalAction(currentState, nextState, msg); // remember that we offered to share this forum - localState.put(TASK, TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US); + localState.setTask(TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US); } else if (action == LOCAL_LEAVE) { BdfDictionary msg = new BdfDictionary(); msg.put(TYPE, SHARE_MSG_TYPE_LEAVE); - msg.put(SESSION_ID, localState.getRaw(SESSION_ID)); - msg.put(GROUP_ID, localState.getRaw(GROUP_ID)); + msg.put(SESSION_ID, localState.getSessionId()); + msg.put(GROUP_ID, localState.getGroupId()); messages = Collections.singletonList(msg); - logLocalAction(currentState, localState, msg); + logLocalAction(currentState, nextState, msg); } else { throw new IllegalArgumentException("Unknown Local Action"); } - return new StateUpdate(false, + return new StateUpdate(false, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -112,16 +108,15 @@ public class SharerEngine } @Override - public StateUpdate onMessageReceived( - BdfDictionary localState, BdfDictionary msg) { + public StateUpdate onMessageReceived( + SharerSessionState localState, BdfDictionary msg) { try { - SharerProtocolState currentState = - getState(localState.getLong(STATE)); + State currentState = localState.getState(); long type = msg.getLong(TYPE); - SharerAction action = SharerAction.getRemote(type); - SharerProtocolState nextState = currentState.next(action); - localState.put(STATE, nextState.getValue()); + Action action = Action.getRemote(type); + State nextState = currentState.next(action); + localState.setState(nextState); logMessageReceived(currentState, nextState, type, msg); @@ -141,7 +136,7 @@ public class SharerEngine deleteMsg = true; } else if (action == REMOTE_LEAVE) { - localState.put(TASK, TASK_UNSHARE_FORUM_SHARED_BY_US); + localState.setTask(TASK_UNSHARE_FORUM_SHARED_BY_US); } else if (currentState == FINISHED) { // ignore and delete messages coming in while in that state @@ -151,30 +146,29 @@ public class SharerEngine // we have sent our invitation and just got a response else if (action == REMOTE_ACCEPT || action == REMOTE_DECLINE) { if (action == REMOTE_ACCEPT) { - localState.put(TASK, TASK_SHARE_FORUM); + localState.setTask(TASK_SHARE_FORUM); } else { // this ensures that the forum can be shared again - localState.put(TASK, + localState.setTask( TASK_REMOVE_FORUM_FROM_LIST_TO_BE_SHARED_BY_US); } - String name = localState.getString(FORUM_NAME); - ContactId c = new ContactId( - localState.getLong(CONTACT_ID).intValue()); + String name = localState.getForumName(); + ContactId c = localState.getContactId(); Event event = new ForumInvitationResponseReceivedEvent(name, c); events = Collections.singletonList(event); } else { throw new IllegalArgumentException("Bad state"); } - return new StateUpdate(deleteMsg, + return new StateUpdate(deleteMsg, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); } } - private void logLocalAction(SharerProtocolState state, - BdfDictionary localState, BdfDictionary msg) { + private void logLocalAction(State currentState, State nextState, + BdfDictionary msg) { if (!LOG.isLoggable(INFO)) return; @@ -182,20 +176,20 @@ public class SharerEngine if (msg.getLong(TYPE, -1L) == SHARE_MSG_TYPE_LEAVE) a = "leave"; try { - LOG.info("Sending " + a + " in state " + state.name() + + LOG.info("Sending " + a + " in state " + currentState.name() + " with session ID " + Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + - getState(localState.getLong(STATE)).name() + "Moving on to state " + nextState.name() ); } catch (FormatException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } } - private void logMessageReceived(SharerProtocolState currentState, - SharerProtocolState nextState, long type, BdfDictionary msg) { + private void logMessageReceived(State currentState, State nextState, + long type, BdfDictionary msg) { + if (!LOG.isLoggable(INFO)) return; try { @@ -217,8 +211,8 @@ public class SharerEngine } @Override - public StateUpdate onMessageDelivered( - BdfDictionary localState, BdfDictionary delivered) { + public StateUpdate onMessageDelivered( + SharerSessionState localState, BdfDictionary delivered) { try { return noUpdate(localState, false); } catch (FormatException e) { @@ -227,38 +221,36 @@ public class SharerEngine } } - private SharerProtocolState getState(Long state) { - return SharerProtocolState.fromValue(state.intValue()); - } - - private StateUpdate abortSession( - SharerProtocolState currentState, BdfDictionary localState) + private StateUpdate abortSession( + State currentState, SharerSessionState localState) throws FormatException { if (LOG.isLoggable(WARNING)) { LOG.warning("Aborting protocol session " + - Arrays.hashCode(localState.getRaw(SESSION_ID)) + + localState.getSessionId().hashCode() + " in state " + currentState.name()); } - localState.put(STATE, ERROR.getValue()); + localState.setState(ERROR); BdfDictionary msg = new BdfDictionary(); msg.put(TYPE, SHARE_MSG_TYPE_ABORT); - msg.put(SESSION_ID, localState.getRaw(SESSION_ID)); - msg.put(GROUP_ID, localState.getRaw(GROUP_ID)); + msg.put(SESSION_ID, localState.getSessionId()); + msg.put(GROUP_ID, localState.getGroupId()); List messages = Collections.singletonList(msg); List events = Collections.emptyList(); - return new StateUpdate(false, false, + return new StateUpdate(false, false, localState, messages, events); } - private StateUpdate noUpdate( - BdfDictionary localState, boolean delete) throws FormatException { + private StateUpdate noUpdate( + SharerSessionState localState, boolean delete) + throws FormatException { - return new StateUpdate(delete, false, + return new StateUpdate(delete, false, localState, Collections.emptyList(), Collections.emptyList()); } + } diff --git a/briar-core/src/org/briarproject/forum/SharerSessionState.java b/briar-core/src/org/briarproject/forum/SharerSessionState.java new file mode 100644 index 000000000..b438c6734 --- /dev/null +++ b/briar-core/src/org/briarproject/forum/SharerSessionState.java @@ -0,0 +1,130 @@ +package org.briarproject.forum; + +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.contact.ContactId; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.sync.GroupId; +import org.briarproject.api.sync.MessageId; + +import static org.briarproject.api.forum.ForumConstants.IS_SHARER; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; +import static org.briarproject.api.forum.ForumConstants.STATE; +import static org.briarproject.forum.SharerSessionState.Action.LOCAL_INVITATION; +import static org.briarproject.forum.SharerSessionState.Action.LOCAL_LEAVE; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_ACCEPT; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_DECLINE; +import static org.briarproject.forum.SharerSessionState.Action.REMOTE_LEAVE; + +// This class is not thread-safe +public class SharerSessionState extends ForumSharingSessionState { + + private State state; + + public SharerSessionState(SessionId sessionId, MessageId storageId, + GroupId groupId, State state, ContactId contactId, GroupId forumId, + String forumName, byte[] forumSalt) { + + super(sessionId, storageId, groupId, contactId, forumId, forumName, + forumSalt); + this.state = state; + } + + public BdfDictionary toBdfDictionary() { + BdfDictionary d = super.toBdfDictionary(); + d.put(STATE, getState().getValue()); + d.put(IS_SHARER, true); + return d; + } + + public void setState(State state) { + this.state = state; + } + + public State getState() { + return state; + } + + public enum State { + ERROR(0), + PREPARE_INVITATION(1) { + @Override + public State next(Action a) { + if (a == LOCAL_INVITATION) return AWAIT_RESPONSE; + return ERROR; + } + }, + AWAIT_RESPONSE(2) { + @Override + public State next(Action a) { + if (a == REMOTE_ACCEPT || a == REMOTE_DECLINE) return FINISHED; + if (a == LOCAL_LEAVE) return LEFT; + return ERROR; + } + }, + FINISHED(3) { + @Override + public State next(Action a) { + if (a == LOCAL_LEAVE || a == REMOTE_LEAVE) return LEFT; + return FINISHED; + } + }, + LEFT(4) { + @Override + public State next(Action a) { + if (a == LOCAL_LEAVE) return ERROR; + return LEFT; + } + }; + + private final int value; + + State(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public static State fromValue(int value) { + for (State s : values()) { + if (s.value == value) return s; + } + throw new IllegalArgumentException(); + } + + public State next(Action a) { + return this; + } + } + + public enum Action { + LOCAL_INVITATION, + LOCAL_LEAVE, + LOCAL_ABORT, + REMOTE_ACCEPT, + REMOTE_DECLINE, + REMOTE_LEAVE, + REMOTE_ABORT; + + public static Action getLocal(long type) { + if (type == SHARE_MSG_TYPE_INVITATION) return LOCAL_INVITATION; + if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; + if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; + return null; + } + + public static Action getRemote(long type) { + if (type == SHARE_MSG_TYPE_ACCEPT) return REMOTE_ACCEPT; + if (type == SHARE_MSG_TYPE_DECLINE) return REMOTE_DECLINE; + if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE; + if (type == SHARE_MSG_TYPE_ABORT) return REMOTE_ABORT; + return null; + } + } + +} \ No newline at end of file From 9532a60f4337457f2ffb3db21f4f488fb8d88bcc Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 12 May 2016 11:51:17 -0300 Subject: [PATCH 2/3] Use dedicated Enum for protocol Actions --- .../forum/ForumSharingManagerImpl.java | 19 +++++++++---------- .../org/briarproject/forum/InviteeEngine.java | 6 ++---- .../forum/InviteeSessionState.java | 10 ---------- .../org/briarproject/forum/SharerEngine.java | 11 ++++------- .../forum/SharerSessionState.java | 17 +++++++++-------- 5 files changed, 24 insertions(+), 39 deletions(-) diff --git a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java index 74e977ac3..1031f3c10 100644 --- a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java @@ -260,17 +260,15 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook SharerSessionState localState = initializeSharerState(txn, f, contactId); - // define action - BdfDictionary localAction = new BdfDictionary(); - localAction.put(TYPE, SHARE_MSG_TYPE_INVITATION); + // add invitation message to local state to be available for engine if (!StringUtils.isNullOrEmpty(msg)) { - localAction.put(INVITATION_MSG, msg); + localState.setMessage(msg); } // start engine and process its state update SharerEngine engine = new SharerEngine(); processSharerStateUpdate(txn, null, - engine.onLocalAction(localState, localAction)); + engine.onLocalAction(localState, Action.LOCAL_INVITATION)); txn.setComplete(); } catch (FormatException e) { @@ -290,11 +288,11 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook InviteeSessionState localState = getSessionStateForResponse(txn, f); // define action - BdfDictionary localAction = new BdfDictionary(); + InviteeSessionState.Action localAction; if (accept) { - localAction.put(TYPE, SHARE_MSG_TYPE_ACCEPT); + localAction = InviteeSessionState.Action.LOCAL_ACCEPT; } else { - localAction.put(TYPE, SHARE_MSG_TYPE_DECLINE); + localAction = InviteeSessionState.Action.LOCAL_DECLINE; } // start engine and process its state update @@ -812,13 +810,14 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook throws DbException, FormatException { ForumSharingSessionState state = getSessionStateForLeaving(txn, f, c); - BdfDictionary action = new BdfDictionary(); - action.put(TYPE, SHARE_MSG_TYPE_LEAVE); if (state instanceof SharerSessionState) { + Action action = Action.LOCAL_LEAVE; SharerEngine engine = new SharerEngine(); processSharerStateUpdate(txn, null, engine.onLocalAction((SharerSessionState) state, action)); } else { + InviteeSessionState.Action action = + InviteeSessionState.Action.LOCAL_LEAVE; InviteeEngine engine = new InviteeEngine(forumFactory); processInviteeStateUpdate(txn, null, engine.onLocalAction((InviteeSessionState) state, action)); diff --git a/briar-core/src/org/briarproject/forum/InviteeEngine.java b/briar-core/src/org/briarproject/forum/InviteeEngine.java index 81d4cf766..3a18581a8 100644 --- a/briar-core/src/org/briarproject/forum/InviteeEngine.java +++ b/briar-core/src/org/briarproject/forum/InviteeEngine.java @@ -42,7 +42,7 @@ import static org.briarproject.forum.InviteeSessionState.State.FINISHED; import static org.briarproject.forum.InviteeSessionState.State.LEFT; public class InviteeEngine - implements ProtocolEngine { + implements ProtocolEngine { private final ForumFactory forumFactory; private static final Logger LOG = @@ -54,12 +54,10 @@ public class InviteeEngine @Override public StateUpdate onLocalAction( - InviteeSessionState localState, BdfDictionary localAction) { + InviteeSessionState localState, Action action) { try { State currentState = localState.getState(); - long type = localAction.getLong(TYPE); - Action action = Action.getLocal(type); State nextState = currentState.next(action); localState.setState(nextState); diff --git a/briar-core/src/org/briarproject/forum/InviteeSessionState.java b/briar-core/src/org/briarproject/forum/InviteeSessionState.java index cc4e1c404..68b397bc7 100644 --- a/briar-core/src/org/briarproject/forum/InviteeSessionState.java +++ b/briar-core/src/org/briarproject/forum/InviteeSessionState.java @@ -8,8 +8,6 @@ import org.briarproject.api.sync.MessageId; import static org.briarproject.api.forum.ForumConstants.IS_SHARER; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; import static org.briarproject.api.forum.ForumConstants.STATE; @@ -111,14 +109,6 @@ public class InviteeSessionState extends ForumSharingSessionState { REMOTE_LEAVE, REMOTE_ABORT; - public static Action getLocal(long type) { - if (type == SHARE_MSG_TYPE_ACCEPT) return LOCAL_ACCEPT; - if (type == SHARE_MSG_TYPE_DECLINE) return LOCAL_DECLINE; - if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; - return null; - } - public static Action getRemote(long type) { if (type == SHARE_MSG_TYPE_INVITATION) return REMOTE_INVITATION; if (type == SHARE_MSG_TYPE_LEAVE) return REMOTE_LEAVE; diff --git a/briar-core/src/org/briarproject/forum/SharerEngine.java b/briar-core/src/org/briarproject/forum/SharerEngine.java index 3e81470ae..a60437c5e 100644 --- a/briar-core/src/org/briarproject/forum/SharerEngine.java +++ b/briar-core/src/org/briarproject/forum/SharerEngine.java @@ -42,19 +42,17 @@ import static org.briarproject.forum.SharerSessionState.State.FINISHED; import static org.briarproject.forum.SharerSessionState.State.LEFT; public class SharerEngine - implements ProtocolEngine { + implements ProtocolEngine { private static final Logger LOG = Logger.getLogger(SharerEngine.class.getName()); @Override public StateUpdate onLocalAction( - SharerSessionState localState, BdfDictionary localAction) { + SharerSessionState localState, Action action) { try { State currentState = localState.getState(); - long type = localAction.getLong(TYPE); - Action action = Action.getLocal(type); State nextState = currentState.next(action); localState.setState(nextState); @@ -79,9 +77,8 @@ public class SharerEngine msg.put(GROUP_ID, localState.getGroupId()); msg.put(FORUM_NAME, localState.getForumName()); msg.put(FORUM_SALT, localState.getForumSalt()); - if (localAction.containsKey(INVITATION_MSG)) { - msg.put(INVITATION_MSG, - localAction.getString(INVITATION_MSG)); + if (localState.getMessage() != null) { + msg.put(INVITATION_MSG, localState.getMessage()); } messages = Collections.singletonList(msg); logLocalAction(currentState, nextState, msg); diff --git a/briar-core/src/org/briarproject/forum/SharerSessionState.java b/briar-core/src/org/briarproject/forum/SharerSessionState.java index b438c6734..665364853 100644 --- a/briar-core/src/org/briarproject/forum/SharerSessionState.java +++ b/briar-core/src/org/briarproject/forum/SharerSessionState.java @@ -10,7 +10,6 @@ import static org.briarproject.api.forum.ForumConstants.IS_SHARER; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; import static org.briarproject.api.forum.ForumConstants.STATE; import static org.briarproject.forum.SharerSessionState.Action.LOCAL_INVITATION; @@ -23,6 +22,7 @@ import static org.briarproject.forum.SharerSessionState.Action.REMOTE_LEAVE; public class SharerSessionState extends ForumSharingSessionState { private State state; + private String msg = null; public SharerSessionState(SessionId sessionId, MessageId storageId, GroupId groupId, State state, ContactId contactId, GroupId forumId, @@ -48,6 +48,14 @@ public class SharerSessionState extends ForumSharingSessionState { return state; } + public void setMessage(String msg) { + this.msg = msg; + } + + public String getMessage() { + return this.msg; + } + public enum State { ERROR(0), PREPARE_INVITATION(1) { @@ -111,13 +119,6 @@ public class SharerSessionState extends ForumSharingSessionState { REMOTE_LEAVE, REMOTE_ABORT; - public static Action getLocal(long type) { - if (type == SHARE_MSG_TYPE_INVITATION) return LOCAL_INVITATION; - if (type == SHARE_MSG_TYPE_LEAVE) return LOCAL_LEAVE; - if (type == SHARE_MSG_TYPE_ABORT) return LOCAL_ABORT; - return null; - } - public static Action getRemote(long type) { if (type == SHARE_MSG_TYPE_ACCEPT) return REMOTE_ACCEPT; if (type == SHARE_MSG_TYPE_DECLINE) return REMOTE_DECLINE; From bd01c3732e204b7a791107db6deb4cd801ae6aae Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Thu, 12 May 2016 13:48:32 -0300 Subject: [PATCH 3/3] Also use dedicated classes to represent messages instead of BdfDictionary --- .../api/forum/ForumSharingMessage.java | 166 ++++++++++++++++++ .../forum/ForumSharingManagerImpl.java | 129 ++++++-------- .../forum/ForumSharingValidator.java | 1 - .../org/briarproject/forum/InviteeEngine.java | 116 ++++++------ .../org/briarproject/forum/SharerEngine.java | 123 ++++++------- 5 files changed, 314 insertions(+), 221 deletions(-) create mode 100644 briar-api/src/org/briarproject/api/forum/ForumSharingMessage.java diff --git a/briar-api/src/org/briarproject/api/forum/ForumSharingMessage.java b/briar-api/src/org/briarproject/api/forum/ForumSharingMessage.java new file mode 100644 index 000000000..79a43ad66 --- /dev/null +++ b/briar-api/src/org/briarproject/api/forum/ForumSharingMessage.java @@ -0,0 +1,166 @@ +package org.briarproject.api.forum; + +import org.briarproject.api.FormatException; +import org.briarproject.api.clients.SessionId; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.data.BdfEntry; +import org.briarproject.api.data.BdfList; +import org.briarproject.api.sync.GroupId; + +import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; +import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; +import static org.briarproject.api.forum.ForumConstants.GROUP_ID; +import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG; +import static org.briarproject.api.forum.ForumConstants.SESSION_ID; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; +import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; +import static org.briarproject.api.forum.ForumConstants.TYPE; + +public interface ForumSharingMessage { + + abstract class BaseMessage { + private final GroupId groupId; + private final SessionId sessionId; + + public BaseMessage(GroupId groupId, SessionId sessionId) { + + this.groupId = groupId; + this.sessionId = sessionId; + } + + public BdfList toBdfList() { + return BdfList.of(getType(), getSessionId()); + } + + public abstract BdfDictionary toBdfDictionary(); + + protected BdfDictionary toBdfDictionaryHelper() { + return BdfDictionary.of( + new BdfEntry(TYPE, getType()), + new BdfEntry(GROUP_ID, groupId), + new BdfEntry(SESSION_ID, sessionId) + ); + } + + public static BaseMessage from(GroupId groupId, BdfDictionary d) + throws FormatException { + + long type = d.getLong(TYPE); + + if (type == SHARE_MSG_TYPE_INVITATION) + return Invitation.from(groupId, d); + else + return SimpleMessage.from(type, groupId, d); + } + + public abstract long getType(); + + public GroupId getGroupId() { + return groupId; + } + + public SessionId getSessionId() { + return sessionId; + } + } + + class Invitation extends BaseMessage { + + private final String forumName; + private final byte[] forumSalt; + private final String message; + + public Invitation(GroupId groupId, SessionId sessionId, + String forumName, byte[] forumSalt, String message) { + + super(groupId, sessionId); + + this.forumName = forumName; + this.forumSalt = forumSalt; + this.message = message; + } + + @Override + public long getType() { + return SHARE_MSG_TYPE_INVITATION; + } + + @Override + public BdfList toBdfList() { + BdfList list = super.toBdfList(); + list.add(forumName); + list.add(forumSalt); + if (message != null) list.add(message); + return list; + } + + @Override + public BdfDictionary toBdfDictionary() { + BdfDictionary d = toBdfDictionaryHelper(); + d.put(FORUM_NAME, forumName); + d.put(FORUM_SALT, forumSalt); + if (message != null) d.put(INVITATION_MSG, message); + return d; + } + + public static Invitation from(GroupId groupId, BdfDictionary d) + throws FormatException { + + SessionId sessionId = new SessionId(d.getRaw(SESSION_ID)); + String forumName = d.getString(FORUM_NAME); + byte[] forumSalt = d.getRaw(FORUM_SALT); + String message = d.getOptionalString(INVITATION_MSG); + + return new Invitation(groupId, sessionId, forumName, forumSalt, + message); + } + + public String getForumName() { + return forumName; + } + + public byte[] getForumSalt() { + return forumSalt; + } + + public String getMessage() { + return message; + } + } + + class SimpleMessage extends BaseMessage { + + private final long type; + + public SimpleMessage(long type, GroupId groupId, SessionId sessionId) { + super(groupId, sessionId); + this.type = type; + } + + @Override + public long getType() { + return type; + } + + @Override + public BdfDictionary toBdfDictionary() { + return toBdfDictionaryHelper(); + } + + public static SimpleMessage from(long type, GroupId groupId, + BdfDictionary d) throws FormatException { + + if (type != SHARE_MSG_TYPE_ACCEPT && + type != SHARE_MSG_TYPE_DECLINE && + type != SHARE_MSG_TYPE_LEAVE && + type != SHARE_MSG_TYPE_ABORT) throw new FormatException(); + + SessionId sessionId = new SessionId(d.getRaw(SESSION_ID)); + return new SimpleMessage(type, groupId, sessionId); + } + } + +} diff --git a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java index 1031f3c10..cbeb56d60 100644 --- a/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java +++ b/briar-core/src/org/briarproject/forum/ForumSharingManagerImpl.java @@ -55,11 +55,7 @@ import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.api.clients.ProtocolEngine.StateUpdate; import static org.briarproject.api.forum.ForumConstants.CONTACT_ID; -import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; -import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; import static org.briarproject.api.forum.ForumConstants.FORUM_SALT_LENGTH; -import static org.briarproject.api.forum.ForumConstants.GROUP_ID; -import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG; import static org.briarproject.api.forum.ForumConstants.IS_SHARER; import static org.briarproject.api.forum.ForumConstants.LOCAL; import static org.briarproject.api.forum.ForumConstants.READ; @@ -83,6 +79,8 @@ import static org.briarproject.api.forum.ForumConstants.TIME; import static org.briarproject.api.forum.ForumConstants.TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TYPE; import static org.briarproject.api.forum.ForumManager.RemoveForumHook; +import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage; +import static org.briarproject.api.forum.ForumSharingMessage.Invitation; import static org.briarproject.forum.ForumSharingSessionState.fromBdfDictionary; import static org.briarproject.forum.SharerSessionState.Action; @@ -178,11 +176,12 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook @Override protected void incomingMessage(Transaction txn, Message m, BdfList body, - BdfDictionary msg) throws DbException, FormatException { + BdfDictionary d) throws DbException, FormatException { - SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID)); - long type = msg.getLong(TYPE); - if (type == SHARE_MSG_TYPE_INVITATION) { + BaseMessage msg = BaseMessage.from(m.getGroupId(), d); + SessionId sessionId = msg.getSessionId(); + + if (msg.getType() == SHARE_MSG_TYPE_INVITATION) { // we are an invitee who just received a new invitation boolean stateExists = true; try { @@ -197,8 +196,9 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook if (stateExists) throw new FormatException(); // check if forum can be shared - Forum f = forumFactory.createForum(msg.getString(FORUM_NAME), - msg.getRaw(FORUM_SALT)); + Invitation invitation = (Invitation) msg; + Forum f = forumFactory.createForum(invitation.getForumName(), + invitation.getForumSalt()); ContactId contactId = getContactId(txn, m.getGroupId()); Contact contact = db.getContact(txn, contactId); if (!canBeShared(txn, f.getId(), contact)) @@ -206,7 +206,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook // initialize state and process invitation InviteeSessionState state = - initializeInviteeState(txn, contactId, msg); + initializeInviteeState(txn, contactId, invitation); InviteeEngine engine = new InviteeEngine(forumFactory); processInviteeStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); @@ -214,15 +214,15 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); deleteMessage(txn, m.getId()); } - } else if (type == SHARE_MSG_TYPE_ACCEPT || - type == SHARE_MSG_TYPE_DECLINE) { + } else if (msg.getType() == SHARE_MSG_TYPE_ACCEPT || + msg.getType() == SHARE_MSG_TYPE_DECLINE) { // we are a sharer who just received a response SharerSessionState state = getSessionStateForSharer(txn, sessionId); SharerEngine engine = new SharerEngine(); processSharerStateUpdate(txn, m.getId(), engine.onMessageReceived(state, msg)); - } else if (type == SHARE_MSG_TYPE_LEAVE || - type == SHARE_MSG_TYPE_ABORT) { + } else if (msg.getType() == SHARE_MSG_TYPE_LEAVE || + msg.getType() == SHARE_MSG_TYPE_ABORT) { // we don't know who we are, so figure it out ForumSharingSessionState s = getSessionState(txn, sessionId, true); if (s instanceof SharerSessionState) { @@ -322,34 +322,33 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook Map map = clientHelper .getMessageMetadataAsDictionary(txn, group.getId()); for (Map.Entry m : map.entrySet()) { - BdfDictionary msg = m.getValue(); + BdfDictionary d = m.getValue(); try { - if (msg.getLong(TYPE) != SHARE_MSG_TYPE_INVITATION) + if (d.getLong(TYPE) != SHARE_MSG_TYPE_INVITATION) continue; + Invitation msg = Invitation.from(group.getId(), d); MessageStatus status = db.getMessageStatus(txn, contactId, m.getKey()); - SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID)); - String name = msg.getString(FORUM_NAME); - String message = msg.getOptionalString(INVITATION_MSG); - long time = msg.getLong(TIME); - boolean local = msg.getBoolean(LOCAL); - boolean read = msg.getBoolean(READ, false); + 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 forum is still available ForumSharingSessionState s = - getSessionState(txn, sessionId, true); + getSessionState(txn, msg.getSessionId(), true); if (!(s instanceof InviteeSessionState)) continue; available = ((InviteeSessionState) s).getState() == InviteeSessionState.State.AWAIT_LOCAL_RESPONSE; } ForumInvitationMessage im = - new ForumInvitationMessage(m.getKey(), sessionId, - contactId, name, message, available, time, - local, status.isSent(), status.isSeen(), - read); + new ForumInvitationMessage(m.getKey(), + msg.getSessionId(), contactId, + msg.getForumName(), msg.getMessage(), + available, time, local, status.isSent(), + status.isSeen(), read); list.add(im); } catch (FormatException e) { if (LOG.isLoggable(WARNING)) @@ -508,13 +507,13 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } private InviteeSessionState initializeInviteeState(Transaction txn, - ContactId contactId, BdfDictionary msg) + ContactId contactId, Invitation msg) throws FormatException, DbException { Contact c = db.getContact(txn, contactId); Group group = getContactGroup(c); - String name = msg.getString(FORUM_NAME); - byte[] salt = msg.getRaw(FORUM_SALT); + String name = msg.getForumName(); + byte[] salt = msg.getForumSalt(); Forum f = forumFactory.createForum(name, salt); // create local message to keep engine state @@ -524,11 +523,10 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook Message m = clientHelper.createMessage(localGroup.getId(), now, BdfList.of(mSalt)); - SessionId sessionId = new SessionId(msg.getRaw(SESSION_ID)); - - InviteeSessionState s = new InviteeSessionState(sessionId, m.getId(), - group.getId(), InviteeSessionState.State.AWAIT_INVITATION, - contactId, f.getId(), f.getName(), f.getSalt()); + InviteeSessionState s = new InviteeSessionState(msg.getSessionId(), + m.getId(), group.getId(), + InviteeSessionState.State.AWAIT_INVITATION, contactId, + f.getId(), f.getName(), f.getSalt()); // save local state to database BdfDictionary d = s.toBdfDictionary(); @@ -646,7 +644,7 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } private void processStateUpdate(Transaction txn, MessageId messageId, - StateUpdate result) + StateUpdate result) throws DbException, FormatException { // perform actions based on new local state @@ -658,8 +656,8 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook result.localState.toBdfDictionary()); // send messages - for (BdfDictionary d : result.toSend) { - sendMessage(txn, d); + for (BaseMessage msg : result.toSend) { + sendMessage(txn, msg); } // broadcast events @@ -678,11 +676,11 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } private void processSharerStateUpdate(Transaction txn, MessageId messageId, - StateUpdate result) + StateUpdate result) throws DbException, FormatException { - StateUpdate r = - new StateUpdate( + StateUpdate r = + new StateUpdate( result.deleteMessage, result.deleteState, result.localState, result.toSend, result.toBroadcast); @@ -690,11 +688,11 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } private void processInviteeStateUpdate(Transaction txn, MessageId messageId, - StateUpdate result) + StateUpdate result) throws DbException, FormatException { - StateUpdate r = - new StateUpdate( + StateUpdate r = + new StateUpdate( result.deleteMessage, result.deleteState, result.localState, result.toSend, result.toBroadcast); @@ -751,50 +749,23 @@ class ForumSharingManagerImpl extends BdfIncomingMessageHook } } - private void sendMessage(Transaction txn, BdfDictionary m) + private void sendMessage(Transaction txn, BaseMessage m) throws FormatException, DbException { - BdfList list = encodeMessage(m); - byte[] body = clientHelper.toByteArray(list); - GroupId groupId = new GroupId(m.getRaw(GROUP_ID)); - Group group = db.getGroup(txn, groupId); + byte[] body = clientHelper.toByteArray(m.toBdfList()); + Group group = db.getGroup(txn, m.getGroupId()); long timestamp = clock.currentTimeMillis(); // add message itself as metadata - m.put(LOCAL, true); - m.put(TIME, timestamp); - Metadata meta = metadataEncoder.encode(m); + BdfDictionary d = m.toBdfDictionary(); + d.put(LOCAL, true); + d.put(TIME, timestamp); + Metadata meta = metadataEncoder.encode(d); messageQueueManager .sendMessage(txn, group, timestamp, body, meta); } - private BdfList encodeMessage(BdfDictionary m) throws FormatException { - long type = m.getLong(TYPE); - - BdfList list; - if (type == SHARE_MSG_TYPE_INVITATION) { - list = BdfList.of(type, - m.getRaw(SESSION_ID), - m.getString(FORUM_NAME), - m.getRaw(FORUM_SALT) - ); - String msg = m.getOptionalString(INVITATION_MSG); - if (msg != null) list.add(msg); - } else if (type == SHARE_MSG_TYPE_ACCEPT) { - list = BdfList.of(type, m.getRaw(SESSION_ID)); - } else if (type == SHARE_MSG_TYPE_DECLINE) { - list = BdfList.of(type, m.getRaw(SESSION_ID)); - } else if (type == SHARE_MSG_TYPE_LEAVE) { - list = BdfList.of(type, m.getRaw(SESSION_ID)); - } else if (type == SHARE_MSG_TYPE_ABORT) { - list = BdfList.of(type, m.getRaw(SESSION_ID)); - } else { - throw new FormatException(); - } - return list; - } - private Group getContactGroup(Contact c) { return privateGroupFactory.createPrivateGroup(CLIENT_ID, c); } diff --git a/briar-core/src/org/briarproject/forum/ForumSharingValidator.java b/briar-core/src/org/briarproject/forum/ForumSharingValidator.java index c204623a2..b16257943 100644 --- a/briar-core/src/org/briarproject/forum/ForumSharingValidator.java +++ b/briar-core/src/org/briarproject/forum/ForumSharingValidator.java @@ -73,7 +73,6 @@ class ForumSharingValidator extends BdfMessageValidator { // Return the metadata d.put(TYPE, type); d.put(SESSION_ID, id); - d.put(GROUP_ID, m.getGroupId()); d.put(LOCAL, false); d.put(TIME, m.getTimestamp()); return d; diff --git a/briar-core/src/org/briarproject/forum/InviteeEngine.java b/briar-core/src/org/briarproject/forum/InviteeEngine.java index 3a18581a8..c7c9ff622 100644 --- a/briar-core/src/org/briarproject/forum/InviteeEngine.java +++ b/briar-core/src/org/briarproject/forum/InviteeEngine.java @@ -3,22 +3,17 @@ package org.briarproject.forum; import org.briarproject.api.FormatException; import org.briarproject.api.clients.ProtocolEngine; import org.briarproject.api.contact.ContactId; -import org.briarproject.api.data.BdfDictionary; -import org.briarproject.api.data.BdfEntry; import org.briarproject.api.event.Event; import org.briarproject.api.event.ForumInvitationReceivedEvent; import org.briarproject.api.forum.Forum; import org.briarproject.api.forum.ForumFactory; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.forum.ForumConstants.GROUP_ID; -import static org.briarproject.api.forum.ForumConstants.SESSION_ID; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; @@ -28,7 +23,8 @@ import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_S import static org.briarproject.api.forum.ForumConstants.TASK_ADD_SHARED_FORUM; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US; import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_WITH_US; -import static org.briarproject.api.forum.ForumConstants.TYPE; +import static org.briarproject.api.forum.ForumSharingMessage.SimpleMessage; +import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage; import static org.briarproject.forum.InviteeSessionState.Action; import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ABORT; import static org.briarproject.forum.InviteeSessionState.Action.LOCAL_ACCEPT; @@ -42,7 +38,7 @@ import static org.briarproject.forum.InviteeSessionState.State.FINISHED; import static org.briarproject.forum.InviteeSessionState.State.LEFT; public class InviteeEngine - implements ProtocolEngine { + implements ProtocolEngine { private final ForumFactory forumFactory; private static final Logger LOG = @@ -53,7 +49,7 @@ public class InviteeEngine } @Override - public StateUpdate onLocalAction( + public StateUpdate onLocalAction( InviteeSessionState localState, Action action) { try { @@ -72,37 +68,34 @@ public class InviteeEngine } return noUpdate(localState, true); } - List messages; + List messages; List events = Collections.emptyList(); if (action == LOCAL_ACCEPT || action == LOCAL_DECLINE) { - BdfDictionary msg = BdfDictionary.of( - new BdfEntry(SESSION_ID, localState.getSessionId()), - new BdfEntry(GROUP_ID, localState.getGroupId()) - ); + BaseMessage msg; if (action == LOCAL_ACCEPT) { localState.setTask(TASK_ADD_SHARED_FORUM); - msg.put(TYPE, SHARE_MSG_TYPE_ACCEPT); + msg = new SimpleMessage(SHARE_MSG_TYPE_ACCEPT, + localState.getGroupId(), localState.getSessionId()); } else { localState.setTask( TASK_REMOVE_FORUM_FROM_LIST_SHARED_WITH_US); - msg.put(TYPE, SHARE_MSG_TYPE_DECLINE); + msg = new SimpleMessage(SHARE_MSG_TYPE_DECLINE, + localState.getGroupId(), localState.getSessionId()); } messages = Collections.singletonList(msg); logLocalAction(currentState, localState, msg); } else if (action == LOCAL_LEAVE) { - BdfDictionary msg = new BdfDictionary(); - msg.put(TYPE, SHARE_MSG_TYPE_LEAVE); - msg.put(SESSION_ID, localState.getSessionId()); - msg.put(GROUP_ID, localState.getGroupId()); + BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE, + localState.getGroupId(), localState.getSessionId()); messages = Collections.singletonList(msg); logLocalAction(currentState, localState, msg); } else { throw new IllegalArgumentException("Unknown Local Action"); } - return new StateUpdate(false, + return new StateUpdate(false, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -110,17 +103,16 @@ public class InviteeEngine } @Override - public StateUpdate onMessageReceived( - InviteeSessionState localState, BdfDictionary msg) { + public StateUpdate onMessageReceived( + InviteeSessionState localState, BaseMessage msg) { try { State currentState = localState.getState(); - long type = msg.getLong(TYPE); - Action action = Action.getRemote(type); + Action action = Action.getRemote(msg.getType()); State nextState = currentState.next(action); localState.setState(nextState); - logMessageReceived(currentState, nextState, type, msg); + logMessageReceived(currentState, nextState, msg.getType(), msg); if (nextState == ERROR) { if (currentState != ERROR) { @@ -130,7 +122,7 @@ public class InviteeEngine } } - List messages = Collections.emptyList(); + List messages = Collections.emptyList(); List events = Collections.emptyList(); boolean deleteMsg = false; @@ -164,7 +156,7 @@ public class InviteeEngine else { throw new IllegalArgumentException("Bad state"); } - return new StateUpdate(deleteMsg, + return new StateUpdate(deleteMsg, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -172,50 +164,42 @@ public class InviteeEngine } private void logLocalAction(State state, - InviteeSessionState localState, BdfDictionary msg) { + InviteeSessionState localState, BaseMessage msg) { if (!LOG.isLoggable(INFO)) return; String a = "response"; - if (msg.getLong(TYPE, -1L) == SHARE_MSG_TYPE_LEAVE) a = "leave"; + if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave"; - try { - LOG.info("Sending " + a + " in state " + state.name() + - " with session ID " + - Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + - Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + localState.getState().name() - ); - } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } + LOG.info("Sending " + a + " in state " + state.name() + + " with session ID " + + msg.getSessionId().hashCode() + " in group " + + msg.getGroupId().hashCode() + ". " + + "Moving on to state " + localState.getState().name() + ); } private void logMessageReceived(State currentState, State nextState, - long type, BdfDictionary msg) { + long type, BaseMessage msg) { if (!LOG.isLoggable(INFO)) return; - try { - String t = "unknown"; - if (type == SHARE_MSG_TYPE_INVITATION) t = "INVITE"; - else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE"; - else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT"; + String t = "unknown"; + if (type == SHARE_MSG_TYPE_INVITATION) t = "INVITE"; + else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE"; + else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT"; - LOG.info("Received " + t + " in state " + currentState.name() + - " with session ID " + - Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + - Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + nextState.name() - ); - } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } + LOG.info("Received " + t + " in state " + currentState.name() + + " with session ID " + + msg.getSessionId().hashCode() + " in group " + + msg.getGroupId().hashCode() + ". " + + "Moving on to state " + nextState.name() + ); } @Override - public StateUpdate onMessageDelivered( - InviteeSessionState localState, BdfDictionary delivered) { + public StateUpdate onMessageDelivered( + InviteeSessionState localState, BaseMessage delivered) { try { return noUpdate(localState, false); } catch (FormatException e) { @@ -224,7 +208,7 @@ public class InviteeEngine } } - private StateUpdate abortSession( + private StateUpdate abortSession( State currentState, InviteeSessionState localState) throws FormatException { @@ -233,25 +217,23 @@ public class InviteeEngine localState.getSessionId().hashCode() + " in state " + currentState.name()); } - localState.setState(ERROR); - BdfDictionary msg = new BdfDictionary(); - msg.put(TYPE, SHARE_MSG_TYPE_ABORT); - msg.put(SESSION_ID, localState.getSessionId()); - msg.put(GROUP_ID, localState.getGroupId()); - List messages = Collections.singletonList(msg); + BaseMessage msg = + new SimpleMessage(SHARE_MSG_TYPE_ABORT, localState.getGroupId(), + localState.getSessionId()); + List messages = Collections.singletonList(msg); List events = Collections.emptyList(); - return new StateUpdate(false, false, + return new StateUpdate(false, false, localState, messages, events); } - private StateUpdate noUpdate( + private StateUpdate noUpdate( InviteeSessionState localState, boolean delete) throws FormatException { - return new StateUpdate(delete, false, - localState, Collections.emptyList(), + return new StateUpdate(delete, false, + localState, Collections.emptyList(), Collections.emptyList()); } } diff --git a/briar-core/src/org/briarproject/forum/SharerEngine.java b/briar-core/src/org/briarproject/forum/SharerEngine.java index a60437c5e..4a142c039 100644 --- a/briar-core/src/org/briarproject/forum/SharerEngine.java +++ b/briar-core/src/org/briarproject/forum/SharerEngine.java @@ -3,33 +3,27 @@ package org.briarproject.forum; import org.briarproject.api.FormatException; import org.briarproject.api.clients.ProtocolEngine; import org.briarproject.api.contact.ContactId; -import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.event.Event; import org.briarproject.api.event.ForumInvitationResponseReceivedEvent; -import static org.briarproject.forum.SharerSessionState.Action; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.logging.Logger; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; -import static org.briarproject.api.forum.ForumConstants.FORUM_NAME; -import static org.briarproject.api.forum.ForumConstants.FORUM_SALT; -import static org.briarproject.api.forum.ForumConstants.GROUP_ID; -import static org.briarproject.api.forum.ForumConstants.INVITATION_MSG; -import static org.briarproject.api.forum.ForumConstants.SESSION_ID; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ABORT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_ACCEPT; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_DECLINE; -import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_INVITATION; import static org.briarproject.api.forum.ForumConstants.SHARE_MSG_TYPE_LEAVE; import static org.briarproject.api.forum.ForumConstants.TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_REMOVE_FORUM_FROM_LIST_TO_BE_SHARED_BY_US; import static org.briarproject.api.forum.ForumConstants.TASK_SHARE_FORUM; import static org.briarproject.api.forum.ForumConstants.TASK_UNSHARE_FORUM_SHARED_BY_US; -import static org.briarproject.api.forum.ForumConstants.TYPE; +import static org.briarproject.api.forum.ForumSharingMessage.BaseMessage; +import static org.briarproject.api.forum.ForumSharingMessage.Invitation; +import static org.briarproject.api.forum.ForumSharingMessage.SimpleMessage; +import static org.briarproject.forum.SharerSessionState.Action; import static org.briarproject.forum.SharerSessionState.Action.LOCAL_ABORT; import static org.briarproject.forum.SharerSessionState.Action.LOCAL_INVITATION; import static org.briarproject.forum.SharerSessionState.Action.LOCAL_LEAVE; @@ -42,13 +36,13 @@ import static org.briarproject.forum.SharerSessionState.State.FINISHED; import static org.briarproject.forum.SharerSessionState.State.LEFT; public class SharerEngine - implements ProtocolEngine { + implements ProtocolEngine { private static final Logger LOG = Logger.getLogger(SharerEngine.class.getName()); @Override - public StateUpdate onLocalAction( + public StateUpdate onLocalAction( SharerSessionState localState, Action action) { try { @@ -67,19 +61,13 @@ public class SharerEngine } return noUpdate(localState, true); } - List messages; + List messages; List events = Collections.emptyList(); if (action == LOCAL_INVITATION) { - BdfDictionary msg = new BdfDictionary(); - msg.put(TYPE, SHARE_MSG_TYPE_INVITATION); - msg.put(SESSION_ID, localState.getSessionId()); - msg.put(GROUP_ID, localState.getGroupId()); - msg.put(FORUM_NAME, localState.getForumName()); - msg.put(FORUM_SALT, localState.getForumSalt()); - if (localState.getMessage() != null) { - msg.put(INVITATION_MSG, localState.getMessage()); - } + BaseMessage msg = new Invitation(localState.getGroupId(), + localState.getSessionId(), localState.getForumName(), + localState.getForumSalt(), localState.getMessage()); messages = Collections.singletonList(msg); logLocalAction(currentState, nextState, msg); @@ -87,17 +75,15 @@ public class SharerEngine localState.setTask(TASK_ADD_FORUM_TO_LIST_TO_BE_SHARED_BY_US); } else if (action == LOCAL_LEAVE) { - BdfDictionary msg = new BdfDictionary(); - msg.put(TYPE, SHARE_MSG_TYPE_LEAVE); - msg.put(SESSION_ID, localState.getSessionId()); - msg.put(GROUP_ID, localState.getGroupId()); + BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_LEAVE, + localState.getGroupId(), localState.getSessionId()); messages = Collections.singletonList(msg); logLocalAction(currentState, nextState, msg); } else { throw new IllegalArgumentException("Unknown Local Action"); } - return new StateUpdate(false, + return new StateUpdate(false, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -105,17 +91,16 @@ public class SharerEngine } @Override - public StateUpdate onMessageReceived( - SharerSessionState localState, BdfDictionary msg) { + public StateUpdate onMessageReceived( + SharerSessionState localState, BaseMessage msg) { try { State currentState = localState.getState(); - long type = msg.getLong(TYPE); - Action action = Action.getRemote(type); + Action action = Action.getRemote(msg.getType()); State nextState = currentState.next(action); localState.setState(nextState); - logMessageReceived(currentState, nextState, type, msg); + logMessageReceived(currentState, nextState, msg.getType(), msg); if (nextState == ERROR) { if (currentState != ERROR) { @@ -124,7 +109,7 @@ public class SharerEngine return noUpdate(localState, true); } } - List messages = Collections.emptyList(); + List messages = Collections.emptyList(); List events = Collections.emptyList(); boolean deleteMsg = false; @@ -157,7 +142,7 @@ public class SharerEngine else { throw new IllegalArgumentException("Bad state"); } - return new StateUpdate(deleteMsg, + return new StateUpdate(deleteMsg, false, localState, messages, events); } catch (FormatException e) { throw new IllegalArgumentException(e); @@ -165,51 +150,43 @@ public class SharerEngine } private void logLocalAction(State currentState, State nextState, - BdfDictionary msg) { + BaseMessage msg) { if (!LOG.isLoggable(INFO)) return; String a = "invitation"; - if (msg.getLong(TYPE, -1L) == SHARE_MSG_TYPE_LEAVE) a = "leave"; + if (msg.getType() == SHARE_MSG_TYPE_LEAVE) a = "leave"; - try { - LOG.info("Sending " + a + " in state " + currentState.name() + - " with session ID " + - Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + - Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + nextState.name() - ); - } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } + LOG.info("Sending " + a + " in state " + currentState.name() + + " with session ID " + + msg.getSessionId().hashCode() + " in group " + + msg.getGroupId().hashCode() + ". " + + "Moving on to state " + nextState.name() + ); } private void logMessageReceived(State currentState, State nextState, - long type, BdfDictionary msg) { + long type, BaseMessage msg) { if (!LOG.isLoggable(INFO)) return; - try { - String t = "unknown"; - if (type == SHARE_MSG_TYPE_ACCEPT) t = "ACCEPT"; - else if (type == SHARE_MSG_TYPE_DECLINE) t = "DECLINE"; - else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE"; - else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT"; + String t = "unknown"; + if (type == SHARE_MSG_TYPE_ACCEPT) t = "ACCEPT"; + else if (type == SHARE_MSG_TYPE_DECLINE) t = "DECLINE"; + else if (type == SHARE_MSG_TYPE_LEAVE) t = "LEAVE"; + else if (type == SHARE_MSG_TYPE_ABORT) t = "ABORT"; - LOG.info("Received " + t + " in state " + currentState.name() + - " with session ID " + - Arrays.hashCode(msg.getRaw(SESSION_ID)) + " in group " + - Arrays.hashCode(msg.getRaw(GROUP_ID)) + ". " + - "Moving on to state " + nextState.name() - ); - } catch (FormatException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } + LOG.info("Received " + t + " in state " + currentState.name() + + " with session ID " + + msg.getSessionId().hashCode() + " in group " + + msg.getGroupId().hashCode() + ". " + + "Moving on to state " + nextState.name() + ); } @Override - public StateUpdate onMessageDelivered( - SharerSessionState localState, BdfDictionary delivered) { + public StateUpdate onMessageDelivered( + SharerSessionState localState, BaseMessage delivered) { try { return noUpdate(localState, false); } catch (FormatException e) { @@ -218,7 +195,7 @@ public class SharerEngine } } - private StateUpdate abortSession( + private StateUpdate abortSession( State currentState, SharerSessionState localState) throws FormatException { @@ -229,24 +206,22 @@ public class SharerEngine } localState.setState(ERROR); - BdfDictionary msg = new BdfDictionary(); - msg.put(TYPE, SHARE_MSG_TYPE_ABORT); - msg.put(SESSION_ID, localState.getSessionId()); - msg.put(GROUP_ID, localState.getGroupId()); - List messages = Collections.singletonList(msg); + BaseMessage msg = new SimpleMessage(SHARE_MSG_TYPE_ABORT, + localState.getGroupId(), localState.getSessionId()); + List messages = Collections.singletonList(msg); List events = Collections.emptyList(); - return new StateUpdate(false, false, + return new StateUpdate(false, false, localState, messages, events); } - private StateUpdate noUpdate( + private StateUpdate noUpdate( SharerSessionState localState, boolean delete) throws FormatException { - return new StateUpdate(delete, false, - localState, Collections.emptyList(), + return new StateUpdate(delete, false, + localState, Collections.emptyList(), Collections.emptyList()); }