support for remote-roster

This commit is contained in:
HanzZ 2011-09-08 12:38:45 +02:00
parent 82b7126633
commit c4cbaf3311
4 changed files with 73 additions and 12 deletions

View file

@ -70,6 +70,10 @@ class RosterManager {
/// \return User
User *getUser() { return m_user; }
bool isRemoteRosterSupported() {
return m_supportRemoteRoster;
}
/// Called when new Buddy is added to this roster.
/// \param buddy newly added Buddy
boost::signal<void (Buddy *buddy)> onBuddySet;
@ -101,6 +105,7 @@ class RosterManager {
void sendRIE();
void handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error, Swift::SetRosterRequest::ref request, const std::string &key);
void handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> roster, Swift::ErrorPayload::ref error);
std::map<std::string, Buddy *, std::less<std::string>, boost::pool_allocator< std::pair<std::string, Buddy *> > > m_buddies;
Component *m_component;
@ -109,6 +114,7 @@ class RosterManager {
Swift::Timer::ref m_setBuddyTimer;
Swift::Timer::ref m_RIETimer;
std::list <Swift::SetRosterRequest::ref> m_requests;
bool m_supportRemoteRoster;
};
}

View file

@ -35,7 +35,9 @@ void LocalBuddy::setAlias(const std::string &alias) {
m_alias = alias;
if (changed) {
getRosterManager()->sendBuddyRosterPush(this);
if (getRosterManager()->getUser()->getComponent()->inServerMode() || getRosterManager()->isRemoteRosterSupported()) {
getRosterManager()->sendBuddyRosterPush(this);
}
getRosterManager()->storeBuddy(this);
}
}

View file

@ -209,7 +209,7 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator << (const T& t) {
int *data = (int *) m_params[m_offset].buffer;
*data = (int) t;
LOG4CXX_INFO(logger, "adding " << m_offset << ":" << (int) t);
// LOG4CXX_INFO(logger, "adding " << m_offset << ":" << (int) t);
m_offset++;
return *this;
}
@ -217,7 +217,7 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator << (const T& t) {
MySQLBackend::Statement& MySQLBackend::Statement::operator << (const std::string& str) {
if (m_offset >= m_params.size())
return *this;
LOG4CXX_INFO(logger, "adding " << m_offset << ":" << str << "(" << str.size() << ")");
// LOG4CXX_INFO(logger, "adding " << m_offset << ":" << str << "(" << str.size() << ")");
strncpy((char*) m_params[m_offset].buffer, str.c_str(), 4096);
*m_params[m_offset].length = str.size();
m_offset++;
@ -232,7 +232,7 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator >> (T& t) {
if (!m_results[m_resultOffset].is_null) {
T *data = (T *) m_results[m_resultOffset].buffer;
t = *data;
std::cout << "getting " << m_resultOffset << " " << (int) t << "\n";
// std::cout << "getting " << m_resultOffset << " " << (int) t << "\n";
}
if (++m_resultOffset == m_results.size())
@ -241,7 +241,7 @@ MySQLBackend::Statement& MySQLBackend::Statement::operator >> (T& t) {
}
MySQLBackend::Statement& MySQLBackend::Statement::operator >> (std::string& t) {
std::cout << "getting " << m_resultOffset << "\n";
// std::cout << "getting " << m_resultOffset << "\n";
if (m_resultOffset > m_results.size())
return *this;

View file

@ -41,6 +41,16 @@ namespace Transport {
static LoggerPtr logger = Logger::getLogger("RosterManager");
// TODO: Once Swiften GetRosterRequest will support setting to="", this can be removed
class AddressedRosterRequest : public Swift::GenericRequest<Swift::RosterPayload> {
public:
typedef boost::shared_ptr<AddressedRosterRequest> ref;
AddressedRosterRequest(Swift::IQRouter* router, Swift::JID to) :
Swift::GenericRequest<Swift::RosterPayload>(Swift::IQ::Get, to, boost::shared_ptr<Swift::Payload>(new Swift::RosterPayload()), router) {
}
};
RosterManager::RosterManager(User *user, Component *component){
m_rosterStorage = NULL;
m_user = user;
@ -48,6 +58,14 @@ RosterManager::RosterManager(User *user, Component *component){
m_setBuddyTimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(1000);
m_RIETimer = m_component->getNetworkFactories()->getTimerFactory()->createTimer(5000);
m_RIETimer->onTick.connect(boost::bind(&RosterManager::sendRIE, this));
m_supportRemoteRoster = false;
if (!m_component->inServerMode()) {
AddressedRosterRequest::ref request = AddressedRosterRequest::ref(new AddressedRosterRequest(m_component->getIQRouter(), m_user->getJID().toBare()));
request->onResponse.connect(boost::bind(&RosterManager::handleRemoteRosterResponse, this, _1, _2));
request->send();
}
}
RosterManager::~RosterManager() {
@ -89,7 +107,9 @@ void RosterManager::setBuddy(Buddy *buddy) {
}
void RosterManager::sendBuddyRosterPush(Buddy *buddy) {
if (!m_user->isConnected())
// user can't receive anything in server mode if he's not logged in.
// He will ask for roster later (handled in rosterreponsder.cpp)
if (m_component->inServerMode() && !m_user->isConnected())
return;
Swift::RosterPayload::ref payload = Swift::RosterPayload::ref(new Swift::RosterPayload());
@ -138,13 +158,18 @@ void RosterManager::setBuddyCallback(Buddy *buddy) {
if (m_setBuddyTimer->onTick.empty()) {
m_setBuddyTimer->stop();
// Send RIE only if there's resource which supports it.
Swift::JID jidWithRIE = m_user->getJIDWithFeature("http://jabber.org/protocol/rosterx");
if (jidWithRIE.isValid()) {
m_RIETimer->start();
if (m_supportRemoteRoster) {
sendBuddyRosterPush(buddy);
}
else {
sendBuddySubscribePresence(buddy);
// Send RIE only if there's resource which supports it.
Swift::JID jidWithRIE = m_user->getJIDWithFeature("http://jabber.org/protocol/rosterx");
if (jidWithRIE.isValid()) {
m_RIETimer->start();
}
else {
sendBuddySubscribePresence(buddy);
}
}
}
}
@ -175,6 +200,34 @@ void RosterManager::handleBuddyRosterPushResponse(Swift::ErrorPayload::ref error
request->onResponse.disconnect_all_slots();
}
void RosterManager::handleRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error) {
if (error) {
m_supportRemoteRoster = false;
LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server does not support remote roster protoXEP");
return;
}
LOG4CXX_INFO(logger, m_user->getJID().toString() << ": This server supports remote roster protoXEP");
m_supportRemoteRoster = true;
BOOST_FOREACH(const Swift::RosterItemPayload &item, payload->getItems()) {
std::string legacyName = Buddy::JIDToLegacyName(item.getJID());
if (m_buddies.find(legacyName) == m_buddies.end()) {
continue;
}
BuddyInfo buddyInfo;
buddyInfo.id = -1;
buddyInfo.alias = item.getName();
buddyInfo.legacyName = legacyName;
buddyInfo.subscription = "both";
buddyInfo.flags = 0;
Buddy *buddy = m_component->getFactory()->createBuddy(this, buddyInfo);
setBuddy(buddy);
}
}
Buddy *RosterManager::getBuddy(const std::string &name) {
return m_buddies[name];
}
@ -209,7 +262,7 @@ void RosterManager::sendRIE() {
item.setJID(buddy->getJID().toBare());
item.setName(buddy->getAlias());
item.setAction(Swift::RosterItemExchangePayload::Item::Add);
// item.setGroups(buddy->getGroups());
item.setGroups(buddy->getGroups());
payload->addItem(item);
}