summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/presence/PresenceOracle.java')
-rw-r--r--src/com/isode/stroke/presence/PresenceOracle.java117
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);