summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/domain/applicationdomaintype.cpp11
-rw-r--r--common/domain/applicationdomaintype.h13
-rw-r--r--common/resourceconfig.cpp93
-rw-r--r--common/resourceconfig.h12
-rw-r--r--common/resourcefacade.cpp99
-rw-r--r--common/resourcefacade.h11
-rw-r--r--docs/applicationdomaintypes.md46
7 files changed, 257 insertions, 28 deletions
diff --git a/common/domain/applicationdomaintype.cpp b/common/domain/applicationdomaintype.cpp
index df10327..462585e 100644
--- a/common/domain/applicationdomaintype.cpp
+++ b/common/domain/applicationdomaintype.cpp
@@ -141,6 +141,11 @@ SinkResource::~SinkResource()
141 141
142} 142}
143 143
144SinkAccount::~SinkAccount()
145{
146
147}
148
144template<> 149template<>
145QByteArray getTypeName<Event>() 150QByteArray getTypeName<Event>()
146{ 151{
@@ -160,6 +165,12 @@ QByteArray getTypeName<SinkResource>()
160} 165}
161 166
162template<> 167template<>
168QByteArray getTypeName<SinkAccount>()
169{
170 return "sinkaccount";
171}
172
173template<>
163QByteArray getTypeName<Mail>() 174QByteArray getTypeName<Mail>()
164{ 175{
165 return "mail"; 176 return "mail";
diff --git a/common/domain/applicationdomaintype.h b/common/domain/applicationdomaintype.h
index 32d8999..d17ad75 100644
--- a/common/domain/applicationdomaintype.h
+++ b/common/domain/applicationdomaintype.h
@@ -135,7 +135,7 @@ struct SINK_EXPORT Folder : public Entity {
135 135
136/** 136/**
137 * Represents an sink resource. 137 * Represents an sink resource.
138 * 138 *
139 * This type is used for configuration of resources, 139 * This type is used for configuration of resources,
140 * and for creating and removing resource instances. 140 * and for creating and removing resource instances.
141 */ 141 */
@@ -145,6 +145,12 @@ struct SINK_EXPORT SinkResource : public ApplicationDomainType {
145 virtual ~SinkResource(); 145 virtual ~SinkResource();
146}; 146};
147 147
148struct SINK_EXPORT SinkAccount : public ApplicationDomainType {
149 typedef QSharedPointer<SinkAccount> Ptr;
150 using ApplicationDomainType::ApplicationDomainType;
151 virtual ~SinkAccount();
152};
153
148/** 154/**
149 * All types need to be registered here an MUST return a different name. 155 * All types need to be registered here an MUST return a different name.
150 * 156 *
@@ -163,6 +169,9 @@ template<>
163QByteArray SINK_EXPORT getTypeName<SinkResource>(); 169QByteArray SINK_EXPORT getTypeName<SinkResource>();
164 170
165template<> 171template<>
172QByteArray SINK_EXPORT getTypeName<SinkAccount>();
173
174template<>
166QByteArray SINK_EXPORT getTypeName<Mail>(); 175QByteArray SINK_EXPORT getTypeName<Mail>();
167 176
168template<> 177template<>
@@ -192,3 +201,5 @@ Q_DECLARE_METATYPE(Sink::ApplicationDomain::Folder)
192Q_DECLARE_METATYPE(Sink::ApplicationDomain::Folder::Ptr) 201Q_DECLARE_METATYPE(Sink::ApplicationDomain::Folder::Ptr)
193Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkResource) 202Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkResource)
194Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkResource::Ptr) 203Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkResource::Ptr)
204Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkAccount)
205Q_DECLARE_METATYPE(Sink::ApplicationDomain::SinkAccount::Ptr)
diff --git a/common/resourceconfig.cpp b/common/resourceconfig.cpp
index b988718..4b33990 100644
--- a/common/resourceconfig.cpp
+++ b/common/resourceconfig.cpp
@@ -23,19 +23,20 @@
23#include <QStandardPaths> 23#include <QStandardPaths>
24#include <QFile> 24#include <QFile>
25 25
26static QSharedPointer<QSettings> getSettings() 26static QSharedPointer<QSettings> getConfig(const QByteArray &identifier)
27{ 27{
28 return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/resources.ini", QSettings::IniFormat); 28 return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/" + identifier + ".ini", QSettings::IniFormat);
29} 29}
30 30
31static QSharedPointer<QSettings> getResourceConfig(const QByteArray &identifier) 31static QSharedPointer<QSettings> getSettings()
32{ 32{
33 return QSharedPointer<QSettings>::create(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/sink/" + identifier, QSettings::IniFormat); 33 return getConfig("resources");
34} 34}
35 35
36
36QByteArray ResourceConfig::newIdentifier(const QByteArray &type) 37QByteArray ResourceConfig::newIdentifier(const QByteArray &type)
37{ 38{
38 auto settings = getSettings(); 39 auto settings = getConfig("resources");
39 const auto counter = settings->value("instanceCounter", 0).toInt() + 1; 40 const auto counter = settings->value("instanceCounter", 0).toInt() + 1;
40 const QByteArray identifier = type + ".instance" + QByteArray::number(counter); 41 const QByteArray identifier = type + ".instance" + QByteArray::number(counter);
41 settings->setValue("instanceCounter", counter); 42 settings->setValue("instanceCounter", counter);
@@ -45,7 +46,7 @@ QByteArray ResourceConfig::newIdentifier(const QByteArray &type)
45 46
46void ResourceConfig::addResource(const QByteArray &identifier, const QByteArray &type) 47void ResourceConfig::addResource(const QByteArray &identifier, const QByteArray &type)
47{ 48{
48 auto settings = getSettings(); 49 auto settings = getConfig("resources");
49 settings->beginGroup(QString::fromLatin1(identifier)); 50 settings->beginGroup(QString::fromLatin1(identifier));
50 settings->setValue("type", type); 51 settings->setValue("type", type);
51 settings->endGroup(); 52 settings->endGroup();
@@ -54,18 +55,18 @@ void ResourceConfig::addResource(const QByteArray &identifier, const QByteArray
54 55
55void ResourceConfig::removeResource(const QByteArray &identifier) 56void ResourceConfig::removeResource(const QByteArray &identifier)
56{ 57{
57 auto settings = getSettings(); 58 auto settings = getConfig("resources");
58 settings->beginGroup(QString::fromLatin1(identifier)); 59 settings->beginGroup(QString::fromLatin1(identifier));
59 settings->remove(""); 60 settings->remove("");
60 settings->endGroup(); 61 settings->endGroup();
61 settings->sync(); 62 settings->sync();
62 QFile::remove(getResourceConfig(identifier)->fileName()); 63 QFile::remove(getConfig(identifier)->fileName());
63} 64}
64 65
65QMap<QByteArray, QByteArray> ResourceConfig::getResources() 66QMap<QByteArray, QByteArray> ResourceConfig::getResources()
66{ 67{
67 QMap<QByteArray, QByteArray> resources; 68 QMap<QByteArray, QByteArray> resources;
68 auto settings = getSettings(); 69 auto settings = getConfig("resources");
69 for (const auto &identifier : settings->childGroups()) { 70 for (const auto &identifier : settings->childGroups()) {
70 settings->beginGroup(identifier); 71 settings->beginGroup(identifier);
71 const auto type = settings->value("type").toByteArray(); 72 const auto type = settings->value("type").toByteArray();
@@ -84,7 +85,7 @@ void ResourceConfig::clear()
84 85
85void ResourceConfig::configureResource(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration) 86void ResourceConfig::configureResource(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration)
86{ 87{
87 auto config = getResourceConfig(identifier); 88 auto config = getConfig(identifier);
88 config->clear(); 89 config->clear();
89 for (const auto &key : configuration.keys()) { 90 for (const auto &key : configuration.keys()) {
90 config->setValue(key, configuration.value(key)); 91 config->setValue(key, configuration.value(key));
@@ -95,7 +96,77 @@ void ResourceConfig::configureResource(const QByteArray &identifier, const QMap<
95QMap<QByteArray, QVariant> ResourceConfig::getConfiguration(const QByteArray &identifier) 96QMap<QByteArray, QVariant> ResourceConfig::getConfiguration(const QByteArray &identifier)
96{ 97{
97 QMap<QByteArray, QVariant> configuration; 98 QMap<QByteArray, QVariant> configuration;
98 auto config = getResourceConfig(identifier); 99 auto config = getConfig(identifier);
100 for (const auto &key : config->allKeys()) {
101 configuration.insert(key.toLatin1(), config->value(key));
102 }
103 return configuration;
104}
105
106
107QByteArray AccountConfig::newIdentifier(const QByteArray &type)
108{
109 auto settings = getConfig("accounts");
110 const auto counter = settings->value("instanceCounter", 0).toInt() + 1;
111 const QByteArray identifier = type + ".instance" + QByteArray::number(counter);
112 settings->setValue("instanceCounter", counter);
113 settings->sync();
114 return identifier;
115}
116
117void AccountConfig::addAccount(const QByteArray &identifier, const QByteArray &type)
118{
119 auto settings = getConfig("accounts");
120 settings->beginGroup(QString::fromLatin1(identifier));
121 settings->setValue("type", type);
122 settings->endGroup();
123 settings->sync();
124}
125
126void AccountConfig::removeAccount(const QByteArray &identifier)
127{
128 auto settings = getConfig("accounts");
129 settings->beginGroup(QString::fromLatin1(identifier));
130 settings->remove("");
131 settings->endGroup();
132 settings->sync();
133 QFile::remove(getConfig(identifier)->fileName());
134}
135
136QMap<QByteArray, QByteArray> AccountConfig::getAccounts()
137{
138 QMap<QByteArray, QByteArray> accounts;
139 auto settings = getConfig("accounts");
140 for (const auto &identifier : settings->childGroups()) {
141 settings->beginGroup(identifier);
142 const auto type = settings->value("type").toByteArray();
143 accounts.insert(identifier.toLatin1(), type);
144 settings->endGroup();
145 }
146 return accounts;
147}
148
149void AccountConfig::clear()
150{
151 auto settings = getSettings();
152 settings->clear();
153 settings->sync();
154}
155
156void AccountConfig::configureAccount(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration)
157{
158 auto config = getConfig(identifier);
159 config->clear();
160 for (const auto &key : configuration.keys()) {
161 config->setValue(key, configuration.value(key));
162 }
163 config->sync();
164}
165
166QMap<QByteArray, QVariant> AccountConfig::getConfiguration(const QByteArray &identifier)
167{
168 QMap<QByteArray, QVariant> configuration;
169 auto config = getConfig(identifier);
99 for (const auto &key : config->allKeys()) { 170 for (const auto &key : config->allKeys()) {
100 configuration.insert(key.toLatin1(), config->value(key)); 171 configuration.insert(key.toLatin1(), config->value(key));
101 } 172 }
diff --git a/common/resourceconfig.h b/common/resourceconfig.h
index 2108caa..505b5ec 100644
--- a/common/resourceconfig.h
+++ b/common/resourceconfig.h
@@ -36,3 +36,15 @@ public:
36 static void configureResource(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration); 36 static void configureResource(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration);
37 static QMap<QByteArray, QVariant> getConfiguration(const QByteArray &identifier); 37 static QMap<QByteArray, QVariant> getConfiguration(const QByteArray &identifier);
38}; 38};
39
40class SINK_EXPORT AccountConfig
41{
42public:
43 static QMap<QByteArray, QByteArray> getAccounts();
44 static QByteArray newIdentifier(const QByteArray &type);
45 static void addAccount(const QByteArray &identifier, const QByteArray &type);
46 static void removeAccount(const QByteArray &identifier);
47 static void clear();
48 static void configureAccount(const QByteArray &identifier, const QMap<QByteArray, QVariant> &configuration);
49 static QMap<QByteArray, QVariant> getConfiguration(const QByteArray &identifier);
50};
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp
index 3095c2e..d91c974 100644
--- a/common/resourcefacade.cpp
+++ b/common/resourcefacade.cpp
@@ -126,3 +126,102 @@ QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::S
126 }); 126 });
127 return qMakePair(job, emitter); 127 return qMakePair(job, emitter);
128} 128}
129
130
131AccountFacade::AccountFacade(const QByteArray &) : Sink::StoreFacade<Sink::ApplicationDomain::SinkAccount>()
132{
133}
134
135AccountFacade::~AccountFacade()
136{
137}
138
139KAsync::Job<void> AccountFacade::create(const Sink::ApplicationDomain::SinkAccount &account)
140{
141 return KAsync::start<void>([account, this]() {
142 const QByteArray type = account.getProperty("type").toByteArray();
143 const QByteArray providedIdentifier = account.getProperty("identifier").toByteArray();
144 // It is currently a requirement that the account starts with the type
145 const QByteArray identifier = providedIdentifier.isEmpty() ? AccountConfig::newIdentifier(type) : providedIdentifier;
146 AccountConfig::addAccount(identifier, type);
147 auto changedProperties = account.changedProperties();
148 changedProperties.removeOne("identifier");
149 changedProperties.removeOne("type");
150 if (!changedProperties.isEmpty()) {
151 // We have some configuration values
152 QMap<QByteArray, QVariant> configurationValues;
153 for (const auto &property : changedProperties) {
154 configurationValues.insert(property, account.getProperty(property));
155 }
156 AccountConfig::configureAccount(identifier, configurationValues);
157 }
158 });
159}
160
161KAsync::Job<void> AccountFacade::modify(const Sink::ApplicationDomain::SinkAccount &account)
162{
163 return KAsync::start<void>([account, this]() {
164 const QByteArray identifier = account.identifier();
165 if (identifier.isEmpty()) {
166 Warning() << "We need an \"identifier\" property to identify the account to configure.";
167 return;
168 }
169 auto changedProperties = account.changedProperties();
170 changedProperties.removeOne("identifier");
171 changedProperties.removeOne("type");
172 if (!changedProperties.isEmpty()) {
173 // We have some configuration values
174 QMap<QByteArray, QVariant> configurationValues;
175 for (const auto &property : changedProperties) {
176 configurationValues.insert(property, account.getProperty(property));
177 }
178 AccountConfig::configureAccount(identifier, configurationValues);
179 }
180 });
181}
182
183KAsync::Job<void> AccountFacade::remove(const Sink::ApplicationDomain::SinkAccount &account)
184{
185 return KAsync::start<void>([account, this]() {
186 const QByteArray identifier = account.identifier();
187 if (identifier.isEmpty()) {
188 Warning() << "We need an \"identifier\" property to identify the account to configure";
189 return;
190 }
191 AccountConfig::removeAccount(identifier);
192 });
193}
194
195QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::SinkAccount::Ptr>::Ptr> AccountFacade::load(const Sink::Query &query)
196{
197 auto resultProvider = new Sink::ResultProvider<typename Sink::ApplicationDomain::SinkAccount::Ptr>();
198 auto emitter = resultProvider->emitter();
199 resultProvider->setFetcher([](const QSharedPointer<Sink::ApplicationDomain::SinkAccount> &) {});
200 resultProvider->onDone([resultProvider]() { delete resultProvider; });
201 auto job = KAsync::start<void>([query, resultProvider]() {
202 const auto configuredAccounts = AccountConfig::getAccounts();
203 for (const auto &res : configuredAccounts.keys()) {
204 const auto type = configuredAccounts.value(res);
205 if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").toByteArray() != type) {
206 continue;
207 }
208 if (!query.ids.isEmpty() && !query.ids.contains(res)) {
209 continue;
210 }
211
212 auto account = Sink::ApplicationDomain::SinkAccount::Ptr::create("", res, 0, QSharedPointer<Sink::ApplicationDomain::MemoryBufferAdaptor>::create());
213 account->setProperty("type", type);
214
215 const auto configurationValues = AccountConfig::getConfiguration(res);
216 for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) {
217 account->setProperty(it.key(), it.value());
218 }
219
220 resultProvider->add(account);
221 }
222 // TODO initialResultSetComplete should be implicit
223 resultProvider->initialResultSetComplete(Sink::ApplicationDomain::SinkAccount::Ptr());
224 resultProvider->complete();
225 });
226 return qMakePair(job, emitter);
227}
diff --git a/common/resourcefacade.h b/common/resourcefacade.h
index 3de0e25..48ff2a5 100644
--- a/common/resourcefacade.h
+++ b/common/resourcefacade.h
@@ -40,3 +40,14 @@ public:
40 KAsync::Job<void> remove(const Sink::ApplicationDomain::SinkResource &resource) Q_DECL_OVERRIDE; 40 KAsync::Job<void> remove(const Sink::ApplicationDomain::SinkResource &resource) Q_DECL_OVERRIDE;
41 QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::SinkResource::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; 41 QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::SinkResource::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE;
42}; 42};
43
44class AccountFacade : public Sink::StoreFacade<Sink::ApplicationDomain::SinkAccount>
45{
46public:
47 AccountFacade(const QByteArray &instanceIdentifier);
48 virtual ~AccountFacade();
49 KAsync::Job<void> create(const Sink::ApplicationDomain::SinkAccount &resource) Q_DECL_OVERRIDE;
50 KAsync::Job<void> modify(const Sink::ApplicationDomain::SinkAccount &resource) Q_DECL_OVERRIDE;
51 KAsync::Job<void> remove(const Sink::ApplicationDomain::SinkAccount &resource) Q_DECL_OVERRIDE;
52 QPair<KAsync::Job<void>, typename Sink::ResultEmitter<Sink::ApplicationDomain::SinkAccount::Ptr>::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE;
53};
diff --git a/docs/applicationdomaintypes.md b/docs/applicationdomaintypes.md
index 798fa13..56e3032 100644
--- a/docs/applicationdomaintypes.md
+++ b/docs/applicationdomaintypes.md
@@ -9,7 +9,7 @@ The definition of the domain model directly affects:
9The purpose of these domain types is strictly to be the interface and the types are not meant to be used by applications directly, or to be restricted by any other specifications (such as ical). By nature these types will be part of the evolving interface, and will need to be adjusted for every new property that an application accesses. 9The purpose of these domain types is strictly to be the interface and the types are not meant to be used by applications directly, or to be restricted by any other specifications (such as ical). By nature these types will be part of the evolving interface, and will need to be adjusted for every new property that an application accesses.
10 10
11### Application Domain Types 11### Application Domain Types
12This is a proposed set of types that we will need to evolve into what we actually require. Hierarchical types are required to be able to query for a result set of mixed types. 12This is the currently defined set of types. Hierarchical types are required to be able to query for a result set of mixed types, but are not necessarily structured as such in the inheritance model.
13 13
14* Entity 14* Entity
15 * Domain Object 15 * Domain Object
@@ -34,40 +34,54 @@ This is a proposed set of types that we will need to evolve into what we actuall
34 * Thread 34 * Thread
35 * Sink Resource 35 * Sink Resource
36 * Maildir Resource 36 * Maildir Resource
37 * IMAP Resource
38 * Account
37 39
38#### Properties 40#### Properties
39```no-highlight 41```no-highlight
40Entity: The smallest unit in the sink universe 42Entity: The smallest unit in the sink universe
41 id: unique identifier in the sink storage. Not persistant over db recreations and can therefore only be referenced from within the sink database. 43 id [QByteArray]: unique identifier in the sink storage. Not persistant over db recreations and can therefore only be referenced from within the sink database.
42``` 44```
43```no-highlight 45```no-highlight
44Domain Object: 46Domain Object:
45 uid: unique identifier of the domain object. 47 uid [QByteArray}: unique identifier of the domain object.
46 revision: revision of the entity 48 revision [int]: revision of the entity
47 resource: reference to SinkResource:id of the parent resource. 49 resource [SinkResource.id]: The parent resource.
48``` 50```
49```no-highlight 51```no-highlight
50Event: 52Event:
51 summary: A string containing a short summary of the event. 53 summary [QString]: A string containing a short summary of the event.
52 startDate: The start date of the event. 54 startDate [QDateTime]: The start date of the event.
53 startTime: The start time of the event. Optional. 55 startTime [QDateTime]: The start time of the event. Optional.
54``` 56```
55```no-highlight 57```no-highlight
56Mail: 58Mail:
57 uid: The message id. 59 uid [QByteArray]: The message id.
58 subject: The subject of the email. 60 subject [QString]: The subject of the email.
59 folder: The identifier of the parent folder. 61 folder [MailFolder.id]: The parent folder.
60 date: The date of the email. 62 date [QDateTime]: The date of the email.
61 mimeMessage: A string containing the path to the mime message 63 mimeMessage [QString]: A string containing the path to the mime message
64```
65```no-highlight
66Mail Folder:
67 parent [MailFolder.id]: The parent folder.
68 name [QString]: The user visible name of the folder.
69 icon [QString]: The name of the icon of the folder.
62``` 70```
63```no-highlight 71```no-highlight
64Sink Resource: 72Sink Resource:
65 type: The type of the resource. 73 type [QByteArray]: The type of the resource.
66 name: The name of the resource. 74 name [QString]: The name of the resource.
75 account [Account.id]: The identifier of the associated account.
67``` 76```
68```no-highlight 77```no-highlight
69Maildir Resource: 78Maildir Resource:
70 path: The path to the maildir. 79 path [QString]: The path to the maildir.
80```
81```no-highlight
82Account:
83 name [QString]: The name of the account.
84 icon [QString]: The name of the icon of the account.
71``` 85```
72 86
73### References/Hierachies 87### References/Hierachies