summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/isode/stroke/presence/PresenceOracle.java117
-rw-r--r--test/com/isode/stroke/parser/payloadparsers/JingleParserTest.java26
-rw-r--r--test/com/isode/stroke/presence/PresenceOracleTest.java85
3 files changed, 195 insertions, 33 deletions
diff --git a/src/com/isode/stroke/presence/PresenceOracle.java b/src/com/isode/stroke/presence/PresenceOracle.java
index 7ac5b9d..e983d51 100644
--- a/src/com/isode/stroke/presence/PresenceOracle.java
+++ b/src/com/isode/stroke/presence/PresenceOracle.java
@@ -6,8 +6,11 @@ package com.isode.stroke.presence;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.PriorityQueue;
import com.isode.stroke.client.StanzaChannel;
import com.isode.stroke.elements.Presence;
@@ -135,6 +138,120 @@ public class PresenceOracle {
results.addAll(presenceMap.values());
return results;
}
+
+ private static class PresenceAccountCmp implements Comparator<Presence> {
+
+ private static int preferenceFromStatusShow(StatusShow.Type showType) {
+ switch (showType) {
+ case FFC:
+ return 5;
+ case Online:
+ return 4;
+ case DND:
+ return 3;
+ case Away:
+ return 2;
+ case XA:
+ return 1;
+ case None:
+ return 0;
+ }
+ assert(false);
+ return -1;
+ }
+
+ @Override
+ public int compare(Presence a, Presence b) {
+ int aPreference = preferenceFromStatusShow(a.getShow());
+ int bPreference = preferenceFromStatusShow(b.getShow());
+
+ if (aPreference != bPreference) {
+ return (aPreference > bPreference) ? -1 : 1;
+ }
+ if (a.getPriority() != b.getPriority()) {
+ return (a.getPriority() > b.getPriority()) ? -1 : 1;
+ }
+ return -a.getFrom().getResource().compareTo(b.getFrom().getResource());
+ }
+
+ }
+
+ /**
+ * Returns the relevant presence for a list of resource presences.
+ *
+ * It only takes the presence show type into account. Priorities are
+ * ignored as various clients set them to arbitrary values unrelated
+ * to actual end point availability.
+ *
+ * The presences of the resources are group by availablilty and sorted
+ * by show type in the following order:
+ *
+ * -# Online
+ * -# Free for Chat
+ * -# Available
+ * -# Away
+ * -# DND
+ * -# Extended Away
+ * -# Away
+ * -# Offline
+ * -# Unavailable
+ * @param presences List of resource presences. Should not be null.
+ * @return The relevant presence.
+ */
+ public static Presence getActivePresence(Collection<? extends Presence> presences) {
+
+ PriorityQueue<Presence> online = new PriorityQueue<Presence>(presences.size(),new PresenceAccountCmp());
+ PriorityQueue<Presence> away = new PriorityQueue<Presence>(presences.size(),new PresenceAccountCmp());
+ PriorityQueue<Presence> offline = new PriorityQueue<Presence>(presences.size(),new PresenceAccountCmp());
+
+ for (Presence presence : presences) {
+ switch (presence.getShow()) {
+ case Online:
+ online.add(presence);
+ break;
+ case Away:
+ away.add(presence);
+ break;
+ case FFC:
+ online.add(presence);
+ break;
+ case XA:
+ away.add(presence);
+ break;
+ case DND:
+ away.add(presence);
+ break;
+ case None:
+ offline.add(presence);
+ break;
+ }
+ }
+
+ Presence accountPresence = null;
+ if (!online.isEmpty()) {
+ accountPresence = online.peek();
+ }
+ else if (!away.isEmpty()) {
+ accountPresence = away.peek();
+ }
+ else if (!offline.isEmpty()) {
+ accountPresence = offline.peek();
+ }
+ return accountPresence;
+ }
+
+ /**
+ * This considers all online resources of a bare JID and returns
+ * the value returned by {@link #getActivePresence(List)}
+ * when passing this list.
+ * @param jid A bare JID
+ * @return The value returned by {@link #getActivePresence(List)}
+ */
+ public Presence getAccountPresence(JID jid) {
+ Collection<Presence> allPresences = getAllPresence(jid.toBare());
+ Presence accountPresence = getActivePresence(allPresences);
+ return accountPresence;
+ }
public Presence getHighestPriorityPresence(final JID bareJID) {
Map<JID,Presence> presenceMap = entries_.get(bareJID);
diff --git a/test/com/isode/stroke/parser/payloadparsers/JingleParserTest.java b/test/com/isode/stroke/parser/payloadparsers/JingleParserTest.java
index ec7f044..d561222 100644
--- a/test/com/isode/stroke/parser/payloadparsers/JingleParserTest.java
+++ b/test/com/isode/stroke/parser/payloadparsers/JingleParserTest.java
@@ -4,7 +4,7 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,28 +18,27 @@ package com.isode.stroke.parser.payloadparsers;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Vector;
+import java.util.logging.Logger;
+
import org.junit.Test;
-import com.isode.stroke.serializer.payloadserializers.JingleContentPayloadSerializer;
-import com.isode.stroke.elements.JinglePayload;
+
+import com.isode.stroke.base.DateTime;
import com.isode.stroke.elements.JingleContentPayload;
import com.isode.stroke.elements.JingleFileTransferDescription;
import com.isode.stroke.elements.JingleFileTransferFileInfo;
+import com.isode.stroke.elements.JingleFileTransferHash;
import com.isode.stroke.elements.JingleIBBTransportPayload;
+import com.isode.stroke.elements.JinglePayload;
import com.isode.stroke.elements.JingleS5BTransportPayload;
-import com.isode.stroke.elements.JingleFileTransferHash;
-import com.isode.stroke.parser.payloadparsers.PayloadsParserTester;
import com.isode.stroke.eventloop.DummyEventLoop;
import com.isode.stroke.jid.JID;
-import com.isode.stroke.base.DateTime;
-import com.isode.stroke.stringcodecs.Base64;
-import java.util.Vector;
-import java.util.logging.Logger;
-import java.util.logging.Level;
import com.isode.stroke.network.HostAddress;
import com.isode.stroke.network.HostAddressPort;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
+import com.isode.stroke.stringcodecs.Base64;
public class JingleParserTest {
@@ -431,7 +430,6 @@ public class JingleParserTest {
// http://xmpp.org/extensions/xep-0234.html#example-10
@Test
public void testParse_Xep0234_Example10() {
- logger_.setLevel(Level.FINE);
DummyEventLoop eventLoop = new DummyEventLoop();
PayloadsParserTester parser = new PayloadsParserTester(eventLoop);
assertNotNull(parser.parse(
diff --git a/test/com/isode/stroke/presence/PresenceOracleTest.java b/test/com/isode/stroke/presence/PresenceOracleTest.java
index ac82045..9a440e6 100644
--- a/test/com/isode/stroke/presence/PresenceOracleTest.java
+++ b/test/com/isode/stroke/presence/PresenceOracleTest.java
@@ -12,32 +12,24 @@
package com.isode.stroke.presence;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import org.junit.Test;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Vector;
+
import org.junit.Before;
+import org.junit.Test;
-import com.isode.stroke.elements.Presence;
-import com.isode.stroke.elements.Payload;
import com.isode.stroke.client.DummyStanzaChannel;
-import com.isode.stroke.presence.DirectedPresenceSender;
-import com.isode.stroke.presence.StanzaChannelPresenceSender;
-import com.isode.stroke.presence.PayloadAddingPresenceSender;
-import com.isode.stroke.presence.PresenceOracle;
-import com.isode.stroke.presence.SubscriptionManager;
+import com.isode.stroke.elements.Presence;
+import com.isode.stroke.elements.StatusShow;
import com.isode.stroke.jid.JID;
import com.isode.stroke.roster.XMPPRoster;
import com.isode.stroke.roster.XMPPRosterImpl;
-import com.isode.stroke.signals.SignalConnection;
-import com.isode.stroke.signals.Slot2;
-import com.isode.stroke.signals.Slot3;
import com.isode.stroke.signals.Slot1;
-
-import java.util.Collection;
-import java.util.Vector;
+import com.isode.stroke.signals.Slot3;
public class PresenceOracleTest {
@@ -91,6 +83,16 @@ public class PresenceOracleTest {
sentPresence.setFrom(jid);
return sentPresence;
}
+
+ private Presence createPresence(JID jid, int priority, Presence.Type type, StatusShow.Type statusShow) {
+ Presence presence = new Presence();
+ presence.setFrom(jid);
+ presence.setPriority(priority);
+ presence.setType(type);
+ presence.setShow(statusShow);
+ assertEquals(statusShow,presence.getShow());
+ return presence;
+ }
@Before
public void setUp() {
@@ -222,5 +224,50 @@ public class PresenceOracleTest {
stanzaChannel_.setAvailable(true);
assertNull(oracle_.getLastPresence(user1));
- }
-} \ No newline at end of file
+ }
+
+ @Test
+ public void testGetActivePresence() {
+ {
+ List<Presence> presenceList = new ArrayList<Presence>();
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceA"), 10,
+ Presence.Type.Available, StatusShow.Type.Away));
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceB"), 5,
+ Presence.Type.Available, StatusShow.Type.Online));
+
+ assertEquals(StatusShow.Type.Online,PresenceOracle.getActivePresence(presenceList).getShow());
+ }
+
+
+ {
+ List<Presence> presenceList = new ArrayList<Presence>();
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceA"), 10,
+ Presence.Type.Available, StatusShow.Type.Away));
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceB"), 5,
+ Presence.Type.Available, StatusShow.Type.DND));
+
+ assertEquals(StatusShow.Type.DND,PresenceOracle.getActivePresence(presenceList).getShow());
+ }
+
+ {
+ List<Presence> presenceList = new ArrayList<Presence>();
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceA"), 0,
+ Presence.Type.Available, StatusShow.Type.Online));
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceB"), 0,
+ Presence.Type.Available, StatusShow.Type.DND));
+
+ assertEquals(StatusShow.Type.Online,PresenceOracle.getActivePresence(presenceList).getShow());
+ }
+
+ {
+ List<Presence> presenceList = new ArrayList<Presence>();
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceA"), 1,
+ Presence.Type.Available, StatusShow.Type.Online));
+ presenceList.add(createPresence(new JID("alice@wonderland.lit/resourceB"), 0,
+ Presence.Type.Available, StatusShow.Type.Online));
+
+ assertEquals(new JID("alice@wonderland.lit/resourceA"), PresenceOracle.getActivePresence(presenceList).getFrom());
+ }
+ }
+
+}