summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2011-04-08 21:58:03 (GMT)
committerRemko Tronçon <git@el-tramo.be>2011-04-18 19:11:40 (GMT)
commit01385d84f07466550fff702079555c65963463a8 (patch)
treed995334b205737b2402a8f5778642342b9b3ab02 /Swiften/Roster/XMPPRosterController.cpp
parent1a92834490cda1352a46eaef02a4e7ff76ab94e3 (diff)
downloadswift-01385d84f07466550fff702079555c65963463a8.zip
swift-01385d84f07466550fff702079555c65963463a8.tar.bz2
Added XEP-0237 Roster Versioning support.
Resolves: #803 Release-Notes: Added support for XEP-0237 Roster Versioning
Diffstat (limited to 'Swiften/Roster/XMPPRosterController.cpp')
-rw-r--r--Swiften/Roster/XMPPRosterController.cpp47
1 files changed, 42 insertions, 5 deletions
diff --git a/Swiften/Roster/XMPPRosterController.cpp b/Swiften/Roster/XMPPRosterController.cpp
index a294d35..baa74ff 100644
--- a/Swiften/Roster/XMPPRosterController.cpp
+++ b/Swiften/Roster/XMPPRosterController.cpp
@@ -13,14 +13,15 @@
#include "Swiften/Queries/IQRouter.h"
#include "Swiften/Roster/GetRosterRequest.h"
#include "Swiften/Roster/XMPPRosterImpl.h"
+#include <Swiften/Roster/RosterStorage.h>
namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, XMPPRosterImpl* xmppRoster) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster) {
- rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, false));
+XMPPRosterController::XMPPRosterController(IQRouter* iqRouter, XMPPRosterImpl* xmppRoster, RosterStorage* rosterStorage) : iqRouter_(iqRouter), rosterPushResponder_(iqRouter), xmppRoster_(xmppRoster), rosterStorage_(rosterStorage), useVersioning(false) {
+ rosterPushResponder_.onRosterReceived.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, false, boost::shared_ptr<RosterPayload>()));
rosterPushResponder_.start();
}
@@ -30,12 +31,24 @@ XMPPRosterController::~XMPPRosterController() {
void XMPPRosterController::requestRoster() {
xmppRoster_->clear();
- GetRosterRequest::ref rosterRequest = GetRosterRequest::create(iqRouter_);
- rosterRequest->onResponse.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, true));
+
+ boost::shared_ptr<RosterPayload> storedRoster = rosterStorage_->getRoster();
+ GetRosterRequest::ref rosterRequest;
+ if (useVersioning) {
+ std::string version = "";
+ if (storedRoster && storedRoster->getVersion()) {
+ version = *storedRoster->getVersion();
+ }
+ rosterRequest = GetRosterRequest::create(iqRouter_, version);
+ }
+ else {
+ rosterRequest = GetRosterRequest::create(iqRouter_);
+ }
+ rosterRequest->onResponse.connect(boost::bind(&XMPPRosterController::handleRosterReceived, this, _1, true, storedRoster));
rosterRequest->send();
}
-void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial) {
+void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload> rosterPayload, bool initial, boost::shared_ptr<RosterPayload> previousRoster) {
if (rosterPayload) {
foreach(const RosterItemPayload& item, rosterPayload->getItems()) {
//Don't worry about the updated case, the XMPPRoster sorts that out.
@@ -46,9 +59,33 @@ void XMPPRosterController::handleRosterReceived(boost::shared_ptr<RosterPayload>
}
}
}
+ else if (previousRoster) {
+ // The cached version hasn't changed; emit all items
+ foreach(const RosterItemPayload& item, previousRoster->getItems()) {
+ if (item.getSubscription() != RosterItemPayload::Remove) {
+ xmppRoster_->addContact(item.getJID(), item.getName(), item.getGroups(), item.getSubscription());
+ }
+ else {
+ std::cerr << "ERROR: Stored invalid roster item" << std::endl;
+ }
+ }
+ }
if (initial) {
xmppRoster_->onInitialRosterPopulated();
}
+ if (rosterPayload && rosterPayload->getVersion() && useVersioning) {
+ saveRoster(*rosterPayload->getVersion());
+ }
+}
+
+void XMPPRosterController::saveRoster(const std::string& version) {
+ std::vector<XMPPRosterItem> items = xmppRoster_->getItems();
+ boost::shared_ptr<RosterPayload> roster(new RosterPayload());
+ roster->setVersion(version);
+ foreach(const XMPPRosterItem& item, items) {
+ roster->addItem(RosterItemPayload(item.getJID(), item.getName(), item.getSubscription(), item.getGroups()));
+ }
+ rosterStorage_->setRoster(roster);
}
}