From e297fb92c2c0e344d36e0aef57921f6b9b921a61 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 31 May 2015 20:16:23 +0200 Subject: Moved default read/write property mapper to TypeImplementation There is always exactly one default buffer that we can centralize in TypeImplementation. --- common/CMakeLists.txt | 1 + common/domain/applicationdomaintype.h | 9 ++++ common/domain/event.cpp | 34 +++++++++++++- common/domain/event.h | 19 ++++++-- common/domainadaptor.cpp | 45 ------------------ common/domainadaptor.h | 69 +++------------------------- common/propertymapper.cpp | 39 ++++++++++++++++ common/propertymapper.h | 86 +++++++++++++++++++++++++++++++++++ 8 files changed, 188 insertions(+), 114 deletions(-) create mode 100644 common/propertymapper.cpp create mode 100644 common/propertymapper.h (limited to 'common') diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 6a048ea..9e30752 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -17,6 +17,7 @@ set(command_SRCS commands.cpp facade.cpp pipeline.cpp + propertymapper.cpp domainadaptor.cpp resource.cpp genericresource.cpp diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h index 2de1460..f2a4ad6 100644 --- a/common/domain/applicationdomaintype.h +++ b/common/domain/applicationdomaintype.h @@ -130,5 +130,14 @@ QByteArray getTypeName(); template<> QByteArray getTypeName(); +/** + * Type implementation. + * + * Needs to be implemented for every application domain type. + * Contains all non-resource specific, but type-specific code. + */ +template +class TypeImplementation; + } } diff --git a/common/domain/event.cpp b/common/domain/event.cpp index 86100b7..ea0931c 100644 --- a/common/domain/event.cpp +++ b/common/domain/event.cpp @@ -20,15 +20,19 @@ #include #include +#include #include "../resultset.h" #include "../index.h" #include "../storage.h" #include "../log.h" +#include "../propertymapper.h" + +#include "event_generated.h" using namespace Akonadi2::ApplicationDomain; -ResultSet EventImplementation::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier) +ResultSet TypeImplementation::queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier) { QVector keys; if (query.propertyFilter.contains("uid")) { @@ -43,7 +47,7 @@ ResultSet EventImplementation::queryIndexes(const Akonadi2::Query &query, const return ResultSet(keys); } -void EventImplementation::index(const Event &type) +void TypeImplementation::index(const Event &type) { Index uidIndex(Akonadi2::Store::storageLocation(), type.resourceInstanceIdentifier() + "index.uid", Akonadi2::Storage::ReadWrite); const auto uid = type.getProperty("uid"); @@ -51,3 +55,29 @@ void EventImplementation::index(const Event &type) uidIndex.add(uid.toByteArray(), type.identifier()); } } + +QSharedPointer > TypeImplementation::initializeReadPropertyMapper() +{ + auto propertyMapper = QSharedPointer >::create(); + propertyMapper->addMapping("summary", [](Buffer::Event const *buffer) -> QVariant { + return propertyToVariant(buffer->summary()); + }); + propertyMapper->addMapping("uid", [](Buffer::Event const *buffer) -> QVariant { + return propertyToVariant(buffer->uid()); + }); + return propertyMapper; +} + +QSharedPointer > TypeImplementation::initializeWritePropertyMapper() +{ + auto propertyMapper = QSharedPointer >::create(); + propertyMapper->addMapping("summary", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function { + auto offset = variantToProperty(value, fbb); + return [offset](Buffer::EventBuilder &builder) { builder.add_summary(offset); }; + }); + propertyMapper->addMapping("uid", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function { + auto offset = variantToProperty(value, fbb); + return [offset](Buffer::EventBuilder &builder) { builder.add_uid(offset); }; + }); + return propertyMapper; +} diff --git a/common/domain/event.h b/common/domain/event.h index 4cb0d34..d4ce20e 100644 --- a/common/domain/event.h +++ b/common/domain/event.h @@ -23,23 +23,34 @@ class ResultSet; class QByteArray; +template +class ReadPropertyMapper; +template +class WritePropertyMapper; + namespace Akonadi2 { class Query; namespace ApplicationDomain { + namespace Buffer { + class Event; + class EventBuilder; + } /** * Implements all type-specific code such as updating and querying indexes. */ -namespace EventImplementation { - typedef Event DomainType; +template<> +struct TypeImplementation { /** * Returns the potential result set based on the indexes. * * An empty result set indicates that a full scan is required. */ - ResultSet queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier); - void index(const Event &type); + static ResultSet queryIndexes(const Akonadi2::Query &query, const QByteArray &resourceInstanceIdentifier); + static void index(const Event &type); + static QSharedPointer > initializeReadPropertyMapper(); + static QSharedPointer > initializeWritePropertyMapper(); }; } diff --git a/common/domainadaptor.cpp b/common/domainadaptor.cpp index 8a4b5ed..2955cab 100644 --- a/common/domainadaptor.cpp +++ b/common/domainadaptor.cpp @@ -19,48 +19,3 @@ #include "domainadaptor.h" -template <> -flatbuffers::uoffset_t variantToProperty(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) -{ - if (property.isValid()) { - return fbb.CreateString(property.toString().toStdString()).o; - } - return 0; -} - -template <> -QVariant propertyToVariant(const flatbuffers::String *property) -{ - if (property) { - return QString::fromStdString(property->c_str()); - } - return QVariant(); -} - -template <> -QSharedPointer > initializeReadPropertyMapper() -{ - auto propertyMapper = QSharedPointer >::create(); - propertyMapper->addMapping("summary", [](Akonadi2::ApplicationDomain::Buffer::Event const *buffer) -> QVariant { - return propertyToVariant(buffer->summary()); - }); - propertyMapper->addMapping("uid", [](Akonadi2::ApplicationDomain::Buffer::Event const *buffer) -> QVariant { - return propertyToVariant(buffer->uid()); - }); - return propertyMapper; -} - -template <> -QSharedPointer > initializeWritePropertyMapper() -{ - auto propertyMapper = QSharedPointer >::create(); - propertyMapper->addMapping("summary", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function { - auto offset = variantToProperty(value, fbb); - return [offset](Akonadi2::ApplicationDomain::Buffer::EventBuilder &builder) { builder.add_summary(offset); }; - }); - propertyMapper->addMapping("uid", [](const QVariant &value, flatbuffers::FlatBufferBuilder &fbb) -> std::function { - auto offset = variantToProperty(value, fbb); - return [offset](Akonadi2::ApplicationDomain::Buffer::EventBuilder &builder) { builder.add_uid(offset); }; - }); - return propertyMapper; -} diff --git a/common/domainadaptor.h b/common/domainadaptor.h index fd015b5..70c3a42 100644 --- a/common/domainadaptor.h +++ b/common/domainadaptor.h @@ -29,65 +29,8 @@ #include "entity_generated.h" #include "metadata_generated.h" #include "entitybuffer.h" - -/** - * The property mapper is a non-typesafe virtual dispatch. - * - * Instead of using an interface and requring each implementation to override - * a virtual method per property, the property mapper can be filled with accessors - * that extract the properties from resource types. - */ -template -class ReadPropertyMapper -{ -public: - virtual QVariant getProperty(const QByteArray &key, BufferType const *buffer) const - { - if (mReadAccessors.contains(key)) { - auto accessor = mReadAccessors.value(key); - return accessor(buffer); - } - return QVariant(); - } - bool hasMapping(const QByteArray &key) const { return mReadAccessors.contains(key); } - QList availableProperties() const { return mReadAccessors.keys(); } - void addMapping(const QByteArray &property, const std::function &mapping) { - mReadAccessors.insert(property, mapping); - } -private: - QHash > mReadAccessors; -}; - -template -class WritePropertyMapper -{ -public: - virtual void setProperty(const QByteArray &key, const QVariant &value, QList > &builderCalls, flatbuffers::FlatBufferBuilder &fbb) const - { - if (mWriteAccessors.contains(key)) { - auto accessor = mWriteAccessors.value(key); - builderCalls << accessor(value, fbb); - } - } - bool hasMapping(const QByteArray &key) const { return mWriteAccessors.contains(key); } - void addMapping(const QByteArray &property, const std::function(const QVariant &, flatbuffers::FlatBufferBuilder &)> &mapping) { - mWriteAccessors.insert(property, mapping); - } -private: - QHash(const QVariant &, flatbuffers::FlatBufferBuilder &)> > mWriteAccessors; -}; - -/** - * Defines how to convert qt primitives to flatbuffer ones - */ -template -flatbuffers::uoffset_t variantToProperty(const QVariant &, flatbuffers::FlatBufferBuilder &fbb); - -/** - * Defines how to convert flatbuffer primitives to qt ones - */ -template -QVariant propertyToVariant(const flatbuffers::String *); +#include "propertymapper.h" +#include "domain/event.h" /** * Create a buffer from a domain object using the provided mappings @@ -177,7 +120,7 @@ class DomainTypeAdaptorFactoryInterface public: virtual ~DomainTypeAdaptorFactoryInterface() {}; virtual QSharedPointer createAdaptor(const Akonadi2::Entity &entity) = 0; - virtual void createBuffer(const DomainType &event, flatbuffers::FlatBufferBuilder &fbb) = 0; + virtual void createBuffer(const DomainType &domainType, flatbuffers::FlatBufferBuilder &fbb) = 0; }; /** @@ -190,9 +133,9 @@ class DomainTypeAdaptorFactory : public DomainTypeAdaptorFactoryInterface()), + mLocalMapper(Akonadi2::ApplicationDomain::TypeImplementation::initializeReadPropertyMapper()), mResourceMapper(QSharedPointer >::create()), - mLocalWriteMapper(initializeWritePropertyMapper()), + mLocalWriteMapper(Akonadi2::ApplicationDomain::TypeImplementation::initializeWritePropertyMapper()), mResourceWriteMapper(QSharedPointer >::create()) {}; virtual ~DomainTypeAdaptorFactory() {}; @@ -216,7 +159,7 @@ public: return adaptor; } - virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) Q_DECL_OVERRIDE {}; + virtual void createBuffer(const DomainType &domainType, flatbuffers::FlatBufferBuilder &fbb) Q_DECL_OVERRIDE {}; protected: QSharedPointer > mLocalMapper; diff --git a/common/propertymapper.cpp b/common/propertymapper.cpp new file mode 100644 index 0000000..0896aa6 --- /dev/null +++ b/common/propertymapper.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "propertymapper.h" + +template <> +flatbuffers::uoffset_t variantToProperty(const QVariant &property, flatbuffers::FlatBufferBuilder &fbb) +{ + if (property.isValid()) { + return fbb.CreateString(property.toString().toStdString()).o; + } + return 0; +} + +template <> +QVariant propertyToVariant(const flatbuffers::String *property) +{ + if (property) { + return QString::fromStdString(property->c_str()); + } + return QVariant(); +} + diff --git a/common/propertymapper.h b/common/propertymapper.h new file mode 100644 index 0000000..0c6c16f --- /dev/null +++ b/common/propertymapper.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2014 Christian Mollekopf + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#pragma once + +#include +#include +#include +#include + +/** + * Defines how to convert qt primitives to flatbuffer ones + */ +template +flatbuffers::uoffset_t variantToProperty(const QVariant &, flatbuffers::FlatBufferBuilder &fbb); + +/** + * Defines how to convert flatbuffer primitives to qt ones + */ +template +QVariant propertyToVariant(const flatbuffers::String *); + + +/** + * The property mapper is a non-typesafe virtual dispatch. + * + * Instead of using an interface and requring each implementation to override + * a virtual method per property, the property mapper can be filled with accessors + * that extract the properties from resource types. + */ +template +class ReadPropertyMapper +{ +public: + virtual QVariant getProperty(const QByteArray &key, BufferType const *buffer) const + { + if (mReadAccessors.contains(key)) { + auto accessor = mReadAccessors.value(key); + return accessor(buffer); + } + return QVariant(); + } + bool hasMapping(const QByteArray &key) const { return mReadAccessors.contains(key); } + QList availableProperties() const { return mReadAccessors.keys(); } + void addMapping(const QByteArray &property, const std::function &mapping) { + mReadAccessors.insert(property, mapping); + } +private: + QHash > mReadAccessors; +}; + +template +class WritePropertyMapper +{ +public: + virtual void setProperty(const QByteArray &key, const QVariant &value, QList > &builderCalls, flatbuffers::FlatBufferBuilder &fbb) const + { + if (mWriteAccessors.contains(key)) { + auto accessor = mWriteAccessors.value(key); + builderCalls << accessor(value, fbb); + } + } + bool hasMapping(const QByteArray &key) const { return mWriteAccessors.contains(key); } + void addMapping(const QByteArray &property, const std::function(const QVariant &, flatbuffers::FlatBufferBuilder &)> &mapping) { + mWriteAccessors.insert(property, mapping); + } +private: + QHash(const QVariant &, flatbuffers::FlatBufferBuilder &)> > mWriteAccessors; +}; + -- cgit v1.2.3