From 1daf22de85758cfd035f1fcf6a70007315db4f28 Mon Sep 17 00:00:00 2001 From: Kevin Smith Date: Wed, 28 Sep 2011 17:45:00 +0100 Subject: Destroy rooms. Resolves: #990 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 @@ -73,6 +73,7 @@ MUCController::MUCController ( 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)); @@ -598,4 +599,8 @@ 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 @@ -91,6 +91,7 @@ namespace Swift { void handleConfigureRequest(Form::ref); void handleConfigurationFailed(ErrorPayload::ref); void handleConfigurationFormReceived(Form::ref); + void handleDestroyRoomRequest(); private: MUC::ref muc_; 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 @@ -102,6 +102,7 @@ namespace Swift { boost::signal onOccupantActionSelected; boost::signal onChangeSubjectRequest; boost::signal onConfigureRequest; + boost::signal onDestroyRequest; // File transfer related boost::signal onFileTransferCancel; 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 @@ -700,6 +700,7 @@ 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; @@ -711,6 +712,9 @@ void QtChatWindow::handleActionButtonClicked() { else if (result == configure) { onConfigureRequest(Form::ref()); } + else if (result == destroy) { + onDestroyRequest(); + } } void QtChatWindow::showRoomConfigurationForm(Form::ref form) { 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 @@ -50,8 +50,17 @@ namespace Swift { const std::vector& getStatusCodes() const {return statusCodes_;} + boost::shared_ptr getPayload() const { + return payload_; + } + + void setPayload(boost::shared_ptr p) { + payload_ = p; + } + private: std::vector items_; std::vector statusCodes_; + boost::shared_ptr 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 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -276,6 +277,15 @@ void MUC::configureRoom(Form::ref form) { request->send(); } +void MUC::destroyRoom() { + MUCOwnerPayload::ref mucPayload = boost::make_shared(); + MUCDestroyPayload::ref mucDestroyPayload = boost::make_shared(); + mucPayload->setPayload(mucDestroyPayload); + GenericRequest* request = new GenericRequest(IQ::Set, getJID(), mucPayload, iqRouter_); + request->onResponse.connect(boost::bind(&MUC::handleConfigurationResultReceived, this, _1, _2)); + request->send(); +} + //TODO: Invites(direct/mediated) //TODO: requesting membership 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 @@ -60,6 +60,7 @@ namespace Swift { void changeSubject(const std::string& subject); void requestConfigurationForm(); void configureRoom(Form::ref); + void destroyRoom(); public: boost::signal onJoinComplete; boost::signal onJoinFailed; 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 @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -103,9 +104,11 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(shared_ptr(new VCardParserFactory())); factories_.push_back(shared_ptr(new PrivateStorageParserFactory(this))); factories_.push_back(shared_ptr(new ChatStateParserFactory())); - factories_.push_back(shared_ptr(new MUCUserPayloadParserFactory())); + factories_.push_back(shared_ptr(new MUCUserPayloadParserFactory(this))); factories_.push_back(shared_ptr(new MUCOwnerPayloadParserFactory(this))); factories_.push_back(shared_ptr(new GenericPayloadParserFactory("query", "http://jabber.org/protocol/muc#admin"))); + factories_.push_back(shared_ptr(new GenericPayloadParserFactory("destroy", "http://jabber.org/protocol/muc#user"))); + factories_.push_back(shared_ptr(new GenericPayloadParserFactory("destroy", "http://jabber.org/protocol/muc#owner"))); factories_.push_back(shared_ptr(new NicknameParserFactory())); factories_.push_back(shared_ptr(new JingleParserFactory(this))); factories_.push_back(shared_ptr(new GenericPayloadParserFactory("reason", "urn:xmpp:jingle:1"))); 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 + +#include + +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 + +#include +#include + +namespace Swift { + class MUCDestroyPayloadParser : public GenericPayloadTreeParser { + 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 @@ -8,22 +8,30 @@ #include +#include +#include #include #include +#include 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(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(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 @@ -13,8 +13,12 @@ #include namespace Swift { + class PayloadParserFactoryCollection; class MUCUserPayloadParser : public GenericPayloadTreeParser { 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 @@ -10,8 +10,20 @@ #include namespace Swift { - class MUCUserPayloadParserFactory : public GenericPayloadParserFactory { + class MUCUserPayloadParserFactory : public PayloadParserFactory { public: - MUCUserPayloadParserFactory() : GenericPayloadParserFactory("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 @@ -9,6 +9,7 @@ #include #include +#include #include using namespace Swift; @@ -18,6 +19,7 @@ class MUCUserPayloadParserTest : public CppUnit::TestFixture CPPUNIT_TEST_SUITE(MUCUserPayloadParserTest); CPPUNIT_TEST(testParseEmpty); CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testParseDestroy); CPPUNIT_TEST_SUITE_END(); public: @@ -56,6 +58,19 @@ class MUCUserPayloadParserTest : public CppUnit::TestFixture CPPUNIT_ASSERT(payload); CPPUNIT_ASSERT(payload->getItems().empty()); } + + void testParseDestroy() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("bert")); + + MUCUserPayload::ref payload = boost::dynamic_pointer_cast(parser.getPayload()); + CPPUNIT_ASSERT(payload); + MUCDestroyPayload::ref destroy = boost::dynamic_pointer_cast(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 @@ -62,6 +62,7 @@ sources = [ "PayloadParsers/MUCUserPayloadParser.cpp", "PayloadParsers/MUCAdminPayloadParser.cpp", "PayloadParsers/MUCOwnerPayloadParser.cpp", + "PayloadParsers/MUCDestroyPayloadParser.cpp", "PayloadParsers/MUCItemParser.cpp", "PayloadParsers/NicknameParser.cpp", "PayloadParsers/ReplaceParser.cpp", @@ -78,6 +79,7 @@ sources = [ "StreamResumedParser.cpp", "Tree/ParserElement.cpp", "Tree/NullParserElement.cpp", + "Tree/TreeReparser.cpp", "XMLParser.cpp", "XMLParserClient.cpp", "XMLParserFactory.cpp", 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 @@ -31,6 +31,7 @@ namespace Swift { void appendCharacterData(const std::string& data); std::vector getChildren(const std::string& name, const std::string& xmlns) const; + const std::vector& getAllChildren() const {return children_;} ParserElement::ref getChild(const std::string& name, const std::string& xmlns) const; virtual operator bool() { 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 + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace Swift { + +typedef std::pair ElementState; + +boost::shared_ptr TreeReparser::parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection) { + PayloadParser* parser = collection->getPayloadParserFactory(root->getName(), root->getNamespace(), root->getAttributes())->createPayloadParser(); + std::deque 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 = 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 +#include + +namespace Swift { + class PayloadParserFactoryCollection; + class TreeReparser { + public: + static boost::shared_ptr parseTree(ParserElement::ref root, PayloadParserFactoryCollection* collection); + + }; +} diff --git a/Swiften/SConscript b/Swiften/SConscript index 0dda91f..fce110a 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -150,6 +150,7 @@ if env["SCONS_STAGE"] == "build" : "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", 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 @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -71,9 +72,10 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { 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()); 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 + +#include +#include + +#include +#include +#include + +namespace Swift { + +MUCDestroyPayloadSerializer::MUCDestroyPayloadSerializer() : GenericPayloadSerializer() { +} + +std::string MUCDestroyPayloadSerializer::serializePayload(boost::shared_ptr payload) const { + XMLElement mucElement("destroy", ""); + if (!payload->getReason().empty()) { + XMLElement::ref reason = boost::make_shared("reason", ""); + reason->addNode(boost::make_shared(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 +#include + +namespace Swift { + class PayloadSerializerCollection; + class MUCDestroyPayloadSerializer : public GenericPayloadSerializer { + public: + MUCDestroyPayloadSerializer(); + virtual std::string serializePayload(boost::shared_ptr 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 @@ -13,11 +13,13 @@ #include #include #include +#include #include +#include namespace Swift { -MUCUserPayloadSerializer::MUCUserPayloadSerializer() : GenericPayloadSerializer() { +MUCUserPayloadSerializer::MUCUserPayloadSerializer(PayloadSerializerCollection* serializers) : GenericPayloadSerializer(), serializers(serializers) { } std::string MUCUserPayloadSerializer::serializePayload(boost::shared_ptr payload) const { @@ -32,6 +34,13 @@ std::string MUCUserPayloadSerializer::serializePayload(boost::shared_ptrgetItems()) { mucElement.addNode(MUCItemSerializer::itemToElement(item)); } + boost::shared_ptr childPayload = payload->getPayload(); + if (childPayload) { + PayloadSerializer* serializer = serializers->getPayloadSerializer(childPayload); + if (serializer) { + mucElement.addNode(boost::shared_ptr(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 @@ -10,11 +10,14 @@ #include namespace Swift { + class PayloadSerializerCollection; class MUCUserPayloadSerializer : public GenericPayloadSerializer { public: - MUCUserPayloadSerializer(); + MUCUserPayloadSerializer(PayloadSerializerCollection* serializers); virtual std::string serializePayload(boost::shared_ptr version) const; + private: + PayloadSerializerCollection* serializers; }; } -- cgit v0.10.2-6-g49f6