diff options
author | Alan Young <consult.awy@gmail.com> | 2014-11-13 06:42:37 (GMT) |
---|---|---|
committer | Alan Young <consult.awy@gmail.com> | 2015-04-10 06:50:58 (GMT) |
commit | 7d2101b93b6253c3ea15b663f7f3dc385cb21364 (patch) | |
tree | d81338baf0d117e83cdc07f882cbedd9471e834d /src/com/isode/stroke/presence/PresenceOracle.java | |
parent | a20ca7ba40d837abe228462be0aba5d32d6831e3 (diff) | |
download | stroke-7d2101b93b6253c3ea15b663f7f3dc385cb21364.zip stroke-7d2101b93b6253c3ea15b663f7f3dc385cb21364.tar.bz2 |
Checkpoint - A bunch of initial stuff for Android
MemoryStorages, Storages
NickManager, NickResolver
CryptoProvider, Hash, SafeByteArray, JavaCryptoProvider
CapsInfoGenerator, CapsManager, CapsMemoryStorage, CapsProvider,
CapsStorage, CapsInfo
CapsInfoSerializer, CapsInfoParser
ClientDiscoManager, DiscoInfoResponder, EntityCapsManager,
EntityCapsProvider
GetDiscoInfoRequest
ChatState, Idle
Presence, PayloadAddingPresenceSender, PresenceOracle,
SubscriptionManager
StatusSerializer, StatusShowSerializer, StatusParser, StatusShowParser,
Replace, ReplaceParser, ReplaceSerializer
SecurityLabel, SecurityLabelsCatalog, GetSecurityLabelsCatalogRequest
VCard, GetVCardRequest, SetVCardRequest, VCardManager,
VCardMemoryStorage, VCardStorage
RosterMemoryStorage, RosterPushResponder, RosterStorage,
SetRosterRequest
XMPPRoster, XMPPRosterController, XMPPRosterImpl, XMPPRosterItem
GetRosterRequest, SetResponder
Add parsers and serializers for Idle, VCard, PrivateStorage & Stroage.
Add
parser for Subject.
Add impromptu flag to MUCInvitation.
Update copyrights.
Change-Id: I9949f506b70e60b3a64f1dadde8f9b235b322e1d
Diffstat (limited to 'src/com/isode/stroke/presence/PresenceOracle.java')
-rw-r--r-- | src/com/isode/stroke/presence/PresenceOracle.java | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/com/isode/stroke/presence/PresenceOracle.java b/src/com/isode/stroke/presence/PresenceOracle.java new file mode 100644 index 0000000..8d63f59 --- /dev/null +++ b/src/com/isode/stroke/presence/PresenceOracle.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.presence; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import com.isode.stroke.client.StanzaChannel; +import com.isode.stroke.elements.Presence; +import com.isode.stroke.elements.StatusShow; +import com.isode.stroke.jid.JID; +import com.isode.stroke.signals.Signal1; +import com.isode.stroke.signals.SignalConnection; +import com.isode.stroke.signals.Slot1; + +public class PresenceOracle { + private final Map<JID,Map<JID,Presence>> entries_ = new HashMap<JID,Map<JID,Presence>>(); + private final StanzaChannel stanzaChannel_; + private final SignalConnection onPresenceReceivedSignal; + private final SignalConnection onAvailableChangedSignal; + + + public final Signal1<Presence> onPresenceChange = new Signal1<Presence>(); + + public PresenceOracle(StanzaChannel stanzaChannel) { + stanzaChannel_ = stanzaChannel; + onPresenceReceivedSignal = stanzaChannel_.onPresenceReceived.connect(new Slot1<Presence>() { + @Override + public void call(Presence p1) { + handleIncomingPresence(p1); + } + }); + onAvailableChangedSignal = stanzaChannel_.onAvailableChanged.connect(new Slot1<Boolean>() { + @Override + public void call(Boolean p1) { + handleStanzaChannelAvailableChanged(p1); + } + }); + } + + void delete() { + onPresenceReceivedSignal.disconnect(); + onAvailableChangedSignal.disconnect(); + } + + void handleStanzaChannelAvailableChanged(boolean available) { + if (available) { + entries_.clear(); + } + } + + + void handleIncomingPresence(Presence presence) { + JID bareJID = presence.getFrom().toBare(); + if (presence.getType() == Presence.Type.Subscribe) { + } + else { + Presence passedPresence = presence; + if (presence.getType() == Presence.Type.Unsubscribe) { + /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */ + passedPresence = new Presence(); + passedPresence.setType(Presence.Type.Unavailable); + passedPresence.setFrom(bareJID); + passedPresence.setStatus(presence.getStatus()); + } + Map<JID,Presence> jidMap = entries_.get(bareJID); + if (jidMap == null) jidMap = new HashMap<JID,Presence>(); + if (passedPresence.getFrom().isBare() && presence.getType() == Presence.Type.Unavailable) { + /* Have a bare-JID only presence of offline */ + jidMap.clear(); + } else if (passedPresence.getType() == Presence.Type.Available) { + /* Don't have a bare-JID only offline presence once there are available presences */ + jidMap.remove(bareJID); + } + if (passedPresence.getType() == Presence.Type.Unavailable && jidMap.size() > 1) { + jidMap.remove(passedPresence.getFrom()); + } else { + jidMap.put(passedPresence.getFrom(), passedPresence); + } + entries_.put(bareJID, jidMap); + onPresenceChange.emit(passedPresence); + } + } + + public Presence getLastPresence(final JID jid) { + Map<JID,Presence> presenceMap = entries_.get(jid.toBare()); + if (presenceMap == null) return new Presence(); + + Presence i = presenceMap.get(jid); + if (i != null) { + return i; + } else { + return new Presence(); + } + } + + public Collection<Presence> getAllPresence(final JID bareJID) { + Collection<Presence> results = new ArrayList<Presence>(); + + Map<JID,Presence> presenceMap = entries_.get(bareJID); + if (presenceMap == null) return results; + + results.addAll(presenceMap.values()); + return results; + } + + public Presence getHighestPriorityPresence(final JID bareJID) { + Map<JID,Presence> presenceMap = entries_.get(bareJID); + if (presenceMap == null) return new Presence(); + + Presence highest = null; + for (Presence current : presenceMap.values()) { + if (highest == null + || current.getPriority() > highest.getPriority() + || (current.getPriority() == highest.getPriority() + && StatusShow.typeToAvailabilityOrdering(current.getShow()) > StatusShow.typeToAvailabilityOrdering(highest.getShow()))) { + highest = current; + } + + } + return highest; + } +} |