diff options
Diffstat (limited to 'Swiften/Client')
-rw-r--r-- | Swiften/Client/Client.cpp | 15 | ||||
-rw-r--r-- | Swiften/Client/Client.h | 19 | ||||
-rw-r--r-- | Swiften/Client/NickResolver.cpp | 71 | ||||
-rw-r--r-- | Swiften/Client/NickResolver.h | 37 | ||||
-rw-r--r-- | Swiften/Client/UnitTest/NickResolverTest.cpp | 151 |
5 files changed, 293 insertions, 0 deletions
diff --git a/Swiften/Client/Client.cpp b/Swiften/Client/Client.cpp index 7363c3f..67e2051 100644 --- a/Swiften/Client/Client.cpp +++ b/Swiften/Client/Client.cpp @@ -14,6 +14,11 @@ #include "Swiften/MUC/MUCRegistry.h" #include "Swiften/Client/MemoryStorages.h" #include "Swiften/VCards/VCardManager.h" +#include "Swiften/VCards/VCardManager.h" +#include "Swiften/Avatars/AvatarManagerImpl.h" +#include "Swiften/Disco/CapsManager.h" +#include "Swiften/Disco/EntityCapsManager.h" +#include "Swiften/Client/NickResolver.h" namespace Swift { @@ -35,9 +40,19 @@ Client::Client(const JID& jid, const String& password, Storages* storages) : Cor mucRegistry = new MUCRegistry(); vcardManager = new VCardManager(jid, getIQRouter(), getStorages()->getVCardStorage()); + avatarManager = new AvatarManagerImpl(vcardManager, getStanzaChannel(), getStorages()->getAvatarStorage(), mucRegistry); + capsManager = new CapsManager(getStorages()->getCapsStorage(), getStanzaChannel(), getIQRouter()); + entityCapsManager = new EntityCapsManager(capsManager, getStanzaChannel()); + + nickResolver = new NickResolver(jid.toBare(), roster, vcardManager, mucRegistry); } Client::~Client() { + delete nickResolver; + + delete entityCapsManager; + delete capsManager; + delete avatarManager; delete vcardManager; delete mucRegistry; diff --git a/Swiften/Client/Client.h b/Swiften/Client/Client.h index 22fc636..342fe76 100644 --- a/Swiften/Client/Client.h +++ b/Swiften/Client/Client.h @@ -19,6 +19,10 @@ namespace Swift { class Storages; class MemoryStorages; class VCardManager; + class AvatarManager; + class CapsManager; + class EntityCapsManager; + class NickResolver; /** * Provides the core functionality for writing XMPP client software. @@ -90,6 +94,17 @@ namespace Swift { return vcardManager; } + AvatarManager* getAvatarManager() const { + return avatarManager; + } + EntityCapsManager* getEntityCapsManager() const { + return entityCapsManager; + } + + NickResolver* getNickResolver() const { + return nickResolver; + } + public: /** * This signal is emitted when a JID changes presence. @@ -114,5 +129,9 @@ namespace Swift { PresenceSender* presenceSender; MUCRegistry* mucRegistry; VCardManager* vcardManager; + AvatarManager* avatarManager; + CapsManager* capsManager; + EntityCapsManager* entityCapsManager; + NickResolver* nickResolver; }; } diff --git a/Swiften/Client/NickResolver.cpp b/Swiften/Client/NickResolver.cpp new file mode 100644 index 0000000..d06a94d --- /dev/null +++ b/Swiften/Client/NickResolver.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include "Swiften/Client/NickResolver.h" + +#include <boost/shared_ptr.hpp> +#include <boost/bind.hpp> + +#include "Swiften/MUC/MUCRegistry.h" +#include "Swiften/Roster/XMPPRoster.h" +#include "Swiften/VCards/VCardManager.h" + +// FIXME: The NickResolver currently relies on the vcard being requested by the client on login. +// The VCardManager should get an onConnected() signal (which is signalled when the stanzachannel is available(, and each time this is emitted, +// the nickresolver should request the vcard. + +namespace Swift { + +NickResolver::NickResolver(const JID& ownJID, XMPPRoster* xmppRoster, VCardManager* vcardManager, MUCRegistry* mucRegistry) : ownJID_(ownJID) { + xmppRoster_ = xmppRoster; + vcardManager_ = vcardManager; + if (vcardManager_) { + vcardManager_->onVCardChanged.connect(boost::bind(&NickResolver::handleVCardReceived, this, _1, _2)); + } + mucRegistry_ = mucRegistry; +} + +String NickResolver::jidToNick(const JID& jid) { + if (jid.toBare() == ownJID_) { + if (!ownNick_.isEmpty()) { + return ownNick_; + } + } + String nick; + + if (mucRegistry_ && 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(); +} + +void NickResolver::handleVCardReceived(const JID& jid, VCard::ref ownVCard) { + if (!jid.equals(ownJID_, JID::WithoutResource)) { + return; + } + String initialNick = ownNick_; + ownNick_ = ownJID_.toString(); + if (ownVCard) { + if (!ownVCard->getNickname().isEmpty()) { + ownNick_ = ownVCard->getNickname(); + } else if (!ownVCard->getGivenName().isEmpty()) { + ownNick_ = ownVCard->getGivenName(); + } else if (!ownVCard->getFullName().isEmpty()) { + ownNick_ = ownVCard->getFullName(); + } + } + if (ownNick_ != initialNick) { + onOwnNickChanged(ownNick_); + } +} + +} + diff --git a/Swiften/Client/NickResolver.h b/Swiften/Client/NickResolver.h new file mode 100644 index 0000000..7f00acd --- /dev/null +++ b/Swiften/Client/NickResolver.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <map> +#include <boost/signals.hpp> +#include <boost/shared_ptr.hpp> + +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" +#include "Swiften/Elements/VCard.h" + +namespace Swift { + class XMPPRoster; + class MUCRegistry; + class VCardManager; + class NickResolver { + public: + NickResolver(const JID& ownJID, XMPPRoster* xmppRoster, VCardManager* vcardManager, MUCRegistry* mucRegistry); + + String jidToNick(const JID& jid); + + boost::signal<void (const String&)> onOwnNickChanged; + private: + void handleVCardReceived(const JID& jid, VCard::ref vCard); + + private: + JID ownJID_; + String ownNick_; + XMPPRoster* xmppRoster_; + MUCRegistry* mucRegistry_; + VCardManager* vcardManager_; + }; +} + diff --git a/Swiften/Client/UnitTest/NickResolverTest.cpp b/Swiften/Client/UnitTest/NickResolverTest.cpp new file mode 100644 index 0000000..f4db2c1 --- /dev/null +++ b/Swiften/Client/UnitTest/NickResolverTest.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2010 Kevin Smith + * Licensed under the GNU General Public License v3. + * See Documentation/Licenses/GPLv3.txt for more information. + */ + +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include "Swiften/Client/NickResolver.h" +#include "Swiften/MUC/MUCRegistry.h" +#include "Swiften/Roster/XMPPRosterImpl.h" +#include "Swiften/VCards/VCardManager.h" +#include "Swiften/VCards/VCardMemoryStorage.h" +#include "Swiften/Queries/IQRouter.h" +#include "Swiften/Client/DummyStanzaChannel.h" + +using namespace Swift; + +class NickResolverTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(NickResolverTest); + CPPUNIT_TEST(testNoMatch); + CPPUNIT_TEST(testZeroLengthMatch); + CPPUNIT_TEST(testMatch); + CPPUNIT_TEST(testOverwrittenMatch); + CPPUNIT_TEST(testRemovedMatch); + CPPUNIT_TEST(testMUCNick); + CPPUNIT_TEST(testMUCNoNick); + CPPUNIT_TEST(testRemovedMatch); + CPPUNIT_TEST(testOwnNickFullOnly); + CPPUNIT_TEST(testOwnNickGivenAndFull); + CPPUNIT_TEST(testOwnNickNickEtAl); + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp() { + ownJID_ = JID("kev@wonderland.lit"); + xmppRoster_ = new XMPPRosterImpl(); + stanzaChannel_ = new DummyStanzaChannel(); + iqRouter_ = new IQRouter(stanzaChannel_); + vCardStorage_ = new VCardMemoryStorage(); + vCardManager_ = new VCardManager(ownJID_, iqRouter_, vCardStorage_); + registry_ = new MUCRegistry(); + resolver_ = new NickResolver(ownJID_, xmppRoster_, vCardManager_, registry_); + } + + void tearDown() { + delete resolver_; + delete registry_; + delete vCardManager_; + delete stanzaChannel_; + delete iqRouter_; + delete vCardStorage_; + delete xmppRoster_; + } + + void testMUCNick() { + registry_->addMUC(JID("foo@bar")); + JID testJID("foo@bar/baz"); + + CPPUNIT_ASSERT_EQUAL(String("baz"), resolver_->jidToNick(testJID)); + } + + void testMUCNoNick() { + registry_->addMUC(JID("foo@bar")); + JID testJID("foo@bar"); + + CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID)); + } + + + void testNoMatch() { + JID testJID("foo@bar/baz"); + + CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID)); + } + + void testZeroLengthMatch() { + JID testJID("foo@bar/baz"); + xmppRoster_->addContact(testJID, "", groups_, RosterItemPayload::Both); + CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID)); + } + + void testMatch() { + JID testJID("foo@bar/baz"); + xmppRoster_->addContact(testJID, "Test", groups_, RosterItemPayload::Both); + + CPPUNIT_ASSERT_EQUAL(String("Test"), resolver_->jidToNick(testJID)); + } + + void testOverwrittenMatch() { + JID testJID("foo@bar/baz"); + xmppRoster_->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both); + xmppRoster_->addContact(testJID, "Test", groups_, RosterItemPayload::Both); + + CPPUNIT_ASSERT_EQUAL(String("Test"), resolver_->jidToNick(testJID)); + } + + void testRemovedMatch() { + JID testJID("foo@bar/baz"); + xmppRoster_->addContact(testJID, "FailTest", groups_, RosterItemPayload::Both); + xmppRoster_->removeContact(testJID); + CPPUNIT_ASSERT_EQUAL(String("foo@bar"), resolver_->jidToNick(testJID)); + } + + void testOwnNickFullOnly() { + populateOwnVCard("", "", "Kevin Smith"); + CPPUNIT_ASSERT_EQUAL(String("Kevin Smith"), resolver_->jidToNick(ownJID_)); + } + + void testOwnNickGivenAndFull() { + populateOwnVCard("", "Kevin", "Kevin Smith"); + CPPUNIT_ASSERT_EQUAL(String("Kevin"), resolver_->jidToNick(ownJID_)); + } + + void testOwnNickNickEtAl() { + populateOwnVCard("Kev", "Kevin", "Kevin Smith"); + CPPUNIT_ASSERT_EQUAL(String("Kev"), resolver_->jidToNick(ownJID_)); + } + + void populateOwnVCard(const String& nick, const String& given, const String& full) { + VCard::ref vcard(new VCard()); + if (!nick.isEmpty()) { + vcard->setNickname(nick); + } + if (!given.isEmpty()) { + vcard->setGivenName(given); + } + if (!full.isEmpty()) { + vcard->setFullName(full); + } + vCardManager_->requestVCard(ownJID_); + IQ::ref result(IQ::createResult(JID(), stanzaChannel_->sentStanzas[0]->getID(), vcard)); + stanzaChannel_->onIQReceived(result); + } + + private: + std::vector<String> groups_; + XMPPRosterImpl* xmppRoster_; + VCardStorage* vCardStorage_; + IQRouter* iqRouter_; + DummyStanzaChannel* stanzaChannel_; + VCardManager* vCardManager_; + MUCRegistry* registry_; + NickResolver* resolver_; + JID ownJID_; + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(NickResolverTest); + |