diff options
Diffstat (limited to 'src/com/isode/stroke/client')
-rw-r--r-- | src/com/isode/stroke/client/Client.java | 132 | ||||
-rw-r--r-- | src/com/isode/stroke/client/CoreClient.java | 14 | ||||
-rw-r--r-- | src/com/isode/stroke/client/MemoryStorages.java | 49 | ||||
-rw-r--r-- | src/com/isode/stroke/client/NickManager.java | 14 | ||||
-rw-r--r-- | src/com/isode/stroke/client/NickManagerImpl.java | 62 | ||||
-rw-r--r-- | src/com/isode/stroke/client/NickResolver.java | 98 | ||||
-rw-r--r-- | src/com/isode/stroke/client/Storages.java | 18 |
7 files changed, 371 insertions, 16 deletions
diff --git a/src/com/isode/stroke/client/Client.java b/src/com/isode/stroke/client/Client.java index 4f5d6c7..0ea6ad7 100644 --- a/src/com/isode/stroke/client/Client.java +++ b/src/com/isode/stroke/client/Client.java @@ -1,22 +1,31 @@ /* - * Copyright (c) 2012, Isode Limited, London, England. - * All rights reserved. - */ -/* - * Copyright (c) 2010, Remko Tronçon. + * Copyright (c) 2010-2015, Isode Limited, London, England. * All rights reserved. */ package com.isode.stroke.client; +import com.isode.stroke.disco.CapsManager; +import com.isode.stroke.disco.ClientDiscoManager; +import com.isode.stroke.disco.EntityCapsManager; +import com.isode.stroke.disco.EntityCapsProvider; +import com.isode.stroke.elements.Presence; import com.isode.stroke.jid.JID; import com.isode.stroke.muc.MUCManager; import com.isode.stroke.muc.MUCRegistry; import com.isode.stroke.network.NetworkFactories; import com.isode.stroke.presence.DirectedPresenceSender; +import com.isode.stroke.presence.PresenceOracle; +import com.isode.stroke.presence.PresenceSender; import com.isode.stroke.presence.StanzaChannelPresenceSender; +import com.isode.stroke.presence.SubscriptionManager; import com.isode.stroke.pubsub.PubSubManager; import com.isode.stroke.pubsub.PubSubManagerImpl; import com.isode.stroke.queries.responders.SoftwareVersionResponder; +import com.isode.stroke.roster.XMPPRoster; +import com.isode.stroke.roster.XMPPRosterController; +import com.isode.stroke.roster.XMPPRosterImpl; +import com.isode.stroke.signals.Signal1; +import com.isode.stroke.vcards.VCardManager; /** * Provides the core functionality for writing XMPP client software. @@ -32,7 +41,21 @@ public class Client extends CoreClient { private final DirectedPresenceSender directedPresenceSender; //NOPMD, this is not better as a local variable private final StanzaChannelPresenceSender stanzaChannelPresenceSender; //NOPMD, this is not better as a local variable private final SoftwareVersionResponder softwareVersionResponder; - private final PubSubManager pubSubManager; + private final PubSubManager pubSubManager; + private final XMPPRosterImpl roster; + private final XMPPRosterController rosterController; + private final PresenceOracle presenceOracle; + private final Storages storages; + private final MemoryStorages memoryStorages; + private final VCardManager vcardManager; + private final CapsManager capsManager; + private final EntityCapsManager entityCapsManager; + private final NickManager nickManager; + private final NickResolver nickResolver; + private final SubscriptionManager subscriptionManager; + private final ClientDiscoManager discoManager; + + final Signal1<Presence> onPresenceChange = new Signal1<Presence>(); /** * Constructor. @@ -50,18 +73,42 @@ public class Client extends CoreClient { * @param networkFactories An implementation of network interaction, must * not be null. */ - public Client(final JID jid, final String password, final NetworkFactories networkFactories) { + public Client(final JID jid, final String password, final NetworkFactories networkFactories, Storages storages) { super(jid, password, networkFactories); + + this.storages = storages; + memoryStorages = new MemoryStorages(networkFactories.getCryptoProvider()); + + softwareVersionResponder = new SoftwareVersionResponder(getIQRouter()); + softwareVersionResponder.start(); + + roster = new XMPPRosterImpl(); + rosterController = new XMPPRosterController(getIQRouter(), roster, getStorages().getRosterStorage()); + + subscriptionManager = new SubscriptionManager(getStanzaChannel()); + + presenceOracle = new PresenceOracle(getStanzaChannel()); + presenceOracle.onPresenceChange.connect(onPresenceChange); + stanzaChannelPresenceSender = new StanzaChannelPresenceSender(getStanzaChannel()); directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender); + discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories.getCryptoProvider()); mucRegistry = new MUCRegistry(); mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry); - softwareVersionResponder = new SoftwareVersionResponder(getIQRouter()); - softwareVersionResponder.start(); - - pubSubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter()); + vcardManager = new VCardManager(jid, getIQRouter(), getStorages().getVCardStorage()); + capsManager = new CapsManager(getStorages().getCapsStorage(), getStanzaChannel(), getIQRouter(), networkFactories.getCryptoProvider()); + entityCapsManager = new EntityCapsManager(capsManager, getStanzaChannel()); + + nickManager = new NickManagerImpl(jid.toBare(), vcardManager); + nickResolver = new NickResolver(jid.toBare(), roster, vcardManager, mucRegistry); + + pubSubManager = new PubSubManagerImpl(getStanzaChannel(), getIQRouter()); + } + + public Client(final JID jid, final String password, final NetworkFactories networkFactories) { + this(jid, password, networkFactories, null); } /** @@ -88,6 +135,10 @@ public class Client extends CoreClient { return pubSubManager; } + public XMPPRoster getRoster() { + return roster; + } + /** * Sets the software version of the client. * @@ -96,4 +147,63 @@ public class Client extends CoreClient { public void setSoftwareVersion(final String name, final String version, final String os) { softwareVersionResponder.setVersion(name, version, os); } + + + public void requestRoster() { + // FIXME: We should set this once when the session is finished, but there + // is currently no callback for this + if (getSession() != null) { + rosterController.setUseVersioning(getSession().getRosterVersioningSuported()); + } + rosterController.requestRoster(); + } + + public Presence getLastPresence(final JID jid) { + return presenceOracle.getLastPresence(jid); + } + + public Presence getHighestPriorityPresence(final JID bareJID) { + return presenceOracle.getHighestPriorityPresence(bareJID); + } + + public PresenceOracle getPresenceOracle() { + return presenceOracle; + } + + public NickManager getNickManager() { + return nickManager; + } + + public NickResolver getNickResolver() { + return nickResolver; + } + + public SubscriptionManager getSubscriptionManager() { + return subscriptionManager; + } + + public ClientDiscoManager getDiscoManager() { + return discoManager; + } + + public VCardManager getVCardManager() { + return vcardManager; + } + + private Storages getStorages() { + if (storages != null) { + return storages; + } + return memoryStorages; + } + + public PresenceSender getPresenceSender() { + return discoManager.getPresenceSender(); + } + + public EntityCapsProvider getEntityCapsProvider() { + return entityCapsManager; + } + + } diff --git a/src/com/isode/stroke/client/CoreClient.java b/src/com/isode/stroke/client/CoreClient.java index a1c6d0a..84ea673 100644 --- a/src/com/isode/stroke/client/CoreClient.java +++ b/src/com/isode/stroke/client/CoreClient.java @@ -1,9 +1,5 @@ /* - * Copyright (c) 2010-2014, Isode Limited, London, England. - * All rights reserved. - */ -/* - * Copyright (c) 2010-2014, Remko Tronçon. + * Copyright (c) 2010-2015, Isode Limited, London, England. * All rights reserved. */ package com.isode.stroke.client; @@ -286,6 +282,10 @@ public class CoreClient { connector_.stop(); } } + + public boolean isActive() { + return (session_ != null && !session_.isFinished()) || connector_ != null; + } public void setCertificate(final CertificateWithKey certificate) { certificate_ = certificate; @@ -477,6 +477,10 @@ public class CoreClient { } connector_ = null; } + + protected ClientSession getSession() { + return session_; + } private void resetSession() { session_.onFinished.disconnectAll(); diff --git a/src/com/isode/stroke/client/MemoryStorages.java b/src/com/isode/stroke/client/MemoryStorages.java new file mode 100644 index 0000000..9bd97a8 --- /dev/null +++ b/src/com/isode/stroke/client/MemoryStorages.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.client; + +import com.isode.stroke.crypto.CryptoProvider; +import com.isode.stroke.disco.CapsMemoryStorage; +import com.isode.stroke.disco.CapsStorage; +import com.isode.stroke.roster.RosterMemoryStorage; +import com.isode.stroke.roster.RosterStorage; +import com.isode.stroke.vcards.VCardMemoryStorage; +import com.isode.stroke.vcards.VCardStorage; + +public class MemoryStorages implements Storages { + private VCardStorage vcardStorage; +// private AvatarStorage avatarStorage; + private CapsStorage capsStorage; + private RosterStorage rosterStorage; +// private HistoryStorage historyStorage; + + public MemoryStorages(CryptoProvider crypto) { + vcardStorage = new VCardMemoryStorage(crypto); + capsStorage = new CapsMemoryStorage(); +// avatarStorage = new AvatarMemoryStorage(); + rosterStorage = new RosterMemoryStorage(); +// #ifdef SWIFT_EXPERIMENTAL_HISTORY +// historyStorage = new SQLiteHistoryStorage(":memory:"); +// #else +// historyStorage = NULL; + + } + + @Override + public VCardStorage getVCardStorage() { + return vcardStorage; + } + + @Override + public RosterStorage getRosterStorage() { + return rosterStorage; + } + + @Override + public CapsStorage getCapsStorage() { + return capsStorage; + } + +} diff --git a/src/com/isode/stroke/client/NickManager.java b/src/com/isode/stroke/client/NickManager.java new file mode 100644 index 0000000..b88dd61 --- /dev/null +++ b/src/com/isode/stroke/client/NickManager.java @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.client; + +import com.isode.stroke.signals.Signal1; + +public abstract class NickManager { + public abstract String getOwnNick(); + public abstract void setOwnNick(final String nick); + + public final Signal1<String> onOwnNickChanged = new Signal1<String>(); +} diff --git a/src/com/isode/stroke/client/NickManagerImpl.java b/src/com/isode/stroke/client/NickManagerImpl.java new file mode 100644 index 0000000..17f9d6b --- /dev/null +++ b/src/com/isode/stroke/client/NickManagerImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.client; + +import com.isode.stroke.elements.VCard; +import com.isode.stroke.jid.JID; +import com.isode.stroke.signals.SignalConnection; +import com.isode.stroke.signals.Slot2; +import com.isode.stroke.vcards.VCardManager; + +public class NickManagerImpl extends NickManager { + private JID ownJID = new JID(); + private String ownNick = ""; + private SignalConnection vCardChangedSignal; + + NickManagerImpl(final JID ownJID, VCardManager vcardManager) { + this.ownJID = ownJID; + + vCardChangedSignal = vcardManager.onVCardChanged.connect(new Slot2<JID, VCard>() { + @Override + public void call(JID p1, VCard p2) { + handleVCardReceived(p1, p2); + } + }); + + updateOwnNickFromVCard(vcardManager.getVCard(ownJID.toBare())); + } + + public void delete() { + vCardChangedSignal.disconnect(); + } + + @Override + public String getOwnNick() { + return ownNick; + } + + @Override + public void setOwnNick(final String nick) { + } + + void handleVCardReceived(final JID jid, VCard vcard) { + if (jid.compare(ownJID, JID.CompareType.WithoutResource) != 0) { + return; + } + updateOwnNickFromVCard(vcard); + } + + void updateOwnNickFromVCard(VCard vcard) { + String nick = null; + if (vcard != null && !vcard.getNickname().isEmpty()) { + nick = vcard.getNickname(); + } + if (ownNick != nick && nick != null && !nick.equals(ownNick)) { + ownNick = nick; + onOwnNickChanged.emit(ownNick); + } + } + +} diff --git a/src/com/isode/stroke/client/NickResolver.java b/src/com/isode/stroke/client/NickResolver.java new file mode 100644 index 0000000..fe2b129 --- /dev/null +++ b/src/com/isode/stroke/client/NickResolver.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.client; + +import java.util.Collection; + +import com.isode.stroke.elements.VCard; +import com.isode.stroke.jid.JID; +import com.isode.stroke.muc.MUCRegistry; +import com.isode.stroke.roster.XMPPRoster; +import com.isode.stroke.signals.Signal2; +import com.isode.stroke.signals.Slot1; +import com.isode.stroke.signals.Slot2; +import com.isode.stroke.signals.Slot3; +import com.isode.stroke.vcards.VCardManager; + +public class NickResolver { + private JID ownJID_; + private String ownNick_; + private XMPPRoster xmppRoster_; + private MUCRegistry mucRegistry_; + private VCardManager vcardManager_; + + public final Signal2<JID, String> onNickChanged = new Signal2<JID, String>(); + + public NickResolver(final JID ownJID, XMPPRoster xmppRoster, VCardManager vcardManager, MUCRegistry mucRegistry) { + ownJID_ = ownJID; + xmppRoster_ = xmppRoster; + vcardManager_ = vcardManager; + if (vcardManager_ != null) { + vcardManager_.onVCardChanged.connect(new Slot2<JID, VCard>() { + @Override + public void call(JID p1, VCard p2) { + handleVCardReceived(p1, p2); + } + }); + } + mucRegistry_ = mucRegistry; + xmppRoster_.onJIDUpdated.connect(new Slot3<JID, String, Collection<String>>() { + @Override + public void call(JID p1, String p2, Collection<String> p3) { + handleJIDUpdated(p1, p2, p3); + } + }); + xmppRoster_.onJIDAdded.connect(new Slot1<JID>() { + @Override + public void call(JID p1) { + handleJIDAdded(p1); + } + }); + } + + void handleJIDUpdated(final JID jid, final String previousNick, final Collection<String> groups) { + onNickChanged.emit(jid, previousNick); + } + + void handleJIDAdded(final JID jid) { + String oldNick= jidToNick(jid); + onNickChanged.emit(jid, oldNick); + } + + public String jidToNick(final JID jid) { + if (jid.toBare().equals(ownJID_)) { + if (ownNick_ != null && !ownNick_.isEmpty()) { + return ownNick_; + } + } + + if (mucRegistry_ != null && mucRegistry_.isMUC(jid.toBare()) ) { + return jid.getResource().isEmpty() ? jid.toBare().toString() : jid.getResource(); + } + + if (xmppRoster_.containsJID(jid) && !xmppRoster_.getNameForJID(jid).isEmpty()) { + return xmppRoster_.getNameForJID(jid); + } + + return jid.toBare().toString(); + } + + void handleVCardReceived(final JID jid, VCard ownVCard) { + if (jid.compare(ownJID_, JID.CompareType.WithoutResource) != 0) { + return; + } + ownNick_ = ownJID_.toString(); + if (ownVCard != null) { + if (!ownVCard.getNickname().isEmpty()) { + ownNick_ = ownVCard.getNickname(); + } else if (!ownVCard.getGivenName().isEmpty()) { + ownNick_ = ownVCard.getGivenName(); + } else if (!ownVCard.getFullName().isEmpty()) { + ownNick_ = ownVCard.getFullName(); + } + } + } + +} diff --git a/src/com/isode/stroke/client/Storages.java b/src/com/isode/stroke/client/Storages.java new file mode 100644 index 0000000..188d1c6 --- /dev/null +++ b/src/com/isode/stroke/client/Storages.java @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2010-2015, Isode Limited, London, England. + * All rights reserved. + */ +package com.isode.stroke.client; + +import com.isode.stroke.disco.CapsStorage; +import com.isode.stroke.roster.RosterStorage; +import com.isode.stroke.vcards.VCardStorage; + +public interface Storages { + VCardStorage getVCardStorage(); +// AvatarStorage getAvatarStorage(); +// CapsStorage getCapsStorage(); + RosterStorage getRosterStorage(); +// HistoryStorage getHistoryStorage(); + CapsStorage getCapsStorage(); +} |