summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp5
-rw-r--r--Swift/Controllers/Chat/MUCController.h1
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h1
-rw-r--r--Swift/QtUI/QtChatWindow.cpp4
-rw-r--r--Swiften/Elements/MUCUserPayload.h9
-rw-r--r--Swiften/MUC/MUC.cpp10
-rw-r--r--Swiften/MUC/MUC.h1
-rw-r--r--Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp5
-rw-r--r--Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp22
-rw-r--r--Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h19
-rw-r--r--Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp28
-rw-r--r--Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h4
-rw-r--r--Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h16
-rw-r--r--Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp15
-rw-r--r--Swiften/Parser/SConscript2
-rw-r--r--Swiften/Parser/Tree/ParserElement.h1
-rw-r--r--Swiften/Parser/Tree/TreeReparser.cpp48
-rw-r--r--Swiften/Parser/Tree/TreeReparser.h19
-rw-r--r--Swiften/SConscript1
-rw-r--r--Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp4
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp37
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h20
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp11
-rw-r--r--Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h5
24 files changed, 272 insertions, 16 deletions
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 56cc639..e1d02ae 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -67,18 +67,19 @@ MUCController::MUCController (
completer_ = new TabComplete();
chatWindow_->setRosterModel(roster_);
chatWindow_->setTabComplete(completer_);
chatWindow_->setName(muc->getJID().getNode());
chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1));
chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2));
chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1));
chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1));
+ chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this));
muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));
muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
if (timerFactory) {
@@ -592,10 +593,14 @@ void MUCController::handleConfigurationFailed(ErrorPayload::ref error) {
std::string errorMessage = getErrorMessage(error);
errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage);
chatWindow_->addErrorMessage(errorMessage);
}
void MUCController::handleConfigurationFormReceived(Form::ref form) {
chatWindow_->showRoomConfigurationForm(form);
}
+void MUCController::handleDestroyRoomRequest() {
+ muc_->destroyRoom();
+}
+
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index 4be1488..7a7461b 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -85,18 +85,19 @@ namespace Swift {
bool messageTargetsMe(boost::shared_ptr<Message> message);
void updateJoinParts();
bool shouldUpdateJoinParts();
void dayTicked() {lastWasPresence_ = false;}
void processUserPart();
void handleBareJIDCapsChanged(const JID& jid);
void handleConfigureRequest(Form::ref);
void handleConfigurationFailed(ErrorPayload::ref);
void handleConfigurationFormReceived(Form::ref);
+ void handleDestroyRoomRequest();
private:
MUC::ref muc_;
UIEventStream* events_;
std::string nick_;
std::string desiredNick_;
Roster* roster_;
TabComplete* completer_;
bool parting_;
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 75c92d3..df57d80 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -96,18 +96,19 @@ namespace Swift {
boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
boost::signal<void ()> onSendCorrectionMessageRequest;
boost::signal<void ()> onUserTyping;
boost::signal<void ()> onUserCancelsTyping;
boost::signal<void ()> onAlertButtonClicked;
boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged;
boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected;
boost::signal<void (const std::string&)> onChangeSubjectRequest;
boost::signal<void (Form::ref)> onConfigureRequest;
+ boost::signal<void ()> onDestroyRequest;
// File transfer related
boost::signal<void (std::string /* id */)> onFileTransferCancel;
boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart;
boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept;
boost::signal<void (std::string /* path */)> onSendFileRequest;
};
}
#endif
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index 1576880..496c42c 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -694,29 +694,33 @@ void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>
void QtChatWindow::setSubject(const std::string& subject) {
//subject_->setVisible(!subject.empty());
subject_->setText(P2QSTRING(subject));
}
void QtChatWindow::handleActionButtonClicked() {
QMenu contextMenu;
QAction* changeSubject = contextMenu.addAction(tr("Change subject"));
QAction* configure = contextMenu.addAction(tr("Configure room"));
+ QAction* destroy = contextMenu.addAction(tr("Destroy room"));
QAction* result = contextMenu.exec(QCursor::pos());
if (result == changeSubject) {
bool ok;
QString subject = QInputDialog::getText(this, tr("Change room subject"), tr("New subject:"), QLineEdit::Normal, subject_->text(), &ok);
if (ok) {
onChangeSubjectRequest(Q2PSTRING(subject));
}
}
else if (result == configure) {
onConfigureRequest(Form::ref());
}
+ else if (result == destroy) {
+ onDestroyRequest();
+ }
}
void QtChatWindow::showRoomConfigurationForm(Form::ref form) {
if (mucConfigurationWindow) {
delete mucConfigurationWindow.data();
}
mucConfigurationWindow = new QtMUCConfigurationWindow(form);
mucConfigurationWindow->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1));
}
diff --git a/Swiften/Elements/MUCUserPayload.h b/Swiften/Elements/MUCUserPayload.h
index 699badd..c9ea62c 100644
--- a/Swiften/Elements/MUCUserPayload.h
+++ b/Swiften/Elements/MUCUserPayload.h
@@ -44,14 +44,23 @@ namespace Swift {
void addItem(const MUCItem& item) {items_.push_back(item);}
void addStatusCode(StatusCode code) {statusCodes_.push_back(code);}
const std::vector<MUCItem>& getItems() const {return items_;}
const std::vector<StatusCode>& getStatusCodes() const {return statusCodes_;}
+ boost::shared_ptr<Payload> getPayload() const {
+ return payload_;
+ }
+
+ void setPayload(boost::shared_ptr<Payload> p) {
+ payload_ = p;
+ }
+
private:
std::vector<MUCItem> items_;
std::vector<StatusCode> statusCodes_;
+ boost::shared_ptr<Payload> payload_;
};
}
diff --git a/Swiften/MUC/MUC.cpp b/Swiften/MUC/MUC.cpp
index c450c6d..6fe8f19 100644
--- a/Swiften/MUC/MUC.cpp
+++ b/Swiften/MUC/MUC.cpp
@@ -14,18 +14,19 @@
#include <Swiften/Presence/DirectedPresenceSender.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/IQ.h>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/Elements/MUCAdminPayload.h>
#include <Swiften/Elements/MUCPayload.h>
+#include <Swiften/Elements/MUCDestroyPayload.h>
#include <Swiften/MUC/MUCRegistry.h>
#include <Swiften/Queries/GenericRequest.h>
namespace Swift {
typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair;
MUC::MUC(StanzaChannel* stanzaChannel, IQRouter* iqRouter, DirectedPresenceSender* presenceSender, const JID &muc, MUCRegistry* mucRegistry) : ownMUCJID(muc), stanzaChannel(stanzaChannel), iqRouter_(iqRouter), presenceSender(presenceSender), mucRegistry(mucRegistry) {
scopedConnection_ = stanzaChannel->onPresenceReceived.connect(boost::bind(&MUC::handleIncomingPresence, this, _1));
@@ -270,18 +271,27 @@ void MUC::handleConfigurationResultReceived(MUCOwnerPayload::ref /*payload*/, Er
void MUC::configureRoom(Form::ref form) {
MUCOwnerPayload::ref mucPayload(new MUCOwnerPayload());
mucPayload->setPayload(form);
GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_);
request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2));
request->send();
}
+void MUC::destroyRoom() {
+ MUCOwnerPayload::ref mucPayload = boost::make_shared<MUCOwnerPayload>();
+ MUCDestroyPayload::ref mucDestroyPayload = boost::make_shared<MUCDestroyPayload>();
+ mucPayload->setPayload(mucDestroyPayload);
+ GenericRequest<MUCOwnerPayload>* request = new GenericRequest<MUCOwnerPayload>(IQ::Set, getJID(), mucPayload, iqRouter_);
+ request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2));
+ request->send();
+}
+
//TODO: Invites(direct/mediated)
//TODO: requesting membership
//TODO: get member list
//TODO: request voice
//TODO: moderator use cases
diff --git a/Swiften/MUC/MUC.h b/Swiften/MUC/MUC.h
index 4017c97..b99c4b4 100644
--- a/Swiften/MUC/MUC.h
+++ b/Swiften/MUC/MUC.h
@@ -54,18 +54,19 @@ namespace Swift {
/** Expose public so it can be called when e.g. user goes offline */
void handleUserLeft(LeavingType);
/** Get occupant information*/
MUCOccupant getOccupant(const std::string& nick);
bool hasOccupant(const std::string& nick);
void kickUser(const JID& jid);
void changeSubject(const std::string& subject);
void requestConfigurationForm();
void configureRoom(Form::ref);
+ void destroyRoom();
public:
boost::signal<void (const std::string& /*nick*/)> onJoinComplete;
boost::signal<void (ErrorPayload::ref)> onJoinFailed;
boost::signal<void (ErrorPayload::ref, const JID&)> onKickFailed;
boost::signal<void (ErrorPayload::ref)> onConfigurationFailed;
boost::signal<void (Presence::ref)> onOccupantPresenceChange;
boost::signal<void (const std::string&, const MUCOccupant& /*now*/, const MUCOccupant::Role& /*old*/)> onOccupantRoleChanged;
boost::signal<void (const std::string&, const MUCOccupant::Affiliation& /*new*/, const MUCOccupant::Affiliation& /*old*/)> onOccupantAffiliationChanged;
boost::signal<void (const MUCOccupant&)> onOccupantJoined;
diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
index 3d56f61..ebb0f3e 100644
--- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
+++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp
@@ -40,18 +40,19 @@
#include <Swiften/Parser/PayloadParsers/IBBParser.h>
#include <Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h>
#include <Swiften/Parser/PayloadParsers/VCardParserFactory.h>
#include <Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h>
#include <Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h>
#include <Swiften/Parser/PayloadParsers/DelayParser.h>
#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h>
#include <Swiften/Parser/PayloadParsers/MUCAdminPayloadParser.h>
#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParser.h>
+#include <Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h>
#include <Swiften/Parser/PayloadParsers/MUCOwnerPayloadParserFactory.h>
#include <Swiften/Parser/PayloadParsers/NicknameParserFactory.h>
#include <Swiften/Parser/PayloadParsers/ReplaceParser.h>
#include <Swiften/Parser/PayloadParsers/LastParser.h>
#include <Swiften/Parser/PayloadParsers/JingleParserFactory.h>
#include <Swiften/Parser/PayloadParsers/JingleReasonParser.h>
#include <Swiften/Parser/PayloadParsers/JingleContentPayloadParserFactory.h>
#include <Swiften/Parser/PayloadParsers/JingleIBBTransportMethodPayloadParser.h>
#include <Swiften/Parser/PayloadParsers/JingleS5BTransportMethodPayloadParser.h>
@@ -97,21 +98,23 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() {
factories_.push_back(shared_ptr<PayloadParserFactory>(new CommandParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new InBandRegistrationPayloadParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new SearchPayloadParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new StreamInitiationParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new BytestreamsParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardUpdateParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new VCardParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new PrivateStorageParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new ChatStateParserFactory()));
- factories_.push_back(shared_ptr<PayloadParserFactory>(new MUCUserPayloadParserFactory()));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new MUCUserPayloadParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new MUCOwnerPayloadParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<MUCAdminPayloadParser>("query", "http://jabber.org/protocol/muc#admin")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<MUCDestroyPayloadParser>("destroy", "http://jabber.org/protocol/muc#user")));
+ factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<MUCDestroyPayloadParser>("destroy", "http://jabber.org/protocol/muc#owner")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new NicknameParserFactory()));
factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleReasonParser>("reason", "urn:xmpp:jingle:1")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleContentPayloadParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleIBBTransportMethodPayloadParser>("transport", "urn:xmpp:jingle:transports:ibb:1")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleS5BTransportMethodPayloadParser>("transport", "urn:xmpp:jingle:transports:s5b:1")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new JingleFileTransferDescriptionParserFactory(this)));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<StreamInitiationFileInfoParser>("file", "http://jabber.org/protocol/si/profile/file-transfer")));
factories_.push_back(shared_ptr<PayloadParserFactory>(new GenericPayloadParserFactory<JingleFileTransferReceivedParser>("received", "urn:xmpp:jingle:apps:file-transfer:3")));
diff --git a/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp
new file mode 100644
index 0000000..a8d29d0
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.cpp
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h>
+
+#include <Swiften/Base/foreach.h>
+
+namespace Swift {
+
+void MUCDestroyPayloadParser::handleTree(ParserElement::ref root) {
+ std::string ns = root->getNamespace();
+ std::string jid = root->getAttributes().getAttribute("jid");
+ if (!jid.empty()) {
+ getPayloadInternal()->setNewVenue(JID(jid));
+ }
+ getPayloadInternal()->setReason(root->getChild("reason", ns)->getText());
+}
+
+}
diff --git a/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h
new file mode 100644
index 0000000..714651f
--- /dev/null
+++ b/Swiften/Parser/PayloadParsers/MUCDestroyPayloadParser.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <boost/optional.hpp>
+
+#include <Swiften/Elements/MUCDestroyPayload.h>
+#include <Swiften/Parser/GenericPayloadTreeParser.h>
+
+namespace Swift {
+ class MUCDestroyPayloadParser : public GenericPayloadTreeParser<MUCDestroyPayload> {
+ public:
+ virtual void handleTree(ParserElement::ref root);
+ };
+}
diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp
index e6ccbbe..2da8b35 100644
--- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp
+++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.cpp
@@ -2,30 +2,38 @@
* Copyright (c) 2010 Kevin Smith
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h>
#include <boost/lexical_cast.hpp>
+#include <Swiften/Parser/PayloadParserFactoryCollection.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/MUCOccupant.h>
+#include <Swiften/Parser/Tree/TreeReparser.h>
namespace Swift {
void MUCUserPayloadParser::handleTree(ParserElement::ref root) {
- foreach (ParserElement::ref itemElement, root->getChildren("item", "http://jabber.org/protocol/muc#user")) {
- MUCItem item = MUCItemParser::itemFromTree(itemElement);
- getPayloadInternal()->addItem(item);
- }
- foreach (ParserElement::ref statusElement, root->getChildren("status", "http://jabber.org/protocol/muc#user")) {
- MUCUserPayload::StatusCode status;
- try {
- status.code = boost::lexical_cast<int>(statusElement->getAttributes().getAttribute("code").c_str());
- getPayloadInternal()->addStatusCode(status);
- } catch (boost::bad_lexical_cast&) {
+ foreach (ParserElement::ref child, root->getAllChildren()) {
+ if (child->getName() == "item" && child->getNamespace() == root->getNamespace()) {
+ MUCItem item = MUCItemParser::itemFromTree(child);
+ getPayloadInternal()->addItem(item);
+ }
+ else if (child->getName() == "status" && child->getNamespace() == root->getNamespace()) {
+ MUCUserPayload::StatusCode status;
+ try {
+ status.code = boost::lexical_cast<int>(child->getAttributes().getAttribute("code").c_str());
+ getPayloadInternal()->addStatusCode(status);
+ } catch (boost::bad_lexical_cast&) {
+ }
+ }
+ else {
+ getPayloadInternal()->setPayload(TreeReparser::parseTree(child, factories));
}
}
}
}
diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h
index e020127..66e63a8 100644
--- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h
+++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h
@@ -7,14 +7,18 @@
#pragma once
#include <boost/optional.hpp>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/Parser/GenericPayloadTreeParser.h>
#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
namespace Swift {
+ class PayloadParserFactoryCollection;
class MUCUserPayloadParser : public GenericPayloadTreeParser<MUCUserPayload> {
public:
+ MUCUserPayloadParser(PayloadParserFactoryCollection* collection) : factories(collection) {}
virtual void handleTree(ParserElement::ref root);
+ private:
+ PayloadParserFactoryCollection* factories;
};
}
diff --git a/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h b/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h
index e6c8863..2c1c915 100644
--- a/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h
+++ b/Swiften/Parser/PayloadParsers/MUCUserPayloadParserFactory.h
@@ -4,14 +4,26 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <Swiften/Parser/GenericPayloadParserFactory.h>
#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h>
namespace Swift {
- class MUCUserPayloadParserFactory : public GenericPayloadParserFactory<MUCUserPayloadParser> {
+ class MUCUserPayloadParserFactory : public PayloadParserFactory {
public:
- MUCUserPayloadParserFactory() : GenericPayloadParserFactory<MUCUserPayloadParser>("x", "http://jabber.org/protocol/muc#user") {}
+ MUCUserPayloadParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) {
+ }
+
+ virtual bool canParse(const std::string& element, const std::string& ns, const AttributeMap&) const {
+ return element == "x" && ns == "http://jabber.org/protocol/muc#user";
+ }
+
+ virtual PayloadParser* createPayloadParser() {
+ return new MUCUserPayloadParser(factories);
+ }
+
+ private:
+ PayloadParserFactoryCollection* factories;
};
}
diff --git a/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp
index cc2463d..45862e2 100644
--- a/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp
+++ b/Swiften/Parser/PayloadParsers/UnitTest/MUCUserPayloadParserTest.cpp
@@ -3,27 +3,29 @@
* 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/Base/foreach.h>
#include <Swiften/Parser/PayloadParsers/MUCUserPayloadParser.h>
+#include <Swiften/Elements/MUCDestroyPayload.h>
#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h>
using namespace Swift;
class MUCUserPayloadParserTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(MUCUserPayloadParserTest);
CPPUNIT_TEST(testParseEmpty);
CPPUNIT_TEST(testParse);
+ CPPUNIT_TEST(testParseDestroy);
CPPUNIT_TEST_SUITE_END();
public:
MUCUserPayloadParserTest() {}
void testParse() {
PayloadsParserTester parser;
CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"><status code='110'/><item affiliation=\"owner\" role=\"visitor\"><actor jid=\"kev@tester.lit\"/><reason>malice</reason></item><status code='210'/></x>"));
@@ -50,12 +52,25 @@ class MUCUserPayloadParserTest : public CppUnit::TestFixture
void testParseEmpty() {
PayloadsParserTester parser;
CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"/>"));
MUCUserPayload::ref payload = boost::dynamic_pointer_cast<MUCUserPayload>(parser.getPayload());
CPPUNIT_ASSERT(payload);
CPPUNIT_ASSERT(payload->getItems().empty());
}
+
+ void testParseDestroy() {
+ PayloadsParserTester parser;
+
+ CPPUNIT_ASSERT(parser.parse("<x xmlns=\"http://jabber.org/protocol/muc#user\"><destroy jid='alice@wonderland.lit'><reason>bert</reason></destroy></x>"));
+
+ MUCUserPayload::ref payload = boost::dynamic_pointer_cast<MUCUserPayload>(parser.getPayload());
+ CPPUNIT_ASSERT(payload);
+ MUCDestroyPayload::ref destroy = boost::dynamic_pointer_cast<MUCDestroyPayload>(payload->getPayload());
+ CPPUNIT_ASSERT(destroy);
+ CPPUNIT_ASSERT_EQUAL(std::string("bert"), destroy->getReason());
+ CPPUNIT_ASSERT_EQUAL(JID("alice@wonderland.lit"), destroy->getNewVenue());
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(MUCUserPayloadParserTest);
diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript
index 67f706d..2a5d2ee 100644
--- a/Swiften/Parser/SConscript
+++ b/Swiften/Parser/SConscript
@@ -56,34 +56,36 @@ sources = [
"PayloadParsers/StatusShowParser.cpp",
"PayloadParsers/StreamInitiationParser.cpp",
"PayloadParsers/BytestreamsParser.cpp",
"PayloadParsers/VCardParser.cpp",
"PayloadParsers/VCardUpdateParser.cpp",
"PayloadParsers/DelayParser.cpp",
"PayloadParsers/MUCUserPayloadParser.cpp",
"PayloadParsers/MUCAdminPayloadParser.cpp",
"PayloadParsers/MUCOwnerPayloadParser.cpp",
+ "PayloadParsers/MUCDestroyPayloadParser.cpp",
"PayloadParsers/MUCItemParser.cpp",
"PayloadParsers/NicknameParser.cpp",
"PayloadParsers/ReplaceParser.cpp",
"PayloadParsers/LastParser.cpp",
"PayloadParsers/S5BProxyRequestParser.cpp",
"PlatformXMLParserFactory.cpp",
"PresenceParser.cpp",
"SerializingParser.cpp",
"StanzaParser.cpp",
"StreamErrorParser.cpp",
"StreamFeaturesParser.cpp",
"StreamManagementEnabledParser.cpp",
"StreamResumeParser.cpp",
"StreamResumedParser.cpp",
"Tree/ParserElement.cpp",
"Tree/NullParserElement.cpp",
+ "Tree/TreeReparser.cpp",
"XMLParser.cpp",
"XMLParserClient.cpp",
"XMLParserFactory.cpp",
"XMPPParser.cpp",
"XMPPParserClient.cpp",
]
if myenv.get("HAVE_EXPAT", 0) :
myenv.Append(CPPDEFINES = "HAVE_EXPAT")
diff --git a/Swiften/Parser/Tree/ParserElement.h b/Swiften/Parser/Tree/ParserElement.h
index b3ad785..b268c76 100644
--- a/Swiften/Parser/Tree/ParserElement.h
+++ b/Swiften/Parser/Tree/ParserElement.h
@@ -25,18 +25,19 @@ namespace Swift {
const std::string& getText() const { return text_; }
const std::string& getName() const { return name_; }
const std::string& getNamespace() const { return xmlns_; }
const AttributeMap& getAttributes() const { return attributes_; }
ParserElement::ref addChild(const std::string& name, const std::string& xmlns, const AttributeMap& attributes);
void appendCharacterData(const std::string& data);
std::vector<ParserElement::ref> getChildren(const std::string& name, const std::string& xmlns) const;
+ const std::vector<ParserElement::ref>& getAllChildren() const {return children_;}
ParserElement::ref getChild(const std::string& name, const std::string& xmlns) const;
virtual operator bool() {
return true;
}
private:
std::vector<ParserElement::ref> children_;
std::string name_;
diff --git a/Swiften/Parser/Tree/TreeReparser.cpp b/Swiften/Parser/Tree/TreeReparser.cpp
new file mode 100644
index 0000000..9d09831
--- /dev/null
+++ b/Swiften/Parser/Tree/TreeReparser.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Parser/Tree/TreeReparser.h>
+
+#include <boost/lexical_cast.hpp>
+#include <utility>
+#include <deque>
+
+#include <Swiften/Parser/PayloadParserFactoryCollection.h>
+#include <Swiften/Parser/PayloadParserFactory.h>
+#include <Swiften/Parser/PayloadParser.h>
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Elements/MUCOccupant.h>
+
+namespace Swift {
+
+typedef std::pair<ParserElement::ref, bool> ElementState;
+
+boost::shared_ptr<Payload> TreeReparser::parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection) {
+ PayloadParser* parser = collection->getPayloadParserFactory(root->getName(), root->getNamespace(), root->getAttributes())->createPayloadParser();
+ std::deque<ElementState > stack;
+ stack.push_back(ElementState(root, true));
+ while (!stack.empty()) {
+ ElementState current = stack.back();
+ stack.pop_back();
+ if (current.second) {
+ stack.push_back(ElementState(current.first, false));
+ parser->handleStartElement(current.first->getName(), current.first->getNamespace(), current.first->getAttributes());
+ foreach(ParserElement::ref child, current.first->getAllChildren()) {
+ stack.push_back(ElementState(child, true));
+ }
+ } else {
+ parser->handleCharacterData(current.first->getText());
+ parser->handleEndElement(current.first->getName(), current.first->getNamespace());
+ }
+
+ }
+
+ boost::shared_ptr<Payload> payload = parser->getPayload();
+ delete parser;
+ return payload;
+}
+
+}
diff --git a/Swiften/Parser/Tree/TreeReparser.h b/Swiften/Parser/Tree/TreeReparser.h
new file mode 100644
index 0000000..212c518
--- /dev/null
+++ b/Swiften/Parser/Tree/TreeReparser.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Parser/GenericPayloadTreeParser.h>
+#include <Swiften/Parser/PayloadParsers/MUCItemParser.h>
+
+namespace Swift {
+ class PayloadParserFactoryCollection;
+ class TreeReparser {
+ public:
+ static boost::shared_ptr<Payload> parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection);
+
+ };
+}
diff --git a/Swiften/SConscript b/Swiften/SConscript
index 0dda91f..fce110a 100644
--- a/Swiften/SConscript
+++ b/Swiften/SConscript
@@ -144,18 +144,19 @@ if env["SCONS_STAGE"] == "build" :
"Serializer/PayloadSerializers/ChatStateSerializer.cpp",
"Serializer/PayloadSerializers/DiscoInfoSerializer.cpp",
"Serializer/PayloadSerializers/DiscoItemsSerializer.cpp",
"Serializer/PayloadSerializers/ErrorSerializer.cpp",
"Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp",
"Serializer/PayloadSerializers/MUCPayloadSerializer.cpp",
"Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp",
"Serializer/PayloadSerializers/MUCAdminPayloadSerializer.cpp",
"Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.cpp",
+ "Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp",
"Serializer/PayloadSerializers/ResourceBindSerializer.cpp",
"Serializer/PayloadSerializers/RosterItemExchangeSerializer.cpp",
"Serializer/PayloadSerializers/RosterSerializer.cpp",
"Serializer/PayloadSerializers/SecurityLabelSerializer.cpp",
"Serializer/PayloadSerializers/SecurityLabelsCatalogSerializer.cpp",
"Serializer/PayloadSerializers/SoftwareVersionSerializer.cpp",
"Serializer/PayloadSerializers/StreamInitiationSerializer.cpp",
"Serializer/PayloadSerializers/BytestreamsSerializer.cpp",
"Serializer/PayloadSerializers/VCardSerializer.cpp",
diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
index 55c39c7..f3e22d2 100644
--- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
+++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp
@@ -17,18 +17,19 @@
#include <Swiften/Serializer/PayloadSerializers/ChatStateSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/PrioritySerializer.h>
#include <Swiften/Serializer/PayloadSerializers/ErrorSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/RosterItemExchangeSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/MUCPayloadSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/MUCAdminPayloadSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/MUCOwnerPayloadSerializer.h>
+#include <Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/SoftwareVersionSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/StatusSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/StatusShowSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/DiscoItemsSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/CapsInfoSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/ResourceBindSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/StartSessionSerializer.h>
#include <Swiften/Serializer/PayloadSerializers/SecurityLabelSerializer.h>
@@ -65,21 +66,22 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() {
serializers_.push_back(new IBBSerializer());
serializers_.push_back(new BodySerializer());
serializers_.push_back(new SubjectSerializer());
serializers_.push_back(new ChatStateSerializer());
serializers_.push_back(new PrioritySerializer());
serializers_.push_back(new ErrorSerializer());
serializers_.push_back(new RosterSerializer());
serializers_.push_back(new RosterItemExchangeSerializer());
serializers_.push_back(new MUCPayloadSerializer());
- serializers_.push_back(new MUCUserPayloadSerializer());
+ serializers_.push_back(new MUCDestroyPayloadSerializer());
serializers_.push_back(new MUCAdminPayloadSerializer());
serializers_.push_back(new MUCOwnerPayloadSerializer(this));
+ serializers_.push_back(new MUCUserPayloadSerializer(this));
serializers_.push_back(new SoftwareVersionSerializer());
serializers_.push_back(new StatusSerializer());
serializers_.push_back(new StatusShowSerializer());
serializers_.push_back(new DiscoInfoSerializer());
serializers_.push_back(new DiscoItemsSerializer());
serializers_.push_back(new CapsInfoSerializer());
serializers_.push_back(new BlockSerializer<BlockPayload>("block"));
serializers_.push_back(new BlockSerializer<UnblockPayload>("unblock"));
serializers_.push_back(new BlockSerializer<BlockListPayload>("blocklist"));
diff --git a/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp
new file mode 100644
index 0000000..e78a381
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.cpp
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#include <Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swiften/Base/foreach.h>
+#include <Swiften/Serializer/XML/XMLElement.h>
+#include <Swiften/Serializer/XML/XMLTextNode.h>
+
+namespace Swift {
+
+MUCDestroyPayloadSerializer::MUCDestroyPayloadSerializer() : GenericPayloadSerializer<MUCDestroyPayload>() {
+}
+
+std::string MUCDestroyPayloadSerializer::serializePayload(boost::shared_ptr<MUCDestroyPayload> payload) const {
+ XMLElement mucElement("destroy", "");
+ if (!payload->getReason().empty()) {
+ XMLElement::ref reason = boost::make_shared<XMLElement>("reason", "");
+ reason->addNode(boost::make_shared<XMLTextNode>(payload->getReason()));
+ mucElement.addNode(reason);
+ }
+ if (payload->getNewVenue().isValid()) {
+ mucElement.setAttribute("jid", payload->getNewVenue().toString());
+ }
+ return mucElement.serialize();
+}
+
+
+
+
+}
diff --git a/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h
new file mode 100644
index 0000000..419a683
--- /dev/null
+++ b/Swiften/Serializer/PayloadSerializers/MUCDestroyPayloadSerializer.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2011 Kevin Smith
+ * Licensed under the GNU General Public License v3.
+ * See Documentation/Licenses/GPLv3.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Serializer/GenericPayloadSerializer.h>
+#include <Swiften/Elements/MUCDestroyPayload.h>
+
+namespace Swift {
+ class PayloadSerializerCollection;
+ class MUCDestroyPayloadSerializer : public GenericPayloadSerializer<MUCDestroyPayload> {
+ public:
+ MUCDestroyPayloadSerializer();
+ virtual std::string serializePayload(boost::shared_ptr<MUCDestroyPayload> version) const;
+ };
+}
+
diff --git a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp
index 0a8153d..68662b1 100644
--- a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.cpp
@@ -7,35 +7,44 @@
#include <Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h>
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <Swiften/Base/foreach.h>
#include <Swiften/Serializer/XML/XMLElement.h>
#include <Swiften/Serializer/XML/XMLTextNode.h>
+#include <Swiften/Serializer/XML/XMLRawTextNode.h>
#include <Swiften/Serializer/PayloadSerializers/MUCItemSerializer.h>
+#include <Swiften/Serializer/PayloadSerializerCollection.h>
namespace Swift {
-MUCUserPayloadSerializer::MUCUserPayloadSerializer() : GenericPayloadSerializer<MUCUserPayload>() {
+MUCUserPayloadSerializer::MUCUserPayloadSerializer(PayloadSerializerCollection* serializers) : GenericPayloadSerializer<MUCUserPayload>(), serializers(serializers) {
}
std::string MUCUserPayloadSerializer::serializePayload(boost::shared_ptr<MUCUserPayload> payload) const {
XMLElement mucElement("x", "http://jabber.org/protocol/muc#user");
foreach (const MUCUserPayload::StatusCode statusCode, payload->getStatusCodes()) {
boost::shared_ptr<XMLElement> statusElement(new XMLElement("status"));
std::ostringstream code;
code << statusCode.code;
statusElement->setAttribute("code", code.str());
mucElement.addNode(statusElement);
}
foreach (const MUCItem item, payload->getItems()) {
mucElement.addNode(MUCItemSerializer::itemToElement(item));
}
+ boost::shared_ptr<Payload> childPayload = payload->getPayload();
+ if (childPayload) {
+ PayloadSerializer* serializer = serializers->getPayloadSerializer(childPayload);
+ if (serializer) {
+ mucElement.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(childPayload))));
+ }
+ }
return mucElement.serialize();
}
}
diff --git a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h
index 84c4a96..8c237e0 100644
--- a/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h
+++ b/Swiften/Serializer/PayloadSerializers/MUCUserPayloadSerializer.h
@@ -4,17 +4,20 @@
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <Swiften/Serializer/GenericPayloadSerializer.h>
#include <Swiften/Elements/MUCUserPayload.h>
namespace Swift {
+ class PayloadSerializerCollection;
class MUCUserPayloadSerializer : public GenericPayloadSerializer<MUCUserPayload> {
public:
- MUCUserPayloadSerializer();
+ MUCUserPayloadSerializer(PayloadSerializerCollection* serializers);
virtual std::string serializePayload(boost::shared_ptr<MUCUserPayload> version) const;
+ private:
+ PayloadSerializerCollection* serializers;
};
}