From a9f3692a0bceb796d10952307f87fdb77abadbf7 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 6 Jul 2016 09:57:51 +0200 Subject: Apply the status to resources --- common/resourcefacade.cpp | 238 ++++++++++++++++++++++++++++++++-------------- common/resourcefacade.h | 26 ++++- 2 files changed, 190 insertions(+), 74 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 @@ #include "query.h" #include "definitions.h" #include "storage.h" +#include "resourceaccess.h" #include -template +using namespace Sink; + +template ConfigNotifier LocalStorageFacade::sConfigNotifier; template -LocalStorageFacade::LocalStorageFacade(const QByteArray &identifier) : Sink::StoreFacade(), mConfigStore(identifier), mResourceInstanceIdentifier(identifier) +static typename DomainType::Ptr readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type) { + auto object = DomainType::Ptr::create(id); + object->setProperty("type", type); + const auto configurationValues = configStore.get(id); + for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { + object->setProperty(it.key(), it.value()); + } + return object; } +static bool matchesFilter(const QHash &filter, const QMap &properties) +{ + for (const auto &filterProperty : filter.keys()) { + if (filterProperty == "type") { + continue; + } + if (!filter.value(filterProperty).matches(properties.value(filterProperty))) { + return false; + } + } + return true; +} + +template +LocalStorageQueryRunner::LocalStorageQueryRunner(const Query &query, const QByteArray &identifier, ConfigNotifier &configNotifier) + : mResultProvider(new ResultProvider), mConfigStore(identifier) +{ + QObject *guard = new QObject; + mResultProvider->setFetcher([this, query, guard, &configNotifier](const QSharedPointer &) { + const auto entries = mConfigStore.getEntries(); + for (const auto &res : entries.keys()) { + const auto type = entries.value(res); + + if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { + Trace() << "Skipping due to type."; + continue; + } + if (!query.ids.isEmpty() && !query.ids.contains(res)) { + continue; + } + const auto configurationValues = mConfigStore.get(res); + if (!matchesFilter(query.propertyFilter, configurationValues)){ + Trace() << "Skipping due to filter."; + continue; + } + Trace() << "Found match " << res; + auto entity = readFromConfig(mConfigStore, res, type); + updateStatus(*entity); + mResultProvider->add(entity); + } + if (query.liveQuery) { + { + auto ret = QObject::connect(&configNotifier, &ConfigNotifier::added, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { + auto entity = entry.staticCast(); + updateStatus(*entity); + mResultProvider->add(entity); + }); + Q_ASSERT(ret); + } + { + auto ret = QObject::connect(&configNotifier, &ConfigNotifier::modified, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { + auto entity = entry.staticCast(); + updateStatus(*entity); + mResultProvider->modify(entity); + }); + Q_ASSERT(ret); + } + { + auto ret = QObject::connect(&configNotifier, &ConfigNotifier::removed, guard, [this](const ApplicationDomain::ApplicationDomainType::Ptr &entry) { + mResultProvider->remove(entry.staticCast()); + }); + Q_ASSERT(ret); + } + } + // TODO initialResultSetComplete should be implicit + mResultProvider->initialResultSetComplete(typename DomainType::Ptr()); + mResultProvider->complete(); + }); + mResultProvider->onDone([=]() { delete guard; }); +} + +// QByteArrayList getMatchingEntries(const Query &query) +// { +// const auto entries = mConfigStore.getEntries(); +// for (const auto &res : entries.keys()) { +// const auto type = entries.value(res); +// +// if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { +// Trace() << "Skipping due to type."; +// continue; +// } +// if (!query.ids.isEmpty() && !query.ids.contains(res)) { +// continue; +// } +// const auto configurationValues = mConfigStore.get(res); +// if (!matchesFilter(query.propertyFilter, configurationValues)){ +// Trace() << "Skipping due to filter."; +// continue; +// } +// Trace() << "Found match " << res; +// auto entity = readFromConfig(mConfigStore, res, type); +// updateStatus(*entity); +// mResultProvider->add(entity); +// } +// +// } + + +template +void LocalStorageQueryRunner::updateStatus(DomainType &entity) +{ + if (mStatusUpdater) { + mStatusUpdater(entity); + } +} + +template +void LocalStorageQueryRunner::setStatusUpdater(const std::function &updater) +{ + mStatusUpdater = updater; +} + +template +void LocalStorageQueryRunner::statusChanged(const QByteArray &identifier) +{ + Trace() << "Status changed " << identifier; + auto entity = readFromConfig(mConfigStore, identifier, ApplicationDomain::getTypeName()); + updateStatus(*entity); + mResultProvider->modify(entity); +} + +template +typename Sink::ResultEmitter::Ptr LocalStorageQueryRunner::emitter() +{ + return mResultProvider->emitter(); +} + + template -LocalStorageFacade::~LocalStorageFacade() +LocalStorageFacade::LocalStorageFacade(const QByteArray &identifier) : StoreFacade(), mIdentifier(identifier), mConfigStore(identifier) { } template -typename DomainType::Ptr LocalStorageFacade::readFromConfig(ConfigStore &configStore, const QByteArray &id, const QByteArray &type) +LocalStorageFacade::~LocalStorageFacade() { - auto object = DomainType::Ptr::create(id); - object->setProperty("type", type); - const auto configurationValues = configStore.get(id); - for (auto it = configurationValues.constBegin(); it != configurationValues.constEnd(); it++) { - object->setProperty(it.key(), it.value()); - } - return object; } template typename DomainType::Ptr LocalStorageFacade::readFromConfig(const QByteArray &id, const QByteArray &type) { - return readFromConfig(mConfigStore, id, type); + return ::readFromConfig(mConfigStore, id, type); } template @@ -119,68 +250,13 @@ KAsync::Job LocalStorageFacade::remove(const DomainType &domai }); } -static bool matchesFilter(const QHash &filter, const QMap &properties) -{ - for (const auto &filterProperty : filter.keys()) { - if (filterProperty == "type") { - continue; - } - if (!filter.value(filterProperty).matches(properties.value(filterProperty))) { - return false; - } - } - return true; -} - template -QPair, typename Sink::ResultEmitter::Ptr> LocalStorageFacade::load(const Sink::Query &query) +QPair, typename ResultEmitter::Ptr> LocalStorageFacade::load(const Query &query) { - QObject *guard = new QObject; - auto resultProvider = new Sink::ResultProvider(); - auto emitter = resultProvider->emitter(); - auto identifier = mResourceInstanceIdentifier; - resultProvider->setFetcher([identifier, query, guard, resultProvider](const QSharedPointer &) { - ConfigStore mConfigStore(identifier); - const auto entries = mConfigStore.getEntries(); - for (const auto &res : entries.keys()) { - const auto type = entries.value(res); - - if (query.propertyFilter.contains("type") && query.propertyFilter.value("type").value.toByteArray() != type) { - Trace() << "Skipping due to type."; - continue; - } - if (!query.ids.isEmpty() && !query.ids.contains(res)) { - continue; - } - const auto configurationValues = mConfigStore.get(res); - if (!matchesFilter(query.propertyFilter, configurationValues)){ - Trace() << "Skipping due to filter."; - continue; - } - Trace() << "Found match " << res; - resultProvider->add(readFromConfig(mConfigStore, res, type)); - } - if (query.liveQuery) { - QObject::connect(&sConfigNotifier, &ConfigNotifier::modified, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { - resultProvider->modify(entry.staticCast()); - }); - QObject::connect(&sConfigNotifier, &ConfigNotifier::added, guard, [resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { - resultProvider->add(entry.staticCast()); - }); - QObject::connect(&sConfigNotifier, &ConfigNotifier::removed, guard,[resultProvider](const Sink::ApplicationDomain::ApplicationDomainType::Ptr &entry) { - resultProvider->remove(entry.staticCast()); - }); - } - // TODO initialResultSetComplete should be implicit - resultProvider->initialResultSetComplete(typename DomainType::Ptr()); - resultProvider->complete(); - }); - resultProvider->onDone([=]() { delete resultProvider; delete guard; }); - - return qMakePair(KAsync::null(), emitter); + auto runner = new LocalStorageQueryRunner(query, mIdentifier, sConfigNotifier); + return qMakePair(KAsync::null(), runner->emitter()); } - ResourceFacade::ResourceFacade() : LocalStorageFacade("resources") { } @@ -201,6 +277,28 @@ KAsync::Job ResourceFacade::remove(const Sink::ApplicationDomain::SinkReso }); } +QPair, typename Sink::ResultEmitter::Ptr> ResourceFacade::load(const Sink::Query &query) +{ + auto runner = new LocalStorageQueryRunner(query, mIdentifier, sConfigNotifier); + auto monitoredResources = QSharedPointer>::create(); + runner->setStatusUpdater([runner, monitoredResources](ApplicationDomain::SinkResource &resource) { + auto resourceAccess = ResourceAccessFactory::instance().getAccess(resource.identifier(), ResourceConfig::getResourceType(resource.identifier())); + if (!monitoredResources->contains(resource.identifier())) { + //TODO disconnect at some point when the runner is done + auto ret = QObject::connect(resourceAccess.data(), &ResourceAccess::notification, [resource, runner, resourceAccess](const Notification ¬ification) { + Trace() << "Received notification in facade: " << notification.type; + if (notification.type == Notification::Status) { + runner->statusChanged(resource.identifier()); + } + }); + Q_ASSERT(ret); + monitoredResources->insert(resource.identifier()); + } + resource.setStatusStatus(resourceAccess->getResourceStatus()); + }); + return qMakePair(KAsync::null(), runner->emitter()); +} + AccountFacade::AccountFacade() : LocalStorageFacade("accounts") { diff --git a/common/resourcefacade.h b/common/resourcefacade.h index 989375d..2573b31 100644 --- a/common/resourcefacade.h +++ b/common/resourcefacade.h @@ -55,6 +55,22 @@ signals: void modified(const Sink::ApplicationDomain::ApplicationDomainType::Ptr &account); }; +template +class LocalStorageQueryRunner +{ +public: + LocalStorageQueryRunner(const Sink::Query &query, const QByteArray &identifier, ConfigNotifier &configNotifier); + typename Sink::ResultEmitter::Ptr emitter(); + void setStatusUpdater(const std::function &); + void statusChanged(const QByteArray &identifier); + +private: + void updateStatus(DomainType &entity); + std::function mStatusUpdater; + QSharedPointer> mResultProvider; + ConfigStore mConfigStore; +}; + template class LocalStorageFacade : public Sink::StoreFacade { @@ -65,13 +81,14 @@ public: virtual KAsync::Job modify(const DomainType &resource) Q_DECL_OVERRIDE; virtual KAsync::Job remove(const DomainType &resource) Q_DECL_OVERRIDE; virtual QPair, typename Sink::ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; + +protected: + QByteArray mIdentifier; + static ConfigNotifier sConfigNotifier; + private: typename DomainType::Ptr readFromConfig(const QByteArray &id, const QByteArray &type); - static typename DomainType::Ptr readFromConfig(ConfigStore &store, const QByteArray &id, const QByteArray &type); - ConfigStore mConfigStore; - static ConfigNotifier sConfigNotifier; - QByteArray mResourceInstanceIdentifier; }; class ResourceFacade : public LocalStorageFacade @@ -80,6 +97,7 @@ public: ResourceFacade(); virtual ~ResourceFacade(); virtual KAsync::Job remove(const Sink::ApplicationDomain::SinkResource &resource) Q_DECL_OVERRIDE; + virtual QPair, typename Sink::ResultEmitter::Ptr> load(const Sink::Query &query) Q_DECL_OVERRIDE; }; class AccountFacade : public LocalStorageFacade -- cgit v1.2.3