diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-09-14 18:57:59 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-09-14 19:15:45 (GMT) |
commit | b8201141afdbd4cab6fcda37cf8daad492b1f996 (patch) | |
tree | ab4908b05a7bb0b1fe97bc4609b68dd9c0b538a9 | |
parent | 5e3ef73cc312d0d79504faa3e0adf4de9bf836c2 (diff) | |
download | swift-b8201141afdbd4cab6fcda37cf8daad492b1f996.zip swift-b8201141afdbd4cab6fcda37cf8daad492b1f996.tar.bz2 |
Added private storage element, parser, and serializer.
14 files changed, 307 insertions, 6 deletions
diff --git a/Swiften/Elements/PrivateStorage.h b/Swiften/Elements/PrivateStorage.h new file mode 100644 index 0000000..66259a3 --- /dev/null +++ b/Swiften/Elements/PrivateStorage.h @@ -0,0 +1,24 @@ +#pragma once + +#include <boost/shared_ptr.hpp> + +#include "Swiften/Elements/Payload.h" + +namespace Swift { + class PrivateStorage : public Payload { + public: + PrivateStorage() { + } + + boost::shared_ptr<Payload> getPayload() const { + return payload; + } + + void setPayload(boost::shared_ptr<Payload> p) { + payload = p; + } + + private: + boost::shared_ptr<Payload> payload; + }; +} diff --git a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp index f4a7b9d..eb4cda0 100644 --- a/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.cpp @@ -18,6 +18,7 @@ #include "Swiften/Parser/PayloadParsers/VCardUpdateParserFactory.h" #include "Swiften/Parser/PayloadParsers/VCardParserFactory.h" #include "Swiften/Parser/PayloadParsers/RawXMLPayloadParserFactory.h" +#include "Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h" using namespace boost; @@ -39,6 +40,7 @@ FullPayloadParserFactoryCollection::FullPayloadParserFactoryCollection() { factories_.push_back(shared_ptr<PayloadParserFactory>(new SecurityLabelsCatalogParserFactory())); 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))); foreach(shared_ptr<PayloadParserFactory> factory, factories_) { addFactory(factory.get()); } diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp new file mode 100644 index 0000000..5c3af26 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.cpp @@ -0,0 +1,43 @@ +#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" +#include "Swiften/Parser/PayloadParserFactoryCollection.h" +#include "Swiften/Parser/PayloadParserFactory.h" + +namespace Swift { + +PrivateStorageParser::PrivateStorageParser(PayloadParserFactoryCollection* factories) : factories(factories), level(0) { +} + +void PrivateStorageParser::handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) { + if (level == 1) { + PayloadParserFactory* payloadParserFactory = factories->getPayloadParserFactory(element, ns, attributes); + if (payloadParserFactory) { + currentPayloadParser.reset(payloadParserFactory->createPayloadParser()); + } + } + + if (level >= 1 && currentPayloadParser.get()) { + currentPayloadParser->handleStartElement(element, ns, attributes); + } + ++level; +} + +void PrivateStorageParser::handleEndElement(const String& element, const String& ns) { + --level; + if (currentPayloadParser.get()) { + if (level >= 1) { + currentPayloadParser->handleEndElement(element, ns); + } + + if (level == 1) { + getPayloadInternal()->setPayload(currentPayloadParser->getPayload()); + } + } +} + +void PrivateStorageParser::handleCharacterData(const String& data) { + if (level > 1 && currentPayloadParser.get()) { + currentPayloadParser->handleCharacterData(data); + } +} + +} diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParser.h b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h new file mode 100644 index 0000000..fae0f10 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParser.h @@ -0,0 +1,25 @@ +#pragma once + +#include <boost/optional.hpp> + +#include "Swiften/Elements/PrivateStorage.h" +#include "Swiften/Parser/GenericPayloadParser.h" + +namespace Swift { + class PayloadParserFactoryCollection; + + class PrivateStorageParser : public GenericPayloadParser<PrivateStorage> { + public: + PrivateStorageParser(PayloadParserFactoryCollection* factories); + + private: + virtual void handleStartElement(const String& element, const String&, const AttributeMap& attributes); + virtual void handleEndElement(const String& element, const String&); + virtual void handleCharacterData(const String& data); + + private: + PayloadParserFactoryCollection* factories; + int level; + std::auto_ptr<PayloadParser> currentPayloadParser; + }; +} diff --git a/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h new file mode 100644 index 0000000..4d9c02b --- /dev/null +++ b/Swiften/Parser/PayloadParsers/PrivateStorageParserFactory.h @@ -0,0 +1,26 @@ +#pragma once + +#include "Swiften/Parser/PayloadParserFactory.h" +#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" + +namespace Swift { + class PayloadParserFactoryCollection; + + class PrivateStorageParserFactory : public PayloadParserFactory { + public: + PrivateStorageParserFactory(PayloadParserFactoryCollection* factories) : factories(factories) { + } + + virtual bool canParse(const String& element, const String& ns, const AttributeMap&) const { + return element == "query" && ns == "jabber:iq:private"; + } + + virtual PayloadParser* createPayloadParser() { + return new PrivateStorageParser(factories); + } + + private: + PayloadParserFactoryCollection* factories; + + }; +} diff --git a/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp new file mode 100644 index 0000000..e820083 --- /dev/null +++ b/Swiften/Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp @@ -0,0 +1,89 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include "Swiften/Elements/Storage.h" +#include "Swiften/Parser/PayloadParsers/PrivateStorageParser.h" +#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadsParserTester.h" +#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h" + +using namespace Swift; + +class PrivateStorageParserTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(PrivateStorageParserTest); + CPPUNIT_TEST(testParse); + CPPUNIT_TEST(testParse_NoPayload); + CPPUNIT_TEST(testParse_MultiplePayloads); + CPPUNIT_TEST_SUITE_END(); + + public: + PrivateStorageParserTest() {} + + void testParse() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse( + "<query xmlns='jabber:iq:private'>" + "<storage xmlns='storage:bookmarks'>" + "<conference name='Swift' jid='swift@rooms.swift.im'>" + "<nick>Alice</nick>" + "</conference>" + "</storage>" + "</query>")); + + boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload()); + CPPUNIT_ASSERT(payload); + boost::shared_ptr<Storage> storage = boost::dynamic_pointer_cast<Storage>(payload->getPayload()); + CPPUNIT_ASSERT(storage); + CPPUNIT_ASSERT_EQUAL(String("Alice"), storage->getConferences()[0].nick); + CPPUNIT_ASSERT_EQUAL(JID("swift@rooms.swift.im"), storage->getConferences()[0].jid); + } + + void testParse_NoPayload() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse("<query xmlns='jabber:iq:private'/>")); + + boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload()); + CPPUNIT_ASSERT(payload); + CPPUNIT_ASSERT(!payload->getPayload()); + } + + void testParse_MultiplePayloads() { + PayloadsParserTester parser; + + CPPUNIT_ASSERT(parser.parse( + "<query xmlns='jabber:iq:private'>" + "<storage xmlns='storage:bookmarks'>" + "<conference name='Swift' jid='swift@rooms.swift.im'>" + "<nick>Alice</nick>" + "</conference>" + "</storage>" + "<storage xmlns='storage:bookmarks'>" + "<conference name='Swift' jid='swift@rooms.swift.im'>" + "<nick>Rabbit</nick>" + "</conference>" + "</storage>" + "</query>")); + + boost::shared_ptr<PrivateStorage> payload = boost::dynamic_pointer_cast<PrivateStorage>(parser.getPayload()); + CPPUNIT_ASSERT(payload); + boost::shared_ptr<Storage> storage = boost::dynamic_pointer_cast<Storage>(payload->getPayload()); + CPPUNIT_ASSERT(storage); + CPPUNIT_ASSERT_EQUAL(String("Rabbit"), storage->getConferences()[0].nick); + } + + void testParse_UnsupportedPayload() { + PayloadParserFactoryCollection factories; + PrivateStorageParser testling(&factories); + PayloadParserTester parser(&testling); + + CPPUNIT_ASSERT(parser.parse( + "<query xmlns='jabber:iq:private'>" + "<foo>Bar</foo>" + "</query>")); + + CPPUNIT_ASSERT(!boost::dynamic_pointer_cast<PrivateStorage>(testling.getPayload())->getPayload()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PrivateStorageParserTest); diff --git a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp index 0cd0100..3fbf27a 100644 --- a/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp +++ b/Swiften/Parser/PayloadParsers/UnitTest/StorageParserTest.cpp @@ -6,8 +6,7 @@ using namespace Swift; -class StorageParserTest : public CppUnit::TestFixture -{ +class StorageParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(StorageParserTest); CPPUNIT_TEST(testParse_Conference); CPPUNIT_TEST(testParse_MultipleConferences); diff --git a/Swiften/Parser/SConscript b/Swiften/Parser/SConscript index e3cd288..3330775 100644 --- a/Swiften/Parser/SConscript +++ b/Swiften/Parser/SConscript @@ -19,6 +19,7 @@ sources = [ "PayloadParsers/ErrorParser.cpp", "PayloadParsers/FullPayloadParserFactoryCollection.cpp", "PayloadParsers/PriorityParser.cpp", + "PayloadParsers/PrivateStorageParser.cpp", "PayloadParsers/RawXMLPayloadParser.cpp", "PayloadParsers/ResourceBindParser.cpp", "PayloadParsers/RosterParser.cpp", diff --git a/Swiften/SConscript b/Swiften/SConscript index 6572e9a..fa10fb1 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -62,6 +62,7 @@ sources = [ "Serializer/PayloadSerializers/VCardSerializer.cpp", "Serializer/PayloadSerializers/VCardUpdateSerializer.cpp", "Serializer/PayloadSerializers/StorageSerializer.cpp", + "Serializer/PayloadSerializers/PrivateStorageSerializer.cpp", "Serializer/PresenceSerializer.cpp", "Serializer/StanzaSerializer.cpp", "Serializer/StreamFeaturesSerializer.cpp", @@ -130,6 +131,7 @@ env.Append(UNITTEST_SOURCES = [ File("Parser/PayloadParsers/UnitTest/StatusShowParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/VCardParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/StorageParserTest.cpp"), + File("Parser/PayloadParsers/UnitTest/PrivateStorageParserTest.cpp"), File("Parser/PayloadParsers/UnitTest/VCardUpdateParserTest.cpp"), File("Parser/UnitTest/AttributeMapTest.cpp"), File("Parser/UnitTest/IQParserTest.cpp"), @@ -162,6 +164,7 @@ env.Append(UNITTEST_SOURCES = [ File("Serializer/PayloadSerializers/UnitTest/StatusShowSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/VCardUpdateSerializerTest.cpp"), File("Serializer/PayloadSerializers/UnitTest/StorageSerializerTest.cpp"), + File("Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp"), File("Serializer/UnitTest/StreamFeaturesSerializerTest.cpp"), File("Serializer/XML/UnitTest/XMLElementTest.cpp"), File("Server/UnitTest/ServerStanzaRouterTest.cpp"), diff --git a/Swiften/Serializer/PayloadSerializerCollection.h b/Swiften/Serializer/PayloadSerializerCollection.h index a126989..63ccabe 100644 --- a/Swiften/Serializer/PayloadSerializerCollection.h +++ b/Swiften/Serializer/PayloadSerializerCollection.h @@ -1,5 +1,4 @@ -#ifndef SWIFTEN_PAYLOADSERIALIZERCOLLECTION_H -#define SWIFTEN_PAYLOADSERIALIZERCOLLECTION_H +#pragma once #include <vector> #include <boost/shared_ptr.hpp> @@ -22,5 +21,3 @@ namespace Swift { std::vector<PayloadSerializer*> serializers_; }; } - -#endif diff --git a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp index 998dce8..fc20018 100644 --- a/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp +++ b/Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.cpp @@ -19,6 +19,7 @@ #include "Swiften/Serializer/PayloadSerializers/VCardUpdateSerializer.h" #include "Swiften/Serializer/PayloadSerializers/RawXMLPayloadSerializer.h" #include "Swiften/Serializer/PayloadSerializers/StorageSerializer.h" +#include "Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h" namespace Swift { @@ -41,6 +42,7 @@ FullPayloadSerializerCollection::FullPayloadSerializerCollection() { serializers_.push_back(new VCardUpdateSerializer()); serializers_.push_back(new RawXMLPayloadSerializer()); serializers_.push_back(new StorageSerializer()); + serializers_.push_back(new PrivateStorageSerializer(this)); foreach(PayloadSerializer* serializer, serializers_) { addSerializer(serializer); } diff --git a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp new file mode 100644 index 0000000..999252c --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.cpp @@ -0,0 +1,28 @@ +#include "Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h" + +#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/PayloadSerializerCollection.h" + +namespace Swift { + +PrivateStorageSerializer::PrivateStorageSerializer(PayloadSerializerCollection* serializers) : serializers(serializers) { +} + +String PrivateStorageSerializer::serializePayload(boost::shared_ptr<PrivateStorage> storage) const { + XMLElement storageElement("query", "jabber:iq:private"); + boost::shared_ptr<Payload> payload = storage->getPayload(); + if (payload) { + PayloadSerializer* serializer = serializers->getPayloadSerializer(payload); + if (serializer) { + storageElement.addNode(boost::shared_ptr<XMLRawTextNode>(new XMLRawTextNode(serializer->serialize(payload)))); + } + } + return storageElement.serialize(); +} + +} diff --git a/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h new file mode 100644 index 0000000..c655634 --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/PrivateStorageSerializer.h @@ -0,0 +1,18 @@ +#pragma once + +#include "Swiften/Serializer/GenericPayloadSerializer.h" +#include "Swiften/Elements/PrivateStorage.h" + +namespace Swift { + class PayloadSerializerCollection; + + class PrivateStorageSerializer : public GenericPayloadSerializer<PrivateStorage> { + public: + PrivateStorageSerializer(PayloadSerializerCollection* serializers); + + virtual String serializePayload(boost::shared_ptr<PrivateStorage>) const; + + private: + PayloadSerializerCollection* serializers; + }; +} diff --git a/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp b/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp new file mode 100644 index 0000000..37c3adb --- /dev/null +++ b/Swiften/Serializer/PayloadSerializers/UnitTest/PrivateStorageSerializerTest.cpp @@ -0,0 +1,44 @@ +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/extensions/TestFactoryRegistry.h> + +#include "Swiften/Serializer/PayloadSerializers/UnitTest/PayloadsSerializer.h" +#include "Swiften/Elements/PrivateStorage.h" +#include "Swiften/Elements/Storage.h" + +using namespace Swift; + +class PrivateStorageSerializerTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(PrivateStorageSerializerTest); + CPPUNIT_TEST(testSerialize); + CPPUNIT_TEST_SUITE_END(); + + public: + PrivateStorageSerializerTest() {} + + void testSerialize() { + PayloadsSerializer serializer; + + boost::shared_ptr<PrivateStorage> privateStorage(new PrivateStorage()); + boost::shared_ptr<Storage> storage(new Storage()); + Storage::Conference conference; + conference.name = "Swift"; + conference.jid = JID("swift@rooms.swift.im"); + conference.nick = "Alice"; + storage->addConference(conference); + privateStorage->setPayload(storage); + + CPPUNIT_ASSERT_EQUAL(String( + "<query xmlns=\"jabber:iq:private\">" + "<storage xmlns=\"storage:bookmarks\">" + "<conference " + "autojoin=\"1\" " + "jid=\"swift@rooms.swift.im\" " + "name=\"Swift\">" + "<nick>Alice</nick>" + "</conference>" + "</storage>" + "</query>"), serializer.serialize(privateStorage)); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PrivateStorageSerializerTest); |