File indexing completed on 2024-05-26 05:27:46
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm> 0004 * 0005 * This program is free software; you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation; either version 2 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program; if not, write to the 0017 * Free Software Foundation, Inc., 0018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 0019 */ 0020 0021 #include "resourcefactory.h" 0022 #include "facade.h" 0023 #include "entitybuffer.h" 0024 #include "pipeline.h" 0025 #include "dummycalendar_generated.h" 0026 #include "mail_generated.h" 0027 #include "domainadaptor.h" 0028 #include "log.h" 0029 #include "dummystore.h" 0030 #include "definitions.h" 0031 #include "facadefactory.h" 0032 #include "adaptorfactoryregistry.h" 0033 #include "synchronizer.h" 0034 #include "inspector.h" 0035 #include "mailpreprocessor.h" 0036 #include "eventpreprocessor.h" 0037 #include "todopreprocessor.h" 0038 #include "contactpreprocessor.h" 0039 #include "specialpurposepreprocessor.h" 0040 #include "resourceconfig.h" 0041 #include <QDate> 0042 0043 //This is the resources entity type, and not the domain type 0044 #define ENTITY_TYPE_EVENT "event" 0045 #define ENTITY_TYPE_TODO "todo" 0046 #define ENTITY_TYPE_CALENDAR "calendar" 0047 #define ENTITY_TYPE_ADDRESSBOOK "addressbook" 0048 #define ENTITY_TYPE_CONTACT "contact" 0049 #define ENTITY_TYPE_MAIL "mail" 0050 #define ENTITY_TYPE_FOLDER "folder" 0051 0052 using namespace Sink; 0053 0054 class DummySynchronizer : public Sink::Synchronizer { 0055 public: 0056 0057 DummySynchronizer(const Sink::ResourceContext &context) 0058 : Sink::Synchronizer(context) 0059 { 0060 setSecret("dummy"); 0061 auto config = ResourceConfig::getConfiguration(context.instanceId()); 0062 if (config.value("populate", false).toBool()) { 0063 DummyStore::instance().populate(); 0064 } 0065 } 0066 0067 Sink::ApplicationDomain::Event::Ptr createEvent(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) 0068 { 0069 auto event = Sink::ApplicationDomain::Event::Ptr::create(); 0070 event->setExtractedUid(data.value("uid").toString()); 0071 event->setExtractedSummary(data.value("summary").toString()); 0072 event->setExtractedDescription(data.value("description").toString()); 0073 event->setExtractedStartTime(data.value("starttime").toDateTime()); 0074 event->setExtractedEndTime(data.value("endtime").toDateTime()); 0075 event->setProperty("remoteId", ridBuffer); 0076 return event; 0077 } 0078 0079 Sink::ApplicationDomain::Mail::Ptr createMail(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) 0080 { 0081 auto mail = Sink::ApplicationDomain::Mail::Ptr::create(); 0082 mail->setExtractedMessageId(ridBuffer); 0083 mail->setExtractedSubject(data.value("subject").toString()); 0084 mail->setExtractedSender(Sink::ApplicationDomain::Mail::Contact{data.value("senderName").toString(), data.value("senderEmail").toString()}); 0085 mail->setExtractedDate(data.value("date").toDateTime()); 0086 mail->setFolder(syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, data.value("parentFolder").toByteArray())); 0087 mail->setUnread(data.value("unread").toBool()); 0088 mail->setImportant(data.value("important").toBool()); 0089 return mail; 0090 } 0091 0092 Sink::ApplicationDomain::Folder::Ptr createFolder(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) 0093 { 0094 auto folder = Sink::ApplicationDomain::Folder::Ptr::create(); 0095 folder->setName(data.value("name").toString()); 0096 folder->setIcon(data.value("icon").toByteArray()); 0097 if (!data.value("parent").toString().isEmpty()) { 0098 auto sinkId = syncStore().resolveRemoteId(ENTITY_TYPE_FOLDER, data.value("parent").toByteArray()); 0099 folder->setParent(sinkId); 0100 } 0101 return folder; 0102 } 0103 0104 void synchronize(const QByteArray &bufferType, const QMap<QString, QMap<QString, QVariant> > &data, std::function<Sink::ApplicationDomain::ApplicationDomainType::Ptr(const QByteArray &ridBuffer, const QMap<QString, QVariant> &data)> createEntity) 0105 { 0106 auto time = QSharedPointer<QTime>::create(); 0107 time->start(); 0108 //TODO find items to remove 0109 int count = 0; 0110 for (auto it = data.constBegin(); it != data.constEnd(); it++) { 0111 count++; 0112 const auto remoteId = it.key().toUtf8(); 0113 auto entity = createEntity(remoteId, it.value()); 0114 createOrModify(bufferType, remoteId, *entity); 0115 } 0116 SinkTrace() << "Sync of " << count << " entities of type " << bufferType << " done." << Sink::Log::TraceTime(time->elapsed()); 0117 } 0118 0119 KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &) Q_DECL_OVERRIDE 0120 { 0121 SinkLog() << " Synchronizing with the source"; 0122 SinkTrace() << "Synchronize with source and sending a notification about it"; 0123 Sink::Notification n; 0124 n.id = "connected"; 0125 n.type = Sink::Notification::Status; 0126 n.message = "We're connected"; 0127 n.code = Sink::ApplicationDomain::ConnectedStatus; 0128 emit notify(n); 0129 return KAsync::start([this]() { 0130 synchronize(ENTITY_TYPE_EVENT, DummyStore::instance().events(), [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) { 0131 return createEvent(ridBuffer, data); 0132 }); 0133 synchronize(ENTITY_TYPE_MAIL, DummyStore::instance().mails(), [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) { 0134 return createMail(ridBuffer, data); 0135 }); 0136 synchronize(ENTITY_TYPE_FOLDER, DummyStore::instance().folders(), [this](const QByteArray &ridBuffer, const QMap<QString, QVariant> &data) { 0137 return createFolder(ridBuffer, data); 0138 }); 0139 }); 0140 } 0141 0142 bool canReplay(const QByteArray &type, const QByteArray &key, const QByteArray &value) Q_DECL_OVERRIDE { return false; } 0143 0144 }; 0145 0146 class DummyInspector : public Sink::Inspector { 0147 public: 0148 DummyInspector(const Sink::ResourceContext &resourceContext) 0149 : Sink::Inspector(resourceContext) 0150 { 0151 0152 } 0153 0154 protected: 0155 KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expectedValue) Q_DECL_OVERRIDE 0156 { 0157 SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << property << expectedValue; 0158 if (property == "testInspection") { 0159 if (expectedValue.toBool()) { 0160 //Success 0161 return KAsync::null<void>(); 0162 } else { 0163 //Failure 0164 return KAsync::error<void>(1, "Failed."); 0165 } 0166 } 0167 return KAsync::null<void>(); 0168 } 0169 }; 0170 0171 DummyResource::DummyResource(const Sink::ResourceContext &resourceContext, const QSharedPointer<Sink::Pipeline> &pipeline) 0172 : Sink::GenericResource(resourceContext, pipeline) 0173 { 0174 setupSynchronizer(QSharedPointer<DummySynchronizer>::create(resourceContext)); 0175 setupInspector(QSharedPointer<DummyInspector>::create(resourceContext)); 0176 setupPreprocessors(ENTITY_TYPE_MAIL, {new MailPropertyExtractor, new SpecialPurposeProcessor}); 0177 setupPreprocessors(ENTITY_TYPE_FOLDER, {}); 0178 setupPreprocessors(ENTITY_TYPE_EVENT, {new EventPropertyExtractor}); 0179 setupPreprocessors(ENTITY_TYPE_TODO, {new TodoPropertyExtractor}); 0180 setupPreprocessors(ENTITY_TYPE_CALENDAR, {}); 0181 setupPreprocessors(ENTITY_TYPE_CONTACT, {new ContactPropertyExtractor}); 0182 setupPreprocessors(ENTITY_TYPE_ADDRESSBOOK, {}); 0183 } 0184 0185 DummyResource::~DummyResource() 0186 { 0187 0188 } 0189 0190 DummyResourceFactory::DummyResourceFactory(QObject *parent) 0191 : Sink::ResourceFactory(parent, { 0192 Sink::ApplicationDomain::ResourceCapabilities::Todo::todo, 0193 Sink::ApplicationDomain::ResourceCapabilities::Todo::calendar, 0194 Sink::ApplicationDomain::ResourceCapabilities::Todo::storage, 0195 Sink::ApplicationDomain::ResourceCapabilities::Event::event, 0196 Sink::ApplicationDomain::ResourceCapabilities::Event::calendar, 0197 Sink::ApplicationDomain::ResourceCapabilities::Event::storage, 0198 Sink::ApplicationDomain::ResourceCapabilities::Contact::contact, 0199 Sink::ApplicationDomain::ResourceCapabilities::Contact::addressbook, 0200 Sink::ApplicationDomain::ResourceCapabilities::Contact::storage, 0201 Sink::ApplicationDomain::ResourceCapabilities::Mail::mail, 0202 Sink::ApplicationDomain::ResourceCapabilities::Mail::folder, 0203 Sink::ApplicationDomain::ResourceCapabilities::Mail::storage, 0204 Sink::ApplicationDomain::ResourceCapabilities::Mail::drafts, 0205 "-folder.rename", 0206 Sink::ApplicationDomain::ResourceCapabilities::Mail::sent} 0207 ) 0208 { 0209 0210 } 0211 0212 Sink::Resource *DummyResourceFactory::createResource(const Sink::ResourceContext &resourceContext) 0213 { 0214 return new DummyResource(resourceContext); 0215 } 0216 0217 void DummyResourceFactory::registerFacades(const QByteArray &resourceName, Sink::FacadeFactory &factory) 0218 { 0219 using namespace Sink::ApplicationDomain; 0220 factory.registerFacade<Contact, DefaultFacade<Contact>>(resourceName); 0221 factory.registerFacade<Addressbook, DefaultFacade<Addressbook>>(resourceName); 0222 factory.registerFacade<Todo, DefaultFacade<Todo>>(resourceName); 0223 factory.registerFacade<Event, DefaultFacade<Event>>(resourceName); 0224 factory.registerFacade<Calendar, DefaultFacade<Calendar>>(resourceName); 0225 factory.registerFacade<Mail, DefaultFacade<Mail>>(resourceName); 0226 factory.registerFacade<Folder, DefaultFacade<Folder>>(resourceName); 0227 } 0228 0229 void DummyResourceFactory::registerAdaptorFactories(const QByteArray &resourceName, Sink::AdaptorFactoryRegistry ®istry) 0230 { 0231 using namespace Sink::ApplicationDomain; 0232 registry.registerFactory<Contact, DomainTypeAdaptorFactory<Contact>>(resourceName); 0233 registry.registerFactory<Addressbook, DomainTypeAdaptorFactory<Addressbook>>(resourceName); 0234 registry.registerFactory<Todo, DomainTypeAdaptorFactory<Todo>>(resourceName); 0235 registry.registerFactory<Event, DomainTypeAdaptorFactory<Event>>(resourceName); 0236 registry.registerFactory<Calendar, DomainTypeAdaptorFactory<Calendar>>(resourceName); 0237 registry.registerFactory<Mail, DomainTypeAdaptorFactory<Mail>>(resourceName); 0238 registry.registerFactory<Folder, DomainTypeAdaptorFactory<Folder>>(resourceName); 0239 } 0240 0241 void DummyResourceFactory::removeDataFromDisk(const QByteArray &instanceIdentifier) 0242 { 0243 DummyResource::removeFromDisk(instanceIdentifier); 0244 } 0245