diff options
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()); + } + } + +} |