diff options
Diffstat (limited to 'src/com')
-rw-r--r-- | src/com/isode/stroke/presence/PresenceOracle.java | 117 |
1 files changed, 117 insertions, 0 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); |