From b4db894f76de9ac252081972143efcd3fcd66533 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 19 Apr 2015 21:07:36 +0200 Subject: Moved complete writing part to GenericFacade --- common/domainadaptor.h | 15 ++++++++--- common/facade.h | 52 ++++++++++++++++++++++++++++++++++++--- examples/dummyresource/facade.cpp | 24 ++---------------- examples/dummyresource/facade.h | 4 --- 4 files changed, 62 insertions(+), 33 deletions(-) diff --git a/common/domainadaptor.h b/common/domainadaptor.h index d07a2bd..fd015b5 100644 --- a/common/domainadaptor.h +++ b/common/domainadaptor.h @@ -171,13 +171,22 @@ QSharedPointer > initializeReadPropertyMapper(); template QSharedPointer > initializeWritePropertyMapper(); +template +class DomainTypeAdaptorFactoryInterface +{ +public: + virtual ~DomainTypeAdaptorFactoryInterface() {}; + virtual QSharedPointer createAdaptor(const Akonadi2::Entity &entity) = 0; + virtual void createBuffer(const DomainType &event, flatbuffers::FlatBufferBuilder &fbb) = 0; +}; + /** * The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter. * It defines how values are split accross local and resource buffer. * This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way. */ template -class DomainTypeAdaptorFactory +class DomainTypeAdaptorFactory : public DomainTypeAdaptorFactoryInterface { public: DomainTypeAdaptorFactory() : @@ -193,7 +202,7 @@ public: * * This returns by default a GenericBufferAdaptor initialized with the corresponding property mappers. */ - virtual QSharedPointer createAdaptor(const Akonadi2::Entity &entity) + virtual QSharedPointer createAdaptor(const Akonadi2::Entity &entity) Q_DECL_OVERRIDE { const auto resourceBuffer = Akonadi2::EntityBuffer::readBuffer(entity.resource()); const auto localBuffer = Akonadi2::EntityBuffer::readBuffer(entity.local()); @@ -207,7 +216,7 @@ public: return adaptor; } - virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) {}; + virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) Q_DECL_OVERRIDE {}; protected: QSharedPointer > mLocalMapper; diff --git a/common/facade.h b/common/facade.h index 6c1ad67..a5858d5 100644 --- a/common/facade.h +++ b/common/facade.h @@ -84,14 +84,29 @@ namespace Akonadi2 { class ResourceAccess; /** * Default facade implementation for resources that are implemented in a separate process using the ResourceAccess class. + * + * Ideally a basic resource has no implementation effort for the facades and can simply instanciate default implementations (meaning it only has to implement the factory with all supported types). + * A resource has to implement: + * * A facade factory registering all available facades + * * An adaptor factory if it uses special resource buffers (default implementation can be used otherwise) + * * A mapping between resource and buffertype if default can't be used. + * + * Additionally a resource only has to provide a synchronizer plugin to execute the synchronization */ template class GenericFacade: public Akonadi2::StoreFacade { public: - GenericFacade(const QByteArray &resourceIdentifier) + /** + * Create a new GenericFacade + * + * @param resourceIdentifier is the identifier of the resource instance + * @param adaptorFactory is the adaptor factory used to generate the mappings from domain to resource types and vice versa + */ + GenericFacade(const QByteArray &resourceIdentifier, const QSharedPointer > &adaptorFactory = QSharedPointer >()) : Akonadi2::StoreFacade(), - mResourceAccess(new ResourceAccess(resourceIdentifier)) + mResourceAccess(new ResourceAccess(resourceIdentifier)), + mDomainTypeAdaptorFactory(adaptorFactory) { } @@ -99,6 +114,34 @@ public: { } + static QByteArray bufferTypeForDomainType() + { + //We happen to have a one to one mapping + return Akonadi2::ApplicationDomain::getTypeName(); + } + + Async::Job create(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE + { + if (!mDomainTypeAdaptorFactory) { + Warning() << "No domain type adaptor factory available"; + } + flatbuffers::FlatBufferBuilder entityFbb; + mDomainTypeAdaptorFactory->createBuffer(domainObject, entityFbb); + return sendCreateCommand(bufferTypeForDomainType(), QByteArray::fromRawData(reinterpret_cast(entityFbb.GetBufferPointer()), entityFbb.GetSize())); + } + + Async::Job modify(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE + { + //TODO + return Async::null(); + } + + Async::Job remove(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE + { + //TODO + return Async::null(); + } + //TODO JOBAPI return job from sync continuation to execute it as subjob? Async::Job load(const Akonadi2::Query &query, const QSharedPointer > &resultProvider) Q_DECL_OVERRIDE { @@ -142,11 +185,11 @@ public: } protected: - Async::Job sendCreateCommand(const QByteArray &t, const QByteArray &buffer) + Async::Job sendCreateCommand(const QByteArray &resourceBufferType, const QByteArray &buffer) { flatbuffers::FlatBufferBuilder fbb; //This is the resource buffer type and not the domain type - auto type = fbb.CreateString(t.constData()); + auto type = fbb.CreateString(resourceBufferType.constData()); auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size()); auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); @@ -177,6 +220,7 @@ protected: protected: //TODO use one resource access instance per application => make static QSharedPointer mResourceAccess; + QSharedPointer > mDomainTypeAdaptorFactory; }; } diff --git a/examples/dummyresource/facade.cpp b/examples/dummyresource/facade.cpp index e50e4f3..37f75ae 100644 --- a/examples/dummyresource/facade.cpp +++ b/examples/dummyresource/facade.cpp @@ -38,8 +38,7 @@ using namespace flatbuffers; DummyResourceFacade::DummyResourceFacade() - : Akonadi2::GenericFacade("org.kde.dummy"), - mFactory(new DummyEventAdaptorFactory) + : Akonadi2::GenericFacade("org.kde.dummy", QSharedPointer::create()) { } @@ -47,25 +46,6 @@ DummyResourceFacade::~DummyResourceFacade() { } -Async::Job DummyResourceFacade::create(const Akonadi2::ApplicationDomain::Event &domainObject) -{ - flatbuffers::FlatBufferBuilder entityFbb; - mFactory->createBuffer(domainObject, entityFbb); - return sendCreateCommand("event", QByteArray::fromRawData(reinterpret_cast(entityFbb.GetBufferPointer()), entityFbb.GetSize())); -} - -Async::Job DummyResourceFacade::modify(const Akonadi2::ApplicationDomain::Event &domainObject) -{ - //Create message buffer and send to resource - return Async::null(); -} - -Async::Job DummyResourceFacade::remove(const Akonadi2::ApplicationDomain::Event &domainObject) -{ - //Create message buffer and send to resource - return Async::null(); -} - static std::function prepareQuery(const Akonadi2::Query &query) { //Compose some functions to make query matching fast. @@ -133,7 +113,7 @@ void DummyResourceFacade::readValue(QSharedPointer storage, c qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; //This only works for a 1:1 mapping of resource to domain types. //Not i.e. for tags that are stored as flags in each entity of an imap store. - auto adaptor = mFactory->createAdaptor(buffer.entity()); + auto adaptor = mDomainTypeAdaptorFactory->createAdaptor(buffer.entity()); //TODO only copy requested properties auto memoryAdaptor = QSharedPointer::create(*adaptor); // here we could copy additional properties that don't have a 1:1 mapping, such as separately stored tags. diff --git a/examples/dummyresource/facade.h b/examples/dummyresource/facade.h index 91ae351..2fd2fa9 100644 --- a/examples/dummyresource/facade.h +++ b/examples/dummyresource/facade.h @@ -34,12 +34,8 @@ class DummyResourceFacade : public Akonadi2::GenericFacade create(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE; - Async::Job modify(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE; - Async::Job remove(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE; Async::Job load(const Akonadi2::Query &query, const std::function &resultCallback) Q_DECL_OVERRIDE; private: void readValue(QSharedPointer storage, const QByteArray &key, const std::function &resultCallback, std::function); - QSharedPointer > mFactory; }; -- cgit v1.2.3