summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/isode/stroke/client')
-rw-r--r--src/com/isode/stroke/client/Client.java132
-rw-r--r--src/com/isode/stroke/client/CoreClient.java14
-rw-r--r--src/com/isode/stroke/client/MemoryStorages.java49
-rw-r--r--src/com/isode/stroke/client/NickManager.java14
-rw-r--r--src/com/isode/stroke/client/NickManagerImpl.java62
-rw-r--r--src/com/isode/stroke/client/NickResolver.java98
-rw-r--r--src/com/isode/stroke/client/Storages.java18
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();
+}