diff options
Diffstat (limited to 'examples/dummyresource/resourcefactory.cpp')
-rw-r--r-- | examples/dummyresource/resourcefactory.cpp | 130 |
1 files changed, 109 insertions, 21 deletions
diff --git a/examples/dummyresource/resourcefactory.cpp b/examples/dummyresource/resourcefactory.cpp index 0e18282..147cb22 100644 --- a/examples/dummyresource/resourcefactory.cpp +++ b/examples/dummyresource/resourcefactory.cpp | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "entitybuffer.h" | 23 | #include "entitybuffer.h" |
24 | #include "pipeline.h" | 24 | #include "pipeline.h" |
25 | #include "dummycalendar_generated.h" | 25 | #include "dummycalendar_generated.h" |
26 | #include "mail_generated.h" | ||
26 | #include "queuedcommand_generated.h" | 27 | #include "queuedcommand_generated.h" |
27 | #include "createentity_generated.h" | 28 | #include "createentity_generated.h" |
28 | #include "domainadaptor.h" | 29 | #include "domainadaptor.h" |
@@ -30,21 +31,23 @@ | |||
30 | #include "index.h" | 31 | #include "index.h" |
31 | #include "log.h" | 32 | #include "log.h" |
32 | #include "domain/event.h" | 33 | #include "domain/event.h" |
34 | #include "domain/mail.h" | ||
33 | #include "dummystore.h" | 35 | #include "dummystore.h" |
34 | #include "definitions.h" | 36 | #include "definitions.h" |
35 | #include "facadefactory.h" | 37 | #include "facadefactory.h" |
36 | 38 | ||
37 | //This is the resources entity type, and not the domain type | 39 | //This is the resources entity type, and not the domain type |
38 | #define ENTITY_TYPE_EVENT "event" | 40 | #define ENTITY_TYPE_EVENT "event" |
41 | #define ENTITY_TYPE_MAIL "mail" | ||
39 | 42 | ||
40 | DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Akonadi2::Pipeline> &pipeline) | 43 | DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QSharedPointer<Akonadi2::Pipeline> &pipeline) |
41 | : Akonadi2::GenericResource(instanceIdentifier, pipeline) | 44 | : Akonadi2::GenericResource(instanceIdentifier, pipeline) |
42 | { | 45 | { |
43 | auto eventFactory = QSharedPointer<DummyEventAdaptorFactory>::create(); | 46 | auto eventFactory = QSharedPointer<DummyEventAdaptorFactory>::create(); |
44 | const auto resourceIdentifier = mResourceInstanceIdentifier; | 47 | const auto resourceIdentifier = mResourceInstanceIdentifier; |
48 | |||
45 | auto eventIndexer = new Akonadi2::SimpleProcessor("eventIndexer", [eventFactory, resourceIdentifier](const Akonadi2::PipelineState &state, const Akonadi2::Entity &entity, Akonadi2::Storage::Transaction &transaction) { | 49 | auto eventIndexer = new Akonadi2::SimpleProcessor("eventIndexer", [eventFactory, resourceIdentifier](const Akonadi2::PipelineState &state, const Akonadi2::Entity &entity, Akonadi2::Storage::Transaction &transaction) { |
46 | auto adaptor = eventFactory->createAdaptor(entity); | 50 | auto adaptor = eventFactory->createAdaptor(entity); |
47 | //FIXME set revision? | ||
48 | Akonadi2::ApplicationDomain::Event event(resourceIdentifier, state.key(), -1, adaptor); | 51 | Akonadi2::ApplicationDomain::Event event(resourceIdentifier, state.key(), -1, adaptor); |
49 | Akonadi2::ApplicationDomain::TypeImplementation<Akonadi2::ApplicationDomain::Event>::index(event, transaction); | 52 | Akonadi2::ApplicationDomain::TypeImplementation<Akonadi2::ApplicationDomain::Event>::index(event, transaction); |
50 | 53 | ||
@@ -58,15 +61,79 @@ DummyResource::DummyResource(const QByteArray &instanceIdentifier, const QShared | |||
58 | mPipeline->setPreprocessors(ENTITY_TYPE_EVENT, Akonadi2::Pipeline::NewPipeline, QVector<Akonadi2::Preprocessor*>() << eventIndexer); | 61 | mPipeline->setPreprocessors(ENTITY_TYPE_EVENT, Akonadi2::Pipeline::NewPipeline, QVector<Akonadi2::Preprocessor*>() << eventIndexer); |
59 | mPipeline->setAdaptorFactory(ENTITY_TYPE_EVENT, eventFactory); | 62 | mPipeline->setAdaptorFactory(ENTITY_TYPE_EVENT, eventFactory); |
60 | //TODO cleanup indexes during removal | 63 | //TODO cleanup indexes during removal |
64 | |||
65 | { | ||
66 | auto mailFactory = QSharedPointer<DummyMailAdaptorFactory>::create(); | ||
67 | auto mailIndexer = new Akonadi2::SimpleProcessor("mailIndexer", [mailFactory, resourceIdentifier](const Akonadi2::PipelineState &state, const Akonadi2::Entity &entity, Akonadi2::Storage::Transaction &transaction) { | ||
68 | auto adaptor = mailFactory->createAdaptor(entity); | ||
69 | Akonadi2::ApplicationDomain::Mail mail(resourceIdentifier, state.key(), -1, adaptor); | ||
70 | Akonadi2::ApplicationDomain::TypeImplementation<Akonadi2::ApplicationDomain::Mail>::index(mail, transaction); | ||
71 | |||
72 | Index ridIndex("mail.index.rid", transaction); | ||
73 | const auto rid = mail.getProperty("remoteId"); | ||
74 | if (rid.isValid()) { | ||
75 | ridIndex.add(rid.toByteArray(), mail.identifier()); | ||
76 | } | ||
77 | }); | ||
78 | |||
79 | mPipeline->setPreprocessors(ENTITY_TYPE_MAIL, Akonadi2::Pipeline::NewPipeline, QVector<Akonadi2::Preprocessor*>() << mailIndexer); | ||
80 | mPipeline->setAdaptorFactory(ENTITY_TYPE_MAIL, mailFactory); | ||
81 | } | ||
82 | } | ||
83 | |||
84 | void DummyResource::createEvent(const QByteArray &ridBuffer, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb) | ||
85 | { | ||
86 | auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); | ||
87 | |||
88 | //Map the source format to the buffer format (which happens to be an exact copy here) | ||
89 | auto summary = m_fbb.CreateString(eventBuffer->summary()->c_str()); | ||
90 | auto rid = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); | ||
91 | auto description = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); | ||
92 | static uint8_t rawData[100]; | ||
93 | auto attachment = Akonadi2::EntityBuffer::appendAsVector(m_fbb, rawData, 100); | ||
94 | |||
95 | auto builder = DummyCalendar::DummyEventBuilder(m_fbb); | ||
96 | builder.add_summary(summary); | ||
97 | builder.add_remoteId(rid); | ||
98 | builder.add_description(description); | ||
99 | builder.add_attachment(attachment); | ||
100 | auto buffer = builder.Finish(); | ||
101 | DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); | ||
102 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); | ||
103 | } | ||
104 | |||
105 | void DummyResource::createMail(const QByteArray &ridBuffer, const QByteArray &data, flatbuffers::FlatBufferBuilder &entityFbb) | ||
106 | { | ||
107 | auto mailBuffer = Akonadi2::ApplicationDomain::Buffer::GetMail(data.data()); | ||
108 | |||
109 | //Map the source format to the buffer format (which happens to be an exact copy here) | ||
110 | auto subject = m_fbb.CreateString(mailBuffer->subject()->c_str()); | ||
111 | auto rid = m_fbb.CreateString(std::string(ridBuffer.constData(), ridBuffer.size())); | ||
112 | auto sender = m_fbb.CreateString(std::string("sender@example.org")); | ||
113 | auto senderName = m_fbb.CreateString(std::string("Sender Name")); | ||
114 | auto date = m_fbb.CreateString(std::string("2004")); | ||
115 | auto folder = m_fbb.CreateString(std::string("inbox")); | ||
116 | |||
117 | auto builder = Akonadi2::ApplicationDomain::Buffer::MailBuilder(m_fbb); | ||
118 | builder.add_subject(subject); | ||
119 | builder.add_sender(sender); | ||
120 | builder.add_senderName(senderName); | ||
121 | builder.add_unread(true); | ||
122 | builder.add_important(false); | ||
123 | builder.add_date(date); | ||
124 | builder.add_folder(folder); | ||
125 | auto buffer = builder.Finish(); | ||
126 | Akonadi2::ApplicationDomain::Buffer::FinishMailBuffer(m_fbb, buffer); | ||
127 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize()); | ||
61 | } | 128 | } |
62 | 129 | ||
63 | KAsync::Job<void> DummyResource::synchronizeWithSource() | 130 | KAsync::Job<void> DummyResource::synchronizeWithSource() |
64 | { | 131 | { |
65 | return KAsync::start<void>([this](KAsync::Future<void> &f) { | 132 | return KAsync::start<void>([this](KAsync::Future<void> &f) { |
66 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier + ".index.uid", Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); | 133 | auto transaction = Akonadi2::Storage(Akonadi2::storageLocation(), mResourceInstanceIdentifier, Akonadi2::Storage::ReadOnly).createTransaction(Akonadi2::Storage::ReadOnly); |
67 | Index uidIndex("index.uid", transaction); | 134 | Index uidIndex("index.uid", transaction); |
68 | 135 | ||
69 | const auto data = DummyStore::instance().data(); | 136 | const auto data = DummyStore::instance().events(); |
70 | for (auto it = data.constBegin(); it != data.constEnd(); it++) { | 137 | for (auto it = data.constBegin(); it != data.constEnd(); it++) { |
71 | bool isNew = true; | 138 | bool isNew = true; |
72 | uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { | 139 | uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { |
@@ -80,25 +147,8 @@ KAsync::Job<void> DummyResource::synchronizeWithSource() | |||
80 | if (isNew) { | 147 | if (isNew) { |
81 | m_fbb.Clear(); | 148 | m_fbb.Clear(); |
82 | 149 | ||
83 | const QByteArray data = it.value().toUtf8(); | ||
84 | auto eventBuffer = DummyCalendar::GetDummyEvent(data.data()); | ||
85 | |||
86 | //Map the source format to the buffer format (which happens to be an exact copy here) | ||
87 | auto summary = m_fbb.CreateString(eventBuffer->summary()->c_str()); | ||
88 | auto rid = m_fbb.CreateString(it.key().toStdString().c_str()); | ||
89 | auto description = m_fbb.CreateString(it.key().toStdString().c_str()); | ||
90 | static uint8_t rawData[100]; | ||
91 | auto attachment = Akonadi2::EntityBuffer::appendAsVector(m_fbb, rawData, 100); | ||
92 | |||
93 | auto builder = DummyCalendar::DummyEventBuilder(m_fbb); | ||
94 | builder.add_summary(summary); | ||
95 | builder.add_remoteId(rid); | ||
96 | builder.add_description(description); | ||
97 | builder.add_attachment(attachment); | ||
98 | auto buffer = builder.Finish(); | ||
99 | DummyCalendar::FinishDummyEventBuffer(m_fbb, buffer); | ||
100 | flatbuffers::FlatBufferBuilder entityFbb; | 150 | flatbuffers::FlatBufferBuilder entityFbb; |
101 | Akonadi2::EntityBuffer::assembleEntityBuffer(entityFbb, 0, 0, m_fbb.GetBufferPointer(), m_fbb.GetSize(), 0, 0); | 151 | createEvent(it.key().toUtf8(), it.value().toUtf8(), entityFbb); |
102 | 152 | ||
103 | flatbuffers::FlatBufferBuilder fbb; | 153 | flatbuffers::FlatBufferBuilder fbb; |
104 | //This is the resource type and not the domain type | 154 | //This is the resource type and not the domain type |
@@ -113,6 +163,43 @@ KAsync::Job<void> DummyResource::synchronizeWithSource() | |||
113 | } | 163 | } |
114 | } | 164 | } |
115 | //TODO find items to remove | 165 | //TODO find items to remove |
166 | |||
167 | const auto mails = DummyStore::instance().mails(); | ||
168 | for (auto it = mails.constBegin(); it != mails.constEnd(); it++) { | ||
169 | bool isNew = true; | ||
170 | uidIndex.lookup(it.key().toLatin1(), [&](const QByteArray &value) { | ||
171 | isNew = false; | ||
172 | }, | ||
173 | [](const Index::Error &error) { | ||
174 | if (error.code != Index::IndexNotAvailable) { | ||
175 | Warning() << "Error in uid index: " << error.message; | ||
176 | } | ||
177 | }); | ||
178 | if (isNew) { | ||
179 | m_fbb.Clear(); | ||
180 | |||
181 | flatbuffers::FlatBufferBuilder entityFbb; | ||
182 | createMail(it.key().toUtf8(), it.value().toUtf8(), entityFbb); | ||
183 | |||
184 | flatbuffers::Verifier verifyer(reinterpret_cast<const uint8_t *>(entityFbb.GetBufferPointer()), entityFbb.GetSize()); | ||
185 | if (!Akonadi2::ApplicationDomain::Buffer::VerifyMailBuffer(verifyer)) { | ||
186 | Warning() << "invalid buffer, not a mail buffer"; | ||
187 | } | ||
188 | |||
189 | flatbuffers::FlatBufferBuilder fbb; | ||
190 | //This is the resource type and not the domain type | ||
191 | auto type = fbb.CreateString(ENTITY_TYPE_MAIL); | ||
192 | auto delta = Akonadi2::EntityBuffer::appendAsVector(fbb, entityFbb.GetBufferPointer(), entityFbb.GetSize()); | ||
193 | auto location = Akonadi2::Commands::CreateCreateEntity(fbb, type, delta); | ||
194 | Akonadi2::Commands::FinishCreateEntityBuffer(fbb, location); | ||
195 | |||
196 | enqueueCommand(mSynchronizerQueue, Akonadi2::Commands::CreateEntityCommand, QByteArray::fromRawData(reinterpret_cast<char const *>(fbb.GetBufferPointer()), fbb.GetSize())); | ||
197 | } else { //modification | ||
198 | //TODO diff and create modification if necessary | ||
199 | } | ||
200 | } | ||
201 | //TODO find items to remove | ||
202 | |||
116 | f.setFinished(); | 203 | f.setFinished(); |
117 | }); | 204 | }); |
118 | } | 205 | } |
@@ -132,6 +219,7 @@ Akonadi2::Resource *DummyResourceFactory::createResource(const QByteArray &insta | |||
132 | void DummyResourceFactory::registerFacades(Akonadi2::FacadeFactory &factory) | 219 | void DummyResourceFactory::registerFacades(Akonadi2::FacadeFactory &factory) |
133 | { | 220 | { |
134 | factory.registerFacade<Akonadi2::ApplicationDomain::Event, DummyResourceFacade>(PLUGIN_NAME); | 221 | factory.registerFacade<Akonadi2::ApplicationDomain::Event, DummyResourceFacade>(PLUGIN_NAME); |
222 | factory.registerFacade<Akonadi2::ApplicationDomain::Mail, DummyResourceMailFacade>(PLUGIN_NAME); | ||
135 | } | 223 | } |
136 | 224 | ||
137 | #include "resourcefactory.moc" | 225 | #include "resourcefactory.moc" |