diff options
author | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-07-06 09:57:51 +0200 |
---|---|---|
committer | Christian Mollekopf <chrigi_1@fastmail.fm> | 2016-07-06 09:57:51 +0200 |
commit | a9f3692a0bceb796d10952307f87fdb77abadbf7 (patch) | |
tree | dc66407c956cdf7538a6fb9f4dd17334ae3530e2 /common/resourcefacade.cpp | |
parent | e03eac8ef4337a9aa538b7cefc803a6abd4acf24 (diff) | |
download | sink-a9f3692a0bceb796d10952307f87fdb77abadbf7.tar.gz sink-a9f3692a0bceb796d10952307f87fdb77abadbf7.zip |
Apply the status to resources
Diffstat (limited to 'common/resourcefacade.cpp')
-rw-r--r-- | common/resourcefacade.cpp | 238 |
1 files changed, 168 insertions, 70 deletions
diff --git a/common/resourcefacade.cpp b/common/resourcefacade.cpp index 3901f43..f6fd7ca 100644 --- a/common/resourcefacade.cpp +++ b/common/resourcefacade.cpp | |||
@@ -22,37 +22,168 @@ | |||
22 | #include "query.h" | 22 | #include "query.h" |
23 | #include "definitions.h" | 23 | #include "definitions.h" |
24 | #include "storage.h" | 24 | #include "storage.h" |
25 | #include "resourceaccess.h" | ||
25 | #include <QDir> | 26 | #include <QDir> |
26 | 27 | ||
27 | template <typename DomainType> | 28 | using namespace Sink; |
29 | |||
30 | template<typename DomainType> | ||
28 | ConfigNotifier LocalStorageFacade<DomainType>::sConfigNotifier; | 31 | ConfigNotifier LocalStorageFacade<DomainType>::sConfigNotifier; |
29 | 32 | ||
30 | template <typename DomainType> | 33 | template <typename DomainType> |
31 | LocalStorageFacade<DomainType>::LocalStorageFacade(const QByteArray &identifier) : Sink::StoreFacade<DomainType>(), mConfigStore(identifier), mResourceInstanceIdentifier(identifier) | 34 | static typename DomainType::Ptr readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type) |
32 | { | 35 | { |
36 | auto object = DomainType::Ptr::create(id); | ||
37 | object->setProperty("type", type); | ||
38 | const auto configurationValues = configStore.get(id); | ||
39 | for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { | ||
40 | object->setProperty(it.key(), it.value()); | ||
41 | } | ||
42 | return object; | ||
33 | } | 43 | } |
34 | 44 | ||
45 | static bool matchesFilter(const QHash<QByteArray, Query::Comparator> &filter, const QMap<QByteArray, QVariant> &properties) | ||
46 | { | ||
47 | for (const auto &filterProperty : filter.keys()) { | ||
48 | if (filterProperty == "type") { | ||
49 | continue; | ||
50 | } | ||
51 | if (!filter.value(filterProperty).matches(properties.value(filterProperty))) { | ||
52 | return false; | ||
53 | } | ||
54 | } | ||
55 | return true; | ||
56 | } | ||
57 | |||
58 | template<typename DomainType> | ||
59 | LocalStorageQueryRunner<DomainType>::LocalStorageQueryRunner(const Query &query, const QByteArray &identifier, ConfigNotifier &configNotifier) | ||
60 | : mResultProvider(new ResultProvider<typename DomainType::Ptr>), mConfigStore(identifier) | ||
61 | { | ||
62 | QObject *guard = new QObject; | ||
63 | mResultProvider->setFetcher([this, query, guard, &configNotifier](const QSharedPointer<DomainType> &) { | ||
64 | const auto entries = mConfigStore.getEntries(); | ||
65 | for (const auto &res : entries.keys()) { | ||
66 | const auto type = entries.value(res); | ||
67 | |||
68 | if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { | ||
69 | Trace() << "Skipping due to type."; | ||
70 | continue; | ||
71 | } | ||
72 | if (!query.ids.isEmpty() && !query.ids.contains(res)) { | ||
73 | continue; | ||
74 | } | ||
75 | const auto configurationValues = mConfigStore.get(res); | ||
76 | if (!matchesFilter(query.propertyFilter, configurationValues)){ | ||
77 | Trace() << "Skipping due to filter."; | ||
78 | continue; | ||
79 | } | ||
80 | Trace() << "Found match " << res; | ||
81 | auto entity = readFromConfig<DomainType>(mConfigStore, res, type); | ||
82 | updateStatus(*entity); | ||
83 | mResultProvider->add(entity); | ||
84 | } | ||
85 | if (query.liveQuery) { | ||
86 | { | ||
87 | auto ret = QObject::connect(&configNotifier, &ConfigNotifier::added, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
88 | auto entity = entry.staticCast<DomainType>(); | ||
89 | updateStatus(*entity); | ||
90 | mResultProvider->add(entity); | ||
91 | }); | ||
92 | Q_ASSERT(ret); | ||
93 | } | ||
94 | { | ||
95 | auto ret = QObject::connect(&configNotifier, &ConfigNotifier::modified, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
96 | auto entity = entry.staticCast<DomainType>(); | ||
97 | updateStatus(*entity); | ||
98 | mResultProvider->modify(entity); | ||
99 | }); | ||
100 | Q_ASSERT(ret); | ||
101 | } | ||
102 | { | ||
103 | auto ret = QObject::connect(&configNotifier, &ConfigNotifier::removed, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
104 | mResultProvider->remove(entry.staticCast<DomainType>()); | ||
105 | }); | ||
106 | Q_ASSERT(ret); | ||
107 | } | ||
108 | } | ||
109 | // TODO initialResultSetComplete should be implicit | ||
110 | mResultProvider->initialResultSetComplete(typename DomainType::Ptr()); | ||
111 | mResultProvider->complete(); | ||
112 | }); | ||
113 | mResultProvider->onDone([=]() { delete guard; }); | ||
114 | } | ||
115 | |||
116 | // QByteArrayList getMatchingEntries(const Query &query) | ||
117 | // { | ||
118 | // const auto entries = mConfigStore.getEntries(); | ||
119 | // for (const auto &res : entries.keys()) { | ||
120 | // const auto type = entries.value(res); | ||
121 | // | ||
122 | // if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { | ||
123 | // Trace() << "Skipping due to type."; | ||
124 | // continue; | ||
125 | // } | ||
126 | // if (!query.ids.isEmpty() && !query.ids.contains(res)) { | ||
127 | // continue; | ||
128 | // } | ||
129 | // const auto configurationValues = mConfigStore.get(res); | ||
130 | // if (!matchesFilter(query.propertyFilter, configurationValues)){ | ||
131 | // Trace() << "Skipping due to filter."; | ||
132 | // continue; | ||
133 | // } | ||
134 | // Trace() << "Found match " << res; | ||
135 | // auto entity = readFromConfig<DomainType>(mConfigStore, res, type); | ||
136 | // updateStatus(*entity); | ||
137 | // mResultProvider->add(entity); | ||
138 | // } | ||
139 | // | ||
140 | // } | ||
141 | |||
142 | |||
143 | template<typename DomainType> | ||
144 | void LocalStorageQueryRunner<DomainType>::updateStatus(DomainType &entity) | ||
145 | { | ||
146 | if (mStatusUpdater) { | ||
147 | mStatusUpdater(entity); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | template<typename DomainType> | ||
152 | void LocalStorageQueryRunner<DomainType>::setStatusUpdater(const std::function<void(DomainType &)> &updater) | ||
153 | { | ||
154 | mStatusUpdater = updater; | ||
155 | } | ||
156 | |||
157 | template<typename DomainType> | ||
158 | void LocalStorageQueryRunner<DomainType>::statusChanged(const QByteArray &identifier) | ||
159 | { | ||
160 | Trace() << "Status changed " << identifier; | ||
161 | auto entity = readFromConfig<DomainType>(mConfigStore, identifier, ApplicationDomain::getTypeName<DomainType>()); | ||
162 | updateStatus(*entity); | ||
163 | mResultProvider->modify(entity); | ||
164 | } | ||
165 | |||
166 | template<typename DomainType> | ||
167 | typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr LocalStorageQueryRunner<DomainType>::emitter() | ||
168 | { | ||
169 | return mResultProvider->emitter(); | ||
170 | } | ||
171 | |||
172 | |||
35 | template <typename DomainType> | 173 | template <typename DomainType> |
36 | LocalStorageFacade<DomainType>::~LocalStorageFacade() | 174 | LocalStorageFacade<DomainType>::LocalStorageFacade(const QByteArray &identifier) : StoreFacade<DomainType>(), mIdentifier(identifier), mConfigStore(identifier) |
37 | { | 175 | { |
38 | } | 176 | } |
39 | 177 | ||
40 | template <typename DomainType> | 178 | template <typename DomainType> |
41 | typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type) | 179 | LocalStorageFacade<DomainType>::~LocalStorageFacade() |
42 | { | 180 | { |
43 | auto object = DomainType::Ptr::create(id); | ||
44 | object->setProperty("type", type); | ||
45 | const auto configurationValues = configStore.get(id); | ||
46 | for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { | ||
47 | object->setProperty(it.key(), it.value()); | ||
48 | } | ||
49 | return object; | ||
50 | } | 181 | } |
51 | 182 | ||
52 | template <typename DomainType> | 183 | template <typename DomainType> |
53 | typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(const QByteArray &id, const QByteArray &type) | 184 | typename DomainType::Ptr LocalStorageFacade<DomainType>::readFromConfig(const QByteArray &id, const QByteArray &type) |
54 | { | 185 | { |
55 | return readFromConfig(mConfigStore, id, type); | 186 | return ::readFromConfig<DomainType>(mConfigStore, id, type); |
56 | } | 187 | } |
57 | 188 | ||
58 | template <typename DomainType> | 189 | template <typename DomainType> |
@@ -119,68 +250,13 @@ KAsync::Job<void> LocalStorageFacade<DomainType>::remove(const DomainType &domai | |||
119 | }); | 250 | }); |
120 | } | 251 | } |
121 | 252 | ||
122 | static bool matchesFilter(const QHash<QByteArray, Sink::Query::Comparator> &filter, const QMap<QByteArray, QVariant> &properties) | ||
123 | { | ||
124 | for (const auto &filterProperty : filter.keys()) { | ||
125 | if (filterProperty == "type") { | ||
126 | continue; | ||
127 | } | ||
128 | if (!filter.value(filterProperty).matches(properties.value(filterProperty))) { | ||
129 | return false; | ||
130 | } | ||
131 | } | ||
132 | return true; | ||
133 | } | ||
134 | |||
135 | template <typename DomainType> | 253 | template <typename DomainType> |
136 | QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename DomainType::Ptr>::Ptr> LocalStorageFacade<DomainType>::load(const Sink::Query &query) | 254 | QPair<KAsync::Job<void>, typename ResultEmitter<typename DomainType::Ptr>::Ptr> LocalStorageFacade<DomainType>::load(const Query &query) |
137 | { | 255 | { |
138 | QObject *guard = new QObject; | 256 | auto runner = new LocalStorageQueryRunner<DomainType>(query, mIdentifier, sConfigNotifier); |
139 | auto resultProvider = new Sink::ResultProvider<typename DomainType::Ptr>(); | 257 | return qMakePair(KAsync::null<void>(), runner->emitter()); |
140 | auto emitter = resultProvider->emitter(); | ||
141 | auto identifier = mResourceInstanceIdentifier; | ||
142 | resultProvider->setFetcher([identifier, query, guard, resultProvider](const QSharedPointer<DomainType> &) { | ||
143 | ConfigStore mConfigStore(identifier); | ||
144 | const auto entries = mConfigStore.getEntries(); | ||
145 | for (const auto &res : entries.keys()) { | ||
146 | const auto type = entries.value(res); | ||
147 | |||
148 | if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { | ||
149 | Trace() << "Skipping due to type."; | ||
150 | continue; | ||
151 | } | ||
152 | if (!query.ids.isEmpty() && !query.ids.contains(res)) { | ||
153 | continue; | ||
154 | } | ||
155 | const auto configurationValues = mConfigStore.get(res); | ||
156 | if (!matchesFilter(query.propertyFilter, configurationValues)){ | ||
157 | Trace() << "Skipping due to filter."; | ||
158 | continue; | ||
159 | } | ||
160 | Trace() << "Found match " << res; | ||
161 | resultProvider->add(readFromConfig(mConfigStore, res, type)); | ||
162 | } | ||
163 | if (query.liveQuery) { | ||
164 | QObject::connect(&sConfigNotifier, &ConfigNotifier::modified, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
165 | resultProvider->modify(entry.staticCast<DomainType>()); | ||
166 | }); | ||
167 | QObject::connect(&sConfigNotifier, &ConfigNotifier::added, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
168 | resultProvider->add(entry.staticCast<DomainType>()); | ||
169 | }); | ||
170 | QObject::connect(&sConfigNotifier, &ConfigNotifier::removed, guard,[resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { | ||
171 | resultProvider->remove(entry.staticCast<DomainType>()); | ||
172 | }); | ||
173 | } | ||
174 | // TODO initialResultSetComplete should be implicit | ||
175 | resultProvider->initialResultSetComplete(typename DomainType::Ptr()); | ||
176 | resultProvider->complete(); | ||
177 | }); | ||
178 | resultProvider->onDone([=]() { delete resultProvider; delete guard; }); | ||
179 | |||
180 | return qMakePair(KAsync::null<void>(), emitter); | ||
181 | } | 258 | } |
182 | 259 | ||
183 | |||
184 | ResourceFacade::ResourceFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkResource>("resources") | 260 | ResourceFacade::ResourceFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkResource>("resources") |
185 | { | 261 | { |
186 | } | 262 | } |
@@ -201,6 +277,28 @@ KAsync::Job<void> ResourceFacade::remove(const Sink::ApplicationDomain::SinkReso | |||
201 | }); | 277 | }); |
202 | } | 278 | } |
203 | 279 | ||
280 | QPair<KAsync::Job<void>, typename Sink::ResultEmitter<typename ApplicationDomain::SinkResource::Ptr>::Ptr> ResourceFacade::load(const Sink::Query &query) | ||
281 | { | ||
282 | auto runner = new LocalStorageQueryRunner<ApplicationDomain::SinkResource>(query, mIdentifier, sConfigNotifier); | ||
283 | auto monitoredResources = QSharedPointer<QSet<QByteArray>>::create(); | ||
284 | runner->setStatusUpdater([runner, monitoredResources](ApplicationDomain::SinkResource &resource) { | ||
285 | auto resourceAccess = ResourceAccessFactory::instance().getAccess(resource.identifier(), ResourceConfig::getResourceType(resource.identifier())); | ||
286 | if (!monitoredResources->contains(resource.identifier())) { | ||
287 | //TODO disconnect at some point when the runner is done | ||
288 | auto ret = QObject::connect(resourceAccess.data(), &ResourceAccess::notification, [resource, runner, resourceAccess](const Notification ¬ification) { | ||
289 | Trace() << "Received notification in facade: " << notification.type; | ||
290 | if (notification.type == Notification::Status) { | ||
291 | runner->statusChanged(resource.identifier()); | ||
292 | } | ||
293 | }); | ||
294 | Q_ASSERT(ret); | ||
295 | monitoredResources->insert(resource.identifier()); | ||
296 | } | ||
297 | resource.setStatusStatus(resourceAccess->getResourceStatus()); | ||
298 | }); | ||
299 | return qMakePair(KAsync::null<void>(), runner->emitter()); | ||
300 | } | ||
301 | |||
204 | 302 | ||
205 | AccountFacade::AccountFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkAccount>("accounts") | 303 | AccountFacade::AccountFacade() : LocalStorageFacade<Sink::ApplicationDomain::SinkAccount>("accounts") |
206 | { | 304 | { |