summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/whiteboard/WhiteboardSessionManager.java')
-rw-r--r--src/com/isode/stroke/whiteboard/WhiteboardSessionManager.java169
1 files changed, 169 insertions, 0 deletions
diff --git a/src/com/isode/stroke/whiteboard/WhiteboardSessionManager.java b/src/com/isode/stroke/whiteboard/WhiteboardSessionManager.java
new file mode 100644
index 0000000..d797303
--- /dev/null
+++ b/src/com/isode/stroke/whiteboard/WhiteboardSessionManager.java
@@ -0,0 +1,169 @@
+/* Copyright (c) 2016, Isode Limited, London, England.
+ * All rights reserved.
+ *
+ * Acquisition and use of this software and related materials for any
+ * purpose requires a written license agreement from Isode Limited,
+ * or a written license from an organisation licensed by Isode Limited
+ * to grant such a license.
+ *
+ */
+package com.isode.stroke.whiteboard;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.isode.stroke.client.StanzaChannel;
+import com.isode.stroke.disco.EntityCapsProvider;
+import com.isode.stroke.elements.DiscoInfo;
+import com.isode.stroke.elements.Presence;
+import com.isode.stroke.jid.JID;
+import com.isode.stroke.presence.PresenceOracle;
+import com.isode.stroke.queries.IQRouter;
+import com.isode.stroke.signals.Signal1;
+import com.isode.stroke.signals.Slot1;
+
+public class WhiteboardSessionManager {
+
+ private final Map<JID,WhiteboardSession> sessions_ = new HashMap<JID,WhiteboardSession>();
+ private final IQRouter router_;
+ private final StanzaChannel stanzaChannel_;
+ private final PresenceOracle presenceOracle_;
+ private final EntityCapsProvider capsProvider_;
+ private WhiteboardResponder responder;
+
+ public final Signal1<IncomingWhiteboardSession> onSessionRequest =
+ new Signal1<IncomingWhiteboardSession>();
+
+ public WhiteboardSessionManager(IQRouter router, StanzaChannel stanzaChannel,
+ PresenceOracle presenceOracle, EntityCapsProvider capsProvider) {
+ router_ = router;
+ stanzaChannel_ = stanzaChannel;
+ presenceOracle_ = presenceOracle;
+ capsProvider_ = capsProvider;
+ responder = new WhiteboardResponder(this, router_);
+ responder.start();
+ stanzaChannel_.onPresenceReceived.connect(new Slot1<Presence>() {
+
+ @Override
+ public void call(Presence presence) {
+ handlePresenceReceived(presence);
+ }
+
+ });
+ stanzaChannel_.onAvailableChanged.connect(new Slot1<Boolean>() {
+
+ @Override
+ public void call(Boolean p1) {
+ handleAvailableChanged(p1.booleanValue());
+ }
+
+ });
+ }
+
+ // Unlike in C++ we can't put this in a destructor to automatically be called when object is
+ // destroyed. Must be called manually.
+ public void stop() {
+ responder.stop();
+ }
+
+ public WhiteboardSession getSession(JID to) {
+ return sessions_.get(to);
+ }
+
+ public WhiteboardSession requestSession(JID to) {
+ WhiteboardSession session = getSession(to);
+ if (session == null) {
+ OutgoingWhiteboardSession outgoingSession = createOutgoingSession(to);
+ outgoingSession.startSession();
+ return outgoingSession;
+ } else {
+ return session;
+ }
+ }
+
+ private JID getFullJID(JID bareJID) {
+ JID fullReceipientJID = null;
+ int priority = Integer.MIN_VALUE;
+
+ //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
+ List<Presence> presences =
+ new ArrayList<Presence>(presenceOracle_.getAllPresence(bareJID));
+
+ //iterate over them
+ for (Presence pres : presences) {
+ if (pres.getPriority() > priority) {
+ // look up caps from the jid
+ DiscoInfo info = capsProvider_.getCaps(pres.getFrom());
+ if (info != null && info.hasFeature(DiscoInfo.WhiteboardFeature)) {
+ priority = pres.getPriority();
+ fullReceipientJID = pres.getFrom();
+ }
+ }
+ }
+
+ return fullReceipientJID;
+ }
+
+ private OutgoingWhiteboardSession createOutgoingSession(JID to) {
+ JID fullJID = to;
+ if (fullJID.isBare()) {
+ fullJID = getFullJID(fullJID);
+ }
+ OutgoingWhiteboardSession session = new OutgoingWhiteboardSession(fullJID, router_);
+ sessions_.put(fullJID, session);
+ session.onSessionTerminated.connect(new Slot1<JID>() {
+
+ @Override
+ public void call(JID jid) {
+ deleteSessionEntry(jid);
+ }
+
+ });
+ session.onRequestRejected.connect(new Slot1<JID>() {
+
+ @Override
+ public void call(JID jid) {
+ deleteSessionEntry(jid);
+ }
+
+ });
+ return session;
+ }
+
+ public void handleIncomingSession(IncomingWhiteboardSession session) {
+ sessions_.put(session.getTo(), session);
+ session.onSessionTerminated.connect(new Slot1<JID>() {
+
+ @Override
+ public void call(JID jid) {
+ deleteSessionEntry(jid);
+ }
+
+ });
+ onSessionRequest.emit(session);
+ }
+
+ private void handlePresenceReceived(Presence presence) {
+ if (!presence.isAvailable()) {
+ WhiteboardSession session = getSession(presence.getFrom());
+ if (session != null) {
+ session.cancel();
+ }
+ }
+ }
+ private void handleAvailableChanged(boolean available) {
+ if (!available) {
+ Map<JID,WhiteboardSession> sessionsCopy = new HashMap<JID,WhiteboardSession>(sessions_);
+ for (WhiteboardSession session : sessionsCopy.values()) {
+ session.cancel();
+ }
+ }
+ }
+
+ private void deleteSessionEntry(JID contact) {
+ sessions_.remove(contact);
+ }
+
+}