summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/domainadaptor.h15
-rw-r--r--common/facade.h52
-rw-r--r--examples/dummyresource/facade.cpp24
-rw-r--r--examples/dummyresource/facade.h4
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<ReadPropertyMapper<T> > initializeReadPropertyMapper();
171template <class T> 171template <class T>
172QSharedPointer<WritePropertyMapper<T> > initializeWritePropertyMapper(); 172QSharedPointer<WritePropertyMapper<T> > initializeWritePropertyMapper();
173 173
174template<typename DomainType>
175class DomainTypeAdaptorFactoryInterface
176{
177public:
178 virtual ~DomainTypeAdaptorFactoryInterface() {};
179 virtual QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity) = 0;
180 virtual void createBuffer(const DomainType &event, flatbuffers::FlatBufferBuilder &fbb) = 0;
181};
182
174/** 183/**
175 * The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter. 184 * The factory should define how to go from an entitybuffer (local + resource buffer), to a domain type adapter.
176 * It defines how values are split accross local and resource buffer. 185 * It defines how values are split accross local and resource buffer.
177 * This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way. 186 * This is required by the facade the read the value, and by the pipeline preprocessors to access the domain values in a generic way.
178 */ 187 */
179template<typename DomainType, typename LocalBuffer, typename ResourceBuffer, typename LocalBuilder, typename ResourceBuilder> 188template<typename DomainType, typename LocalBuffer, typename ResourceBuffer, typename LocalBuilder, typename ResourceBuilder>
180class DomainTypeAdaptorFactory 189class DomainTypeAdaptorFactory : public DomainTypeAdaptorFactoryInterface<DomainType>
181{ 190{
182public: 191public:
183 DomainTypeAdaptorFactory() : 192 DomainTypeAdaptorFactory() :
@@ -193,7 +202,7 @@ public:
193 * 202 *
194 * This returns by default a GenericBufferAdaptor initialized with the corresponding property mappers. 203 * This returns by default a GenericBufferAdaptor initialized with the corresponding property mappers.
195 */ 204 */
196 virtual QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity) 205 virtual QSharedPointer<Akonadi2::ApplicationDomain::BufferAdaptor> createAdaptor(const Akonadi2::Entity &entity) Q_DECL_OVERRIDE
197 { 206 {
198 const auto resourceBuffer = Akonadi2::EntityBuffer::readBuffer<ResourceBuffer>(entity.resource()); 207 const auto resourceBuffer = Akonadi2::EntityBuffer::readBuffer<ResourceBuffer>(entity.resource());
199 const auto localBuffer = Akonadi2::EntityBuffer::readBuffer<LocalBuffer>(entity.local()); 208 const auto localBuffer = Akonadi2::EntityBuffer::readBuffer<LocalBuffer>(entity.local());
@@ -207,7 +216,7 @@ public:
207 return adaptor; 216 return adaptor;
208 } 217 }
209 218
210 virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) {}; 219 virtual void createBuffer(const Akonadi2::ApplicationDomain::Event &event, flatbuffers::FlatBufferBuilder &fbb) Q_DECL_OVERRIDE {};
211 220
212protected: 221protected:
213 QSharedPointer<ReadPropertyMapper<LocalBuffer> > mLocalMapper; 222 QSharedPointer<ReadPropertyMapper<LocalBuffer> > 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 {
84 class ResourceAccess; 84 class ResourceAccess;
85/** 85/**
86 * Default facade implementation for resources that are implemented in a separate process using the ResourceAccess class. 86 * Default facade implementation for resources that are implemented in a separate process using the ResourceAccess class.
87 *
88 * 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).
89 * A resource has to implement:
90 * * A facade factory registering all available facades
91 * * An adaptor factory if it uses special resource buffers (default implementation can be used otherwise)
92 * * A mapping between resource and buffertype if default can't be used.
93 *
94 * Additionally a resource only has to provide a synchronizer plugin to execute the synchronization
87 */ 95 */
88template <typename DomainType> 96template <typename DomainType>
89class GenericFacade: public Akonadi2::StoreFacade<DomainType> 97class GenericFacade: public Akonadi2::StoreFacade<DomainType>
90{ 98{
91public: 99public:
92 GenericFacade(const QByteArray &resourceIdentifier) 100 /**
101 * Create a new GenericFacade
102 *
103 * @param resourceIdentifier is the identifier of the resource instance
104 * @param adaptorFactory is the adaptor factory used to generate the mappings from domain to resource types and vice versa
105 */
106 GenericFacade(const QByteArray &resourceIdentifier, const QSharedPointer<DomainTypeAdaptorFactoryInterface<DomainType> > &adaptorFactory = QSharedPointer<DomainTypeAdaptorFactoryInterface<DomainType> >())
93 : Akonadi2::StoreFacade<DomainType>(), 107 : Akonadi2::StoreFacade<DomainType>(),
94 mResourceAccess(new ResourceAccess(resourceIdentifier)) 108 mResourceAccess(new ResourceAccess(resourceIdentifier)),
109 mDomainTypeAdaptorFactory(adaptorFactory)
95 { 110 {
96 } 111 }
97 112
@@ -99,6 +114,34 @@ public:
99 { 114 {
100 } 115 }
101 116
117 static QByteArray bufferTypeForDomainType()
118 {
119 //We happen to have a one to one mapping
120 return Akonadi2::ApplicationDomain::getTypeName<DomainType>();
121 }
122
123 Async::Job<void> create(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE
124 {
125 if (!mDomainTypeAdaptorFactory) {
126 Warning() << "No domain type adaptor factory available";
127 }
128 flatbuffers::FlatBufferBuilder entityFbb;
129 mDomainTypeAdaptorFactory->createBuffer(domainObject, entityFbb);
130 return sendCreateCommand(bufferTypeForDomainType(), QByteArray::fromRawData(reinterpret_cast<const char*>(entityFbb.GetBufferPointer()), entityFbb.GetSize()));
131 }
132
133 Async::Job<void> modify(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE
134 {
135 //TODO
136 return Async::null<void>();
137 }
138
139 Async::Job<void> remove(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE
140 {
141 //TODO
142 return Async::null<void>();
143 }
144
102 //TODO JOBAPI return job from sync continuation to execute it as subjob? 145 //TODO JOBAPI return job from sync continuation to execute it as subjob?
103 Async::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<typename DomainType::Ptr> > &resultProvider) Q_DECL_OVERRIDE 146 Async::Job<void> load(const Akonadi2::Query &query, const QSharedPointer<Akonadi2::ResultProvider<typename DomainType::Ptr> > &resultProvider) Q_DECL_OVERRIDE
104 { 147 {
@@ -142,11 +185,11 @@ public:
142 } 185 }
143 186
144protected: 187protected:
145 Async::Job<void> sendCreateCommand(const QByteArray &t, const QByteArray &buffer) 188 Async::Job<void> sendCreateCommand(const QByteArray &resourceBufferType, const QByteArray &buffer)
146 { 189 {
147 flatbuffers::FlatBufferBuilder fbb; 190 flatbuffers::FlatBufferBuilder fbb;
148 //This is the resource buffer type and not the domain type 191 //This is the resource buffer type and not the domain type
149 auto type = fbb.CreateString(t.constData()); 192 auto type = fbb.CreateString(resourceBufferType.constData());
150 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size()); 193 auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, buffer.constData(), buffer.size());
151 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); 194 auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta);
152 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); 195 Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location);
@@ -177,6 +220,7 @@ protected:
177protected: 220protected:
178 //TODO use one resource access instance per application => make static 221 //TODO use one resource access instance per application => make static
179 QSharedPointer<Akonadi2::ResourceAccess> mResourceAccess; 222 QSharedPointer<Akonadi2::ResourceAccess> mResourceAccess;
223 QSharedPointer<DomainTypeAdaptorFactoryInterface<DomainType> > mDomainTypeAdaptorFactory;
180}; 224};
181 225
182} 226}
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;
38 38
39 39
40DummyResourceFacade::DummyResourceFacade() 40DummyResourceFacade::DummyResourceFacade()
41 : Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Event>("org.kde.dummy"), 41 : Akonadi2::GenericFacade<Akonadi2::ApplicationDomain::Event>("org.kde.dummy", QSharedPointer<DummyEventAdaptorFactory>::create())
42 mFactory(new DummyEventAdaptorFactory)
43{ 42{
44} 43}
45 44
@@ -47,25 +46,6 @@ DummyResourceFacade::~DummyResourceFacade()
47{ 46{
48} 47}
49 48
50Async::Job<void> DummyResourceFacade::create(const Akonadi2::ApplicationDomain::Event &domainObject)
51{
52 flatbuffers::FlatBufferBuilder entityFbb;
53 mFactory->createBuffer(domainObject, entityFbb);
54 return sendCreateCommand("event", QByteArray::fromRawData(reinterpret_cast<const char*>(entityFbb.GetBufferPointer()), entityFbb.GetSize()));
55}
56
57Async::Job<void> DummyResourceFacade::modify(const Akonadi2::ApplicationDomain::Event &domainObject)
58{
59 //Create message buffer and send to resource
60 return Async::null<void>();
61}
62
63Async::Job<void> DummyResourceFacade::remove(const Akonadi2::ApplicationDomain::Event &domainObject)
64{
65 //Create message buffer and send to resource
66 return Async::null<void>();
67}
68
69static std::function<bool(const std::string &key, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local)> prepareQuery(const Akonadi2::Query &query) 49static std::function<bool(const std::string &key, DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local)> prepareQuery(const Akonadi2::Query &query)
70{ 50{
71 //Compose some functions to make query matching fast. 51 //Compose some functions to make query matching fast.
@@ -133,7 +113,7 @@ void DummyResourceFacade::readValue(QSharedPointer<Akonadi2::Storage> storage, c
133 qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1; 113 qint64 revision = metadataBuffer ? metadataBuffer->revision() : -1;
134 //This only works for a 1:1 mapping of resource to domain types. 114 //This only works for a 1:1 mapping of resource to domain types.
135 //Not i.e. for tags that are stored as flags in each entity of an imap store. 115 //Not i.e. for tags that are stored as flags in each entity of an imap store.
136 auto adaptor = mFactory->createAdaptor(buffer.entity()); 116 auto adaptor = mDomainTypeAdaptorFactory->createAdaptor(buffer.entity());
137 //TODO only copy requested properties 117 //TODO only copy requested properties
138 auto memoryAdaptor = QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create(*adaptor); 118 auto memoryAdaptor = QSharedPointer<Akonadi2::ApplicationDomain::MemoryBufferAdaptor>::create(*adaptor);
139 // here we could copy additional properties that don't have a 1:1 mapping, such as separately stored tags. 119 // 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<Akonadi2::Application
34public: 34public:
35 DummyResourceFacade(); 35 DummyResourceFacade();
36 virtual ~DummyResourceFacade(); 36 virtual ~DummyResourceFacade();
37 Async::Job<void> create(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE;
38 Async::Job<void> modify(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE;
39 Async::Job<void> remove(const Akonadi2::ApplicationDomain::Event &domainObject) Q_DECL_OVERRIDE;
40 Async::Job<qint64> load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback) Q_DECL_OVERRIDE; 37 Async::Job<qint64> load(const Akonadi2::Query &query, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback) Q_DECL_OVERRIDE;
41 38
42private: 39private:
43 void readValue(QSharedPointer<Akonadi2::Storage> storage, const QByteArray &key, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback, std::function<bool(const std::string &key, DummyCalendar::DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local)>); 40 void readValue(QSharedPointer<Akonadi2::Storage> storage, const QByteArray &key, const std::function<void(const Akonadi2::ApplicationDomain::Event::Ptr &)> &resultCallback, std::function<bool(const std::string &key, DummyCalendar::DummyEvent const *buffer, Akonadi2::ApplicationDomain::Buffer::Event const *local)>);
44 QSharedPointer<DomainTypeAdaptorFactory<Akonadi2::ApplicationDomain::Event, Akonadi2::ApplicationDomain::Buffer::Event, DummyCalendar::DummyEvent, Akonadi2::ApplicationDomain::Buffer::EventBuilder, DummyCalendar::DummyEventBuilder> > mFactory;
45}; 41};