[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [sink/develop] /: Moved inspection commands to a separate inspector.
From:       Christian Mollekopf <chrigi_1 () fastmail ! fm>
Date:       2016-12-02 10:08:34
Message-ID: E1cCkle-0004b8-KT () code ! kde ! org
[Download RAW message or body]

Git commit 938554f267193b652478fc12343819fa45d76034 by Christian Mollekopf.
Committed on 28/11/2016 at 18:33.
Pushed by cmollekopf into branch 'develop'.

Moved inspection commands to a separate inspector.

M  +1    -0    common/CMakeLists.txt
M  +16   -11   common/commandprocessor.cpp
M  +10   -4    common/commandprocessor.h
M  +8    -50   common/genericresource.cpp
M  +2    -2    common/genericresource.h
A  +85   -0    common/inspector.cpp     [License: LGPL]
A  +52   -0    common/inspector.h     [License: LGPL]
M  +27   -17   examples/dummyresource/resourcefactory.cpp
M  +0    -1    examples/dummyresource/resourcefactory.h
M  +165  -141  examples/imapresource/imapresource.cpp
M  +0    -7    examples/imapresource/imapresource.h
M  +98   -87   examples/maildirresource/maildirresource.cpp
M  +1    -2    examples/maildirresource/maildirresource.h
M  +27   -21   examples/mailtransportresource/mailtransportresource.cpp
M  +0    -2    examples/mailtransportresource/mailtransportresource.h

https://commits.kde.org/sink/938554f267193b652478fc12343819fa45d76034

diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
index 018fc22..df44ce5 100644
--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -78,6 +78,7 @@ set(command_SRCS
     mail/threadindexer.cpp
     notification.cpp
     commandprocessor.cpp
+    inspector.cpp
     ${storage_SRCS})
 
 add_library(${PROJECT_NAME} SHARED ${command_SRCS})
diff --git a/common/commandprocessor.cpp b/common/commandprocessor.cpp
index c9fca37..4ff352b 100644
--- a/common/commandprocessor.cpp
+++ b/common/commandprocessor.cpp
@@ -22,7 +22,8 @@
 #include "commands.h"
 #include "messagequeue.h"
 #include "queuedcommand_generated.h"
-
+#include "inspector.h"
+#include "synchronizer.h"
 #include "pipeline.h"
 
 static int sBatchSize = 100;
@@ -42,11 +43,6 @@ void CommandProcessor::setOldestUsedRevision(qint64 revision)
     mLowerBoundRevision = revision;
 }
 
-void CommandProcessor::setInspectionCommand(const InspectionFunction &f)
-{
-    mInspect = f;
-}
-
 void CommandProcessor::setFlushCommand(const FlushFunction &f)
 {
     mFlush = f;
@@ -91,12 +87,9 @@ KAsync::Job<qint64> CommandProcessor::processQueuedCommand(const \
Sink::QueuedCom  case Sink::Commands::CreateEntityCommand:
             return mPipeline->newEntity(data, size);
         case Sink::Commands::InspectionCommand:
-            if (mInspect) {
-                return mInspect(data, size)
+            Q_ASSERT(mInspector);
+            return mInspector->processCommand(data, size)
                     .syncThen<qint64>([]() { return -1; });
-            } else {
-                return KAsync::error<qint64>(-1, "Missing inspection command.");
-            }
         case Sink::Commands::FlushCommand:
             if (mFlush) {
                 return mFlush(data, size)
@@ -191,3 +184,15 @@ KAsync::Job<void> CommandProcessor::processPipeline()
         });
 }
 
+void CommandProcessor::setInspector(const QSharedPointer<Inspector> &inspector)
+{
+    mInspector = inspector;
+    QObject::connect(mInspector.data(), &Inspector::notify, this, \
&CommandProcessor::notify); +}
+
+void CommandProcessor::setSynchronizer(const QSharedPointer<Synchronizer> \
&synchronizer) +{
+    mSynchronizer = synchronizer;
+    QObject::connect(mSynchronizer.data(), &Synchronizer::notify, this, \
&CommandProcessor::notify); +}
+
diff --git a/common/commandprocessor.h b/common/commandprocessor.h
index 51d845e..75ae37a 100644
--- a/common/commandprocessor.h
+++ b/common/commandprocessor.h
@@ -24,12 +24,16 @@
 #include <QObject>
 #include <Async/Async>
 #include <functional>
+
 #include "log.h"
+#include "notification.h"
 
 class MessageQueue;
 
 namespace Sink {
     class Pipeline;
+    class Inspector;
+    class Synchronizer;
     class QueuedCommand;
 
 /**
@@ -38,7 +42,6 @@ namespace Sink {
 class CommandProcessor : public QObject
 {
     Q_OBJECT
-    typedef std::function<KAsync::Job<void>(void const *, size_t)> \
                InspectionFunction;
     typedef std::function<KAsync::Job<void>(void const *, size_t)> FlushFunction;
     SINK_DEBUG_AREA("commandprocessor")
 
@@ -47,11 +50,13 @@ public:
 
     void setOldestUsedRevision(qint64 revision);
 
-    void setInspectionCommand(const InspectionFunction &f);
-
     void setFlushCommand(const FlushFunction &f);
 
+    void setInspector(const QSharedPointer<Inspector> &inspector);
+    void setSynchronizer(const QSharedPointer<Synchronizer> &synchronizer);
+
 signals:
+    void notify(Notification);
     void error(int errorCode, const QString &errorMessage);
 
 private:
@@ -72,8 +77,9 @@ private:
     bool mProcessingLock;
     // The lowest revision we no longer need
     qint64 mLowerBoundRevision;
-    InspectionFunction mInspect;
     FlushFunction mFlush;
+    QSharedPointer<Synchronizer> mSynchronizer;
+    QSharedPointer<Inspector> mInspector;
 };
 
 };
diff --git a/common/genericresource.cpp b/common/genericresource.cpp
index 3aa4fce..80e59c9 100644
--- a/common/genericresource.cpp
+++ b/common/genericresource.cpp
@@ -59,41 +59,6 @@ GenericResource::GenericResource(const ResourceContext \
&resourceContext, const Q  \
mClientLowerBoundRevision(std::numeric_limits<qint64>::max())  {
     mProcessor = std::unique_ptr<CommandProcessor>(new \
CommandProcessor(mPipeline.data(), QList<MessageQueue *>() << &mUserQueue << \
                &mSynchronizerQueue));
-    mProcessor->setInspectionCommand([this](void const *command, size_t size) {
-        flatbuffers::Verifier verifier((const uint8_t *)command, size);
-        if (Sink::Commands::VerifyInspectionBuffer(verifier)) {
-            auto buffer = Sink::Commands::GetInspection(command);
-            int inspectionType = buffer->type();
-
-            QByteArray inspectionId = BufferUtils::extractBuffer(buffer->id());
-            QByteArray entityId = BufferUtils::extractBuffer(buffer->entityId());
-            QByteArray domainType = \
                BufferUtils::extractBuffer(buffer->domainType());
-            QByteArray property = BufferUtils::extractBuffer(buffer->property());
-            QByteArray expectedValueString = \
                BufferUtils::extractBuffer(buffer->expectedValue());
-            QDataStream s(expectedValueString);
-            QVariant expectedValue;
-            s >> expectedValue;
-            inspect(inspectionType, inspectionId, domainType, entityId, property, \
                expectedValue)
-                .then<void>(
-                    [=](const KAsync::Error &error) {
-                        Sink::Notification n;
-                        n.type = Sink::Notification::Inspection;
-                        n.id = inspectionId;
-                        if (error) {
-                            Warning_area("resource.inspection") << "Inspection \
                failed: " << inspectionType << inspectionId << entityId << \
                error.errorMessage;
-                            n.code = Sink::Notification::Failure;
-                        } else {
-                            Log_area("resource.inspection") << "Inspection was \
                successful: " << inspectionType << inspectionId << entityId;
-                            n.code = Sink::Notification::Success;
-                        }
-                        emit notify(n);
-                        return KAsync::null();
-                    })
-                .exec();
-            return KAsync::null<void>();
-        }
-        return KAsync::error<void>(-1, "Invalid inspection command.");
-    });
     mProcessor->setFlushCommand([this](void const *command, size_t size) {
         flatbuffers::Verifier verifier((const uint8_t *)command, size);
         if (Sink::Commands::VerifyFlushBuffer(verifier)) {
@@ -114,14 +79,9 @@ GenericResource::GenericResource(const ResourceContext \
&resourceContext, const Q  }
         return KAsync::error<void>(-1, "Invalid flush command.");
     });
-    {
-        auto ret = QObject::connect(mProcessor.get(), &CommandProcessor::error, \
                [this](int errorCode, const QString &msg) { \
                onProcessorError(errorCode, msg); });
-        Q_ASSERT(ret);
-    }
-    {
-        auto ret = QObject::connect(mPipeline.data(), &Pipeline::revisionUpdated, \
                this, &Resource::revisionUpdated);
-        Q_ASSERT(ret);
-    }
+    QObject::connect(mProcessor.get(), &CommandProcessor::error, [this](int \
errorCode, const QString &msg) { onProcessorError(errorCode, msg); }); +    \
QObject::connect(mProcessor.get(), &CommandProcessor::notify, this, \
&GenericResource::notify); +    QObject::connect(mPipeline.data(), \
&Pipeline::revisionUpdated, this, &Resource::revisionUpdated);  
     mCommitQueueTimer.setInterval(sCommitInterval);
     mCommitQueueTimer.setSingleShot(true);
@@ -132,13 +92,6 @@ GenericResource::~GenericResource()
 {
 }
 
-KAsync::Job<void> GenericResource::inspect(
-    int inspectionType, const QByteArray &inspectionId, const QByteArray \
&domainType, const QByteArray &entityId, const QByteArray &property, const QVariant \
                &expectedValue)
-{
-    SinkWarning() << "Inspection not implemented";
-    return KAsync::null<void>();
-}
-
 void GenericResource::setupPreprocessors(const QByteArray &type, const \
QVector<Sink::Preprocessor *> &preprocessors)  {
     mPipeline->setPreprocessors(type, preprocessors);
@@ -179,6 +132,11 @@ void GenericResource::setupSynchronizer(const \
                QSharedPointer<Synchronizer> &sync
     QMetaObject::invokeMethod(mSynchronizer.data(), "revisionChanged", \
Qt::QueuedConnection);  }
 
+void GenericResource::setupInspector(const QSharedPointer<Inspector> &inspector)
+{
+    mProcessor->setInspector(inspector);
+}
+
 void GenericResource::removeFromDisk(const QByteArray &instanceIdentifier)
 {
     Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier, \
                Sink::Storage::DataStore::ReadWrite).removeFromDisk();
diff --git a/common/genericresource.h b/common/genericresource.h
index 12f15f3..0bc47da 100644
--- a/common/genericresource.h
+++ b/common/genericresource.h
@@ -32,6 +32,7 @@ namespace Sink {
 class Pipeline;
 class Preprocessor;
 class Synchronizer;
+class Inspector;
 class CommandProcessor;
 
 /**
@@ -50,8 +51,6 @@ public:
     virtual KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &query) \
Q_DECL_OVERRIDE;  virtual KAsync::Job<void> processAllMessages() Q_DECL_OVERRIDE;
     virtual void setLowerBoundRevision(qint64 revision) Q_DECL_OVERRIDE;
-    virtual KAsync::Job<void>
-    inspect(int inspectionType, const QByteArray &inspectionId, const QByteArray \
&domainType, const QByteArray &entityId, const QByteArray &property, const QVariant \
&expectedValue);  
     int error() const;
 
@@ -64,6 +63,7 @@ private slots:
 protected:
     void setupPreprocessors(const QByteArray &type, const QVector<Sink::Preprocessor \
                *> &preprocessors);
     void setupSynchronizer(const QSharedPointer<Synchronizer> &synchronizer);
+    void setupInspector(const QSharedPointer<Inspector> &inspector);
 
     void onProcessorError(int errorCode, const QString &errorMessage);
     void enqueueCommand(MessageQueue &mq, int commandId, const QByteArray &data);
diff --git a/common/inspector.cpp b/common/inspector.cpp
new file mode 100644
index 0000000..8b4c93a
--- /dev/null
+++ b/common/inspector.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "inspector.h"
+
+#include "resourcecontext.h"
+#include "inspection_generated.h"
+#include "bufferutils.h"
+
+#include <QDataStream>
+
+using namespace Sink;
+
+Inspector::Inspector(const ResourceContext &context)
+    : QObject(),
+    mResourceContext(context)
+    // mEntityStore(Storage::EntityStore::Ptr::create(mResourceContext)),
+    // mSyncStorage(Sink::storageLocation(), mResourceContext.instanceId() + \
".synchronization", Sink::Storage::DataStore::DataStore::ReadWrite) +{
+    // SinkTrace() << "Starting synchronizer: " << mResourceContext.resourceType << \
mResourceContext.instanceId(); +}
+
+Inspector::~Inspector()
+{
+
+}
+
+KAsync::Job<void> Inspector::processCommand(void const *command, size_t size)
+{
+    flatbuffers::Verifier verifier((const uint8_t *)command, size);
+    if (Sink::Commands::VerifyInspectionBuffer(verifier)) {
+        auto buffer = Sink::Commands::GetInspection(command);
+        int inspectionType = buffer->type();
+
+        QByteArray inspectionId = BufferUtils::extractBuffer(buffer->id());
+        QByteArray entityId = BufferUtils::extractBuffer(buffer->entityId());
+        QByteArray domainType = BufferUtils::extractBuffer(buffer->domainType());
+        QByteArray property = BufferUtils::extractBuffer(buffer->property());
+        QByteArray expectedValueString = \
BufferUtils::extractBuffer(buffer->expectedValue()); +        QDataStream \
s(expectedValueString); +        QVariant expectedValue;
+        s >> expectedValue;
+        inspect(inspectionType, inspectionId, domainType, entityId, property, \
expectedValue) +            .then<void>(
+                [=](const KAsync::Error &error) {
+                    Sink::Notification n;
+                    n.type = Sink::Notification::Inspection;
+                    n.id = inspectionId;
+                    if (error) {
+                        Warning_area("resource.inspection") << "Inspection failed: " \
<< inspectionType << inspectionId << entityId << error.errorMessage; +                \
n.code = Sink::Notification::Failure; +                    } else {
+                        Log_area("resource.inspection") << "Inspection was \
successful: " << inspectionType << inspectionId << entityId; +                        \
n.code = Sink::Notification::Success; +                    }
+                    emit notify(n);
+                    return KAsync::null();
+                })
+            .exec();
+        return KAsync::null<void>();
+    }
+    return KAsync::error<void>(-1, "Invalid inspection command.");
+}
+
+KAsync::Job<void> Inspector::inspect(int inspectionType, const QByteArray \
&inspectionId, const QByteArray &domainType, const QByteArray &entityId, const \
QByteArray &property, const QVariant &expectedValue) +{
+    return KAsync::error(-1, "Inspection not implemented.");
+}
+
diff --git a/common/inspector.h b/common/inspector.h
new file mode 100644
index 0000000..ff167b1
--- /dev/null
+++ b/common/inspector.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) version 3, or any
+ * later version accepted by the membership of KDE e.V. (or its
+ * successor approved by the membership of KDE e.V.), which shall
+ * act as a proxy defined in Section 6 of version 3 of the license.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include "sink_export.h"
+#include <QObject>
+#include <Async/Async>
+
+#include "notification.h"
+#include "resourcecontext.h"
+
+namespace Sink {
+
+/**
+ * Synchronize and add what we don't already have to local queue
+ */
+class SINK_EXPORT Inspector : public QObject
+{
+    Q_OBJECT
+public:
+    Inspector(const ResourceContext &resourceContext);
+    virtual ~Inspector();
+
+    KAsync::Job<void> processCommand(void const *command, size_t size);
+
+signals:
+    void notify(Notification);
+
+protected:
+    virtual KAsync::Job<void> inspect(int inspectionType, const QByteArray \
&inspectionId, const QByteArray &domainType, const QByteArray &entityId, const \
QByteArray &property, const QVariant &expectedValue); +
+    Sink::ResourceContext mResourceContext;
+};
+
+}
diff --git a/examples/dummyresource/resourcefactory.cpp \
b/examples/dummyresource/resourcefactory.cpp index f5ab2d9..8e81c79 100644
--- a/examples/dummyresource/resourcefactory.cpp
+++ b/examples/dummyresource/resourcefactory.cpp
@@ -37,6 +37,7 @@
 #include "facadefactory.h"
 #include "adaptorfactoryregistry.h"
 #include "synchronizer.h"
+#include "inspector.h"
 #include "mailpreprocessor.h"
 #include "remoteidmap.h"
 #include <QDate>
@@ -130,10 +131,36 @@ class DummySynchronizer : public Sink::Synchronizer {
 
 };
 
+class DummyInspector : public Sink::Inspector {
+public:
+    DummyInspector(const Sink::ResourceContext &resourceContext)
+        : Sink::Inspector(resourceContext)
+    {
+
+    }
+
+protected:
+    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
const QVariant &expectedValue) Q_DECL_OVERRIDE +    {
+        SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << \
property << expectedValue; +        if (property == "testInspection") {
+            if (expectedValue.toBool()) {
+                //Success
+                return KAsync::null<void>();
+            } else {
+                //Failure
+                return KAsync::error<void>(1, "Failed.");
+            }
+        }
+        return KAsync::null<void>();
+    }
+};
+
 DummyResource::DummyResource(const Sink::ResourceContext &resourceContext, const \
QSharedPointer<Sink::Pipeline> &pipeline)  : Sink::GenericResource(resourceContext, \
pipeline)  {
     setupSynchronizer(QSharedPointer<DummySynchronizer>::create(resourceContext));
+    setupInspector(QSharedPointer<DummyInspector>::create(resourceContext));
     setupPreprocessors(ENTITY_TYPE_MAIL,
             QVector<Sink::Preprocessor*>() << new MailPropertyExtractor);
     setupPreprocessors(ENTITY_TYPE_FOLDER,
@@ -159,23 +186,6 @@ KAsync::Job<void> DummyResource::synchronizeWithSource(const \
Sink::QueryBase &qu  return GenericResource::synchronizeWithSource(query);
 }
 
-KAsync::Job<void> DummyResource::inspect(int inspectionType, const QByteArray \
&inspectionId, const QByteArray &domainType, const QByteArray &entityId, const \
                QByteArray &property, const QVariant &expectedValue)
-{
-
-    SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << \
                property << expectedValue;
-    if (property == "testInspection") {
-        if (expectedValue.toBool()) {
-            //Success
-            return KAsync::null<void>();
-        } else {
-            //Failure
-            return KAsync::error<void>(1, "Failed.");
-        }
-    }
-    return KAsync::null<void>();
-}
-
-
 DummyResourceFactory::DummyResourceFactory(QObject *parent)
     : Sink::ResourceFactory(parent)
 {
diff --git a/examples/dummyresource/resourcefactory.h \
b/examples/dummyresource/resourcefactory.h index 8ef27a6..2eb7558 100644
--- a/examples/dummyresource/resourcefactory.h
+++ b/examples/dummyresource/resourcefactory.h
@@ -33,7 +33,6 @@ public:
     virtual ~DummyResource();
 
     KAsync::Job<void> synchronizeWithSource(const Sink::QueryBase &) \
                Q_DECL_OVERRIDE;
-    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
const QVariant &expectedValue) Q_DECL_OVERRIDE;  };
 
 class DummyResourceFactory : public Sink::ResourceFactory
diff --git a/examples/imapresource/imapresource.cpp \
b/examples/imapresource/imapresource.cpp index 2aa5a2c..40fa75f 100644
--- a/examples/imapresource/imapresource.cpp
+++ b/examples/imapresource/imapresource.cpp
@@ -27,6 +27,7 @@
 #include "definitions.h"
 #include "inspection.h"
 #include "synchronizer.h"
+#include "inspector.h"
 #include "remoteidmap.h"
 #include "query.h"
 
@@ -553,169 +554,192 @@ public:
     QByteArray mResourceInstanceIdentifier;
 };
 
-ImapResource::ImapResource(const ResourceContext &resourceContext)
-    : Sink::GenericResource(resourceContext)
-{
-    auto config = ResourceConfig::getConfiguration(resourceContext.instanceId());
-    mServer = config.value("server").toString();
-    mPort = config.value("port").toInt();
-    mUser = config.value("username").toString();
-    mPassword = config.value("password").toString();
-    if (mServer.startsWith("imap")) {
-        mServer.remove("imap://");
-        mServer.remove("imaps://");
-    }
-    if (mServer.contains(':')) {
-        auto list = mServer.split(':');
-        mServer = list.at(0);
-        mPort = list.at(1).toInt();
-    }
-
-    auto synchronizer = QSharedPointer<ImapSynchronizer>::create(resourceContext);
-    synchronizer->mServer = mServer;
-    synchronizer->mPort = mPort;
-    synchronizer->mUser = mUser;
-    synchronizer->mPassword = mPassword;
-    setupSynchronizer(synchronizer);
-
-    setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new \
SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) \
                << new MimeMessageMover << new MailPropertyExtractor);
-    setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>());
-}
+class ImapInspector : public Sink::Inspector {
+public:
+    ImapInspector(const Sink::ResourceContext &resourceContext)
+        : Sink::Inspector(resourceContext)
+    {
 
-KAsync::Job<void> ImapResource::inspect(int inspectionType, const QByteArray \
&inspectionId, const QByteArray &domainType, const QByteArray &entityId, const \
                QByteArray &property, const QVariant &expectedValue)
-{
-    auto synchronizationStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId() + ".synchronization", \
                Sink::Storage::DataStore::ReadOnly);
-    auto synchronizationTransaction = \
synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +    }
 
-    auto mainStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
                mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly);
-    auto transaction = \
mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +protected:
+    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
const QVariant &expectedValue) Q_DECL_OVERRIDE { +        auto synchronizationStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId() + ".synchronization", \
Sink::Storage::DataStore::ReadOnly); +        auto synchronizationTransaction = \
synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly);  
-    Sink::Storage::EntityStore entityStore(mResourceContext);
-    auto syncStore = \
QSharedPointer<Sink::RemoteIdMap>::create(synchronizationTransaction); +        auto \
mainStore = QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); +        auto \
transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly);  
-    SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << \
property << expectedValue; +        Sink::Storage::EntityStore \
entityStore(mResourceContext); +        auto syncStore = \
QSharedPointer<Sink::RemoteIdMap>::create(synchronizationTransaction);  
-    if (domainType == ENTITY_TYPE_MAIL) {
-        const auto mail = \
                entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId);
-        const auto folder = \
                entityStore.readLatest<Sink::ApplicationDomain::Folder>(mail.getFolder());
                
-        const auto folderRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, \
                mail.getFolder());
-        const auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, \
                mail.identifier());
-        if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) {
-            SinkWarning() << "Missing remote id for folder or mail. " << \
                mailRemoteId << folderRemoteId;
-            return KAsync::error<void>();
-        }
-        const auto uid = uidFromMailRid(mailRemoteId);
-        SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << \
mail.identifier() << folder.identifier(); +        SinkTrace() << "Inspecting " << \
inspectionType << domainType << entityId << property << expectedValue;  
-        KIMAP2::ImapSet set;
-        set.add(uid);
-        if (set.isEmpty()) {
-            return KAsync::error<void>(1, "Couldn't determine uid of mail.");
-        }
-        KIMAP2::FetchJob::FetchScope scope;
-        scope.mode = KIMAP2::FetchJob::FetchScope::Full;
-        auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
-        auto messageByUid = QSharedPointer<QHash<qint64, Imap::Message>>::create();
-        SinkTrace() << "Connecting to:" << mServer << mPort;
-        SinkTrace() << "as:" << mUser;
-        auto inspectionJob = imap->login(mUser, mPassword)
-            .then<Imap::SelectResult>(imap->select(folderRemoteId))
-            .syncThen<void, Imap::SelectResult>([](Imap::SelectResult){})
-            .then<void>(imap->fetch(set, scope, [imap, messageByUid](const \
                Imap::Message &message) {
-                messageByUid->insert(message.uid, message);
-            }));
-
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::PropertyInspectionType) {
-            if (property == "unread") {
-                return inspectionJob.then<void>([=]() {
-                    auto msg = messageByUid->value(uid);
-                    if (expectedValue.toBool() && \
                msg.flags.contains(Imap::Flags::Seen)) {
-                        return KAsync::error<void>(1, "Expected unread but couldn't \
                find it.");
-                    }
-                    if (!expectedValue.toBool() && \
                !msg.flags.contains(Imap::Flags::Seen)) {
-                        return KAsync::error<void>(1, "Expected read but couldn't \
                find it.");
-                    }
-                    return KAsync::null<void>();
-                });
-            }
-            if (property == "subject") {
-                return inspectionJob.then<void>([=]() {
-                    auto msg = messageByUid->value(uid);
-                    if (msg.msg->subject(true)->asUnicodeString() != \
                expectedValue.toString()) {
-                        return KAsync::error<void>(1, "Subject not as expected: " + \
                msg.msg->subject(true)->asUnicodeString());
-                    }
-                    return KAsync::null<void>();
-                });
+        if (domainType == ENTITY_TYPE_MAIL) {
+            const auto mail = \
entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); +            const \
auto folder = entityStore.readLatest<Sink::ApplicationDomain::Folder>(mail.getFolder());
 +            const auto folderRemoteId = \
syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, mail.getFolder()); +            const \
auto mailRemoteId = syncStore->resolveLocalId(ENTITY_TYPE_MAIL, mail.identifier()); + \
if (mailRemoteId.isEmpty() || folderRemoteId.isEmpty()) { +                \
SinkWarning() << "Missing remote id for folder or mail. " << mailRemoteId << \
folderRemoteId; +                return KAsync::error<void>();
             }
-        }
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::ExistenceInspectionType) {
-            return inspectionJob.then<void>([=]() {
-                if (!messageByUid->contains(uid)) {
-                    SinkWarning() << "Existing messages are: " << \
                messageByUid->keys();
-                    SinkWarning() << "We're looking for: " << uid;
-                    return KAsync::error<void>(1, "Couldn't find message: " + \
                mailRemoteId);
-                }
-                return KAsync::null<void>();
-            });
-        }
-    }
-    if (domainType == ENTITY_TYPE_FOLDER) {
-        const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, \
                entityId);
-        const auto folder = \
                entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId);
-
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) {
-            SinkLog() << "Inspecting cache integrity" << remoteId;
+            const auto uid = uidFromMailRid(mailRemoteId);
+            SinkTrace() << "Mail remote id: " << folderRemoteId << mailRemoteId << \
mail.identifier() << folder.identifier();  
-            int expectedCount = 0;
-            Index index("mail.index.folder", transaction);
-            index.lookup(entityId, [&](const QByteArray &sinkId) {
-                expectedCount++;
-            },
-            [&](const Index::Error &error) {
-                SinkWarning() << "Error in index: " <<  error.message << property;
-            });
-
-            auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*");
+            KIMAP2::ImapSet set;
+            set.add(uid);
+            if (set.isEmpty()) {
+                return KAsync::error<void>(1, "Couldn't determine uid of mail.");
+            }
             KIMAP2::FetchJob::FetchScope scope;
-            scope.mode = KIMAP2::FetchJob::FetchScope::Headers;
+            scope.mode = KIMAP2::FetchJob::FetchScope::Full;
             auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
             auto messageByUid = QSharedPointer<QHash<qint64, \
                Imap::Message>>::create();
-            return imap->login(mUser, mPassword)
-                .then<void>(imap->select(remoteId).syncThen<void>([](){}))
-                .then<void>(imap->fetch(set, scope, [=](const Imap::Message message) \
{ +            SinkTrace() << "Connecting to:" << mServer << mPort;
+            SinkTrace() << "as:" << mUser;
+            auto inspectionJob = imap->login(mUser, mPassword)
+                .then<Imap::SelectResult>(imap->select(folderRemoteId))
+                .syncThen<void, Imap::SelectResult>([](Imap::SelectResult){})
+                .then<void>(imap->fetch(set, scope, [imap, messageByUid](const \
Imap::Message &message) {  messageByUid->insert(message.uid, message);
-                }))
-                .then<void>([imap, messageByUid, expectedCount]() {
-                    if (messageByUid->size() != expectedCount) {
-                        return KAsync::error<void>(1, QString("Wrong number of \
messages on the server; found %1 instead of \
%2.").arg(messageByUid->size()).arg(expectedCount)); +                }));
+
+            if (inspectionType == \
Sink::ResourceControl::Inspection::PropertyInspectionType) { +                if \
(property == "unread") { +                    return inspectionJob.then<void>([=]() {
+                        auto msg = messageByUid->value(uid);
+                        if (expectedValue.toBool() && \
msg.flags.contains(Imap::Flags::Seen)) { +                            return \
KAsync::error<void>(1, "Expected unread but couldn't find it."); +                    \
} +                        if (!expectedValue.toBool() && \
!msg.flags.contains(Imap::Flags::Seen)) { +                            return \
KAsync::error<void>(1, "Expected read but couldn't find it."); +                      \
} +                        return KAsync::null<void>();
+                    });
+                }
+                if (property == "subject") {
+                    return inspectionJob.then<void>([=]() {
+                        auto msg = messageByUid->value(uid);
+                        if (msg.msg->subject(true)->asUnicodeString() != \
expectedValue.toString()) { +                            return \
KAsync::error<void>(1, "Subject not as expected: " + \
msg.msg->subject(true)->asUnicodeString()); +                        }
+                        return KAsync::null<void>();
+                    });
+                }
+            }
+            if (inspectionType == \
Sink::ResourceControl::Inspection::ExistenceInspectionType) { +                return \
inspectionJob.then<void>([=]() { +                    if \
(!messageByUid->contains(uid)) { +                        SinkWarning() << "Existing \
messages are: " << messageByUid->keys(); +                        SinkWarning() << \
"We're looking for: " << uid; +                        return KAsync::error<void>(1, \
"Couldn't find message: " + mailRemoteId);  }
                     return KAsync::null<void>();
                 });
+            }
         }
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::ExistenceInspectionType) {
-            auto  folderByPath = QSharedPointer<QSet<QString>>::create();
-            auto  folderByName = QSharedPointer<QSet<QString>>::create();
+        if (domainType == ENTITY_TYPE_FOLDER) {
+            const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, \
entityId); +            const auto folder = \
entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId);  
-            auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
-            auto inspectionJob = imap->login(mUser, mPassword)
-                .then<void>(imap->fetchFolders([=](const Imap::Folder &f) {
-                    *folderByPath << f.normalizedPath();
-                    *folderByName << f.name();
-                }))
-                .then<void>([this, folderByName, folderByPath, folder, remoteId, \
                imap]() {
-                    if (!folderByName->contains(folder.getName())) {
-                        SinkWarning() << "Existing folders are: " << *folderByPath;
-                        SinkWarning() << "We're looking for: " << folder.getName();
-                        return KAsync::error<void>(1, "Wrong folder name: " + \
                remoteId);
-                    }
-                    return KAsync::null<void>();
+            if (inspectionType == \
Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { +                \
SinkLog() << "Inspecting cache integrity" << remoteId; +
+                int expectedCount = 0;
+                Index index("mail.index.folder", transaction);
+                index.lookup(entityId, [&](const QByteArray &sinkId) {
+                    expectedCount++;
+                },
+                [&](const Index::Error &error) {
+                    SinkWarning() << "Error in index: " <<  error.message << \
property;  });
 
-            return inspectionJob;
+                auto set = KIMAP2::ImapSet::fromImapSequenceSet("1:*");
+                KIMAP2::FetchJob::FetchScope scope;
+                scope.mode = KIMAP2::FetchJob::FetchScope::Headers;
+                auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
+                auto messageByUid = QSharedPointer<QHash<qint64, \
Imap::Message>>::create(); +                return imap->login(mUser, mPassword)
+                    .then<void>(imap->select(remoteId).syncThen<void>([](){}))
+                    .then<void>(imap->fetch(set, scope, [=](const Imap::Message \
message) { +                        messageByUid->insert(message.uid, message);
+                    }))
+                    .then<void>([imap, messageByUid, expectedCount]() {
+                        if (messageByUid->size() != expectedCount) {
+                            return KAsync::error<void>(1, QString("Wrong number of \
messages on the server; found %1 instead of \
%2.").arg(messageByUid->size()).arg(expectedCount)); +                        }
+                        return KAsync::null<void>();
+                    });
+            }
+            if (inspectionType == \
Sink::ResourceControl::Inspection::ExistenceInspectionType) { +                auto  \
folderByPath = QSharedPointer<QSet<QString>>::create(); +                auto  \
folderByName = QSharedPointer<QSet<QString>>::create(); +
+                auto imap = QSharedPointer<ImapServerProxy>::create(mServer, mPort);
+                auto inspectionJob = imap->login(mUser, mPassword)
+                    .then<void>(imap->fetchFolders([=](const Imap::Folder &f) {
+                        *folderByPath << f.normalizedPath();
+                        *folderByName << f.name();
+                    }))
+                    .then<void>([this, folderByName, folderByPath, folder, remoteId, \
imap]() { +                        if (!folderByName->contains(folder.getName())) {
+                            SinkWarning() << "Existing folders are: " << \
*folderByPath; +                            SinkWarning() << "We're looking for: " << \
folder.getName(); +                            return KAsync::error<void>(1, "Wrong \
folder name: " + remoteId); +                        }
+                        return KAsync::null<void>();
+                    });
+
+                return inspectionJob;
+            }
+
         }
+        return KAsync::null<void>();
+    }
+
+public:
+    QString mServer;
+    int mPort;
+    QString mUser;
+    QString mPassword;
+};
+
 
+ImapResource::ImapResource(const ResourceContext &resourceContext)
+    : Sink::GenericResource(resourceContext)
+{
+    auto config = ResourceConfig::getConfiguration(resourceContext.instanceId());
+    auto server = config.value("server").toString();
+    auto port = config.value("port").toInt();
+    auto user = config.value("username").toString();
+    auto password = config.value("password").toString();
+    if (server.startsWith("imap")) {
+        server.remove("imap://");
+        server.remove("imaps://");
+    }
+    if (server.contains(':')) {
+        auto list = server.split(':');
+        server = list.at(0);
+        port = list.at(1).toInt();
     }
-    return KAsync::null<void>();
+
+    auto synchronizer = QSharedPointer<ImapSynchronizer>::create(resourceContext);
+    synchronizer->mServer = server;
+    synchronizer->mPort = port;
+    synchronizer->mUser = user;
+    synchronizer->mPassword = password;
+    setupSynchronizer(synchronizer);
+
+    auto inspector = QSharedPointer<ImapInspector>::create(resourceContext);
+    inspector->mServer = server;
+    inspector->mPort = port;
+    inspector->mUser = user;
+    inspector->mPassword = password;
+    setupInspector(inspector);
+
+    setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new \
SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) \
<< new MimeMessageMover << new MailPropertyExtractor); +    \
setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>());  }
 
 ImapResourceFactory::ImapResourceFactory(QObject *parent)
diff --git a/examples/imapresource/imapresource.h \
b/examples/imapresource/imapresource.h index d345d64..aeb1200 100644
--- a/examples/imapresource/imapresource.h
+++ b/examples/imapresource/imapresource.h
@@ -40,13 +40,6 @@ class ImapResource : public Sink::GenericResource
 {
 public:
     ImapResource(const Sink::ResourceContext &resourceContext);
-    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
                const QVariant &expectedValue) Q_DECL_OVERRIDE;
-
-private:
-    QString mServer;
-    int mPort;
-    QString mUser;
-    QString mPassword;
 };
 
 class ImapResourceFactory : public Sink::ResourceFactory
diff --git a/examples/maildirresource/maildirresource.cpp \
b/examples/maildirresource/maildirresource.cpp index ee84bde..2b19789 100644
--- a/examples/maildirresource/maildirresource.cpp
+++ b/examples/maildirresource/maildirresource.cpp
@@ -27,6 +27,7 @@
 #include "libmaildir/maildir.h"
 #include "inspection.h"
 #include "synchronizer.h"
+#include "inspector.h"
 
 #include "facadefactory.h"
 #include "adaptorfactoryregistry.h"
@@ -425,6 +426,102 @@ public:
     QString mMaildirPath;
 };
 
+class MaildirInspector : public Sink::Inspector {
+public:
+    MaildirInspector(const Sink::ResourceContext &resourceContext)
+        : Sink::Inspector(resourceContext)
+    {
+
+    }
+protected:
+
+    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
const QVariant &expectedValue) Q_DECL_OVERRIDE { +        auto synchronizationStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId() + ".synchronization", \
Sink::Storage::DataStore::ReadOnly); +        auto synchronizationTransaction = \
synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +
+        auto mainStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly); +        auto \
transaction = mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly); +
+        Sink::Storage::EntityStore entityStore(mResourceContext);
+        auto syncStore = \
QSharedPointer<RemoteIdMap>::create(synchronizationTransaction); +
+        SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << \
property << expectedValue; +
+        if (domainType == ENTITY_TYPE_MAIL) {
+            auto mail = \
entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId); +            const \
auto filePath = getFilePathFromMimeMessagePath(mail.getMimeMessagePath()); +
+            if (inspectionType == \
Sink::ResourceControl::Inspection::PropertyInspectionType) { +                if \
(property == "unread") { +                    const auto flags = \
KPIM::Maildir::readEntryFlags(filePath.split('/').last()); +                    if \
(expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { +                        \
return KAsync::error<void>(1, "Expected unread but couldn't find it."); +             \
} +                    if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) \
{ +                        return KAsync::error<void>(1, "Expected read but couldn't \
find it."); +                    }
+                    return KAsync::null<void>();
+                }
+                if (property == "subject") {
+                    KMime::Message *msg = new KMime::Message;
+                    \
msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath))); +   \
msg->parse(); +
+                    if (msg->subject(true)->asUnicodeString() != \
expectedValue.toString()) { +                        return KAsync::error<void>(1, \
"Subject not as expected: " + msg->subject(true)->asUnicodeString()); +               \
} +                    return KAsync::null<void>();
+                }
+            }
+            if (inspectionType == \
Sink::ResourceControl::Inspection::ExistenceInspectionType) { +                if \
(QFileInfo(filePath).exists() != expectedValue.toBool()) { +                    \
return KAsync::error<void>(1, "Wrong file existence: " + filePath); +                \
} +            }
+        }
+        if (domainType == ENTITY_TYPE_FOLDER) {
+            const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, \
entityId); +            auto folder = \
entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId); +
+            if (inspectionType == \
Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) { +                \
SinkTrace() << "Inspecting cache integrity" << remoteId; +                if \
(!QDir(remoteId).exists()) { +                    return KAsync::error<void>(1, "The \
directory is not existing: " + remoteId); +                }
+
+                int expectedCount = 0;
+                Index index("mail.index.folder", transaction);
+                index.lookup(entityId, [&](const QByteArray &sinkId) {
+                        expectedCount++;
+                },
+                [&](const Index::Error &error) {
+                    SinkWarning() << "Error in index: " <<  error.message << \
property; +                });
+
+                QDir dir(remoteId + "/cur");
+                const QFileInfoList list = dir.entryInfoList(QDir::Files);
+                if (list.size() != expectedCount) {
+                    for (const auto &fileInfo : list) {
+                        SinkWarning() << "Found in cache: " << fileInfo.fileName();
+                    }
+                    return KAsync::error<void>(1, QString("Wrong number of files; \
found %1 instead of %2.").arg(list.size()).arg(expectedCount)); +                }
+            }
+            if (inspectionType == \
Sink::ResourceControl::Inspection::ExistenceInspectionType) { +                if \
(!remoteId.endsWith(folder.getName().toUtf8())) { +                    return \
KAsync::error<void>(1, "Wrong folder name: " + remoteId); +                }
+                //TODO we shouldn't use the remoteId here to figure out the path, it \
could be gone/changed already +                if (QDir(remoteId).exists() != \
expectedValue.toBool()) { +                    return KAsync::error<void>(1, "Wrong \
folder existence: " + remoteId); +                }
+            }
+
+        }
+        return KAsync::null<void>();
+    }
+};
+
 
 MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext)
     : Sink::GenericResource(resourceContext)
@@ -439,6 +536,7 @@ MaildirResource::MaildirResource(const Sink::ResourceContext \
                &resourceContext)
     auto synchronizer = \
QSharedPointer<MaildirSynchronizer>::create(resourceContext);  \
synchronizer->mMaildirPath = mMaildirPath;  setupSynchronizer(synchronizer);
+    setupInspector(QSharedPointer<MaildirInspector>::create(resourceContext));
 
     setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new \
SpecialPurposeProcessor(resourceContext.resourceType, resourceContext.instanceId()) \
<< new MaildirMimeMessageMover(resourceContext.instanceId(), mMaildirPath) << new \
                MaildirMailPropertyExtractor);
     setupPreprocessors(ENTITY_TYPE_FOLDER, QVector<Sink::Preprocessor*>() << new \
FolderPreprocessor(mMaildirPath)); @@ -458,93 +556,6 @@ \
MaildirResource::MaildirResource(const Sink::ResourceContext &resourceContext)  \
synchronizer->commit();  }
 
-KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray \
&inspectionId, const QByteArray &domainType, const QByteArray &entityId, const \
                QByteArray &property, const QVariant &expectedValue)
-{
-    auto synchronizationStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
mResourceContext.instanceId() + ".synchronization", \
                Sink::Storage::DataStore::ReadOnly);
-    auto synchronizationTransaction = \
                synchronizationStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
                
-
-    auto mainStore = \
QSharedPointer<Sink::Storage::DataStore>::create(Sink::storageLocation(), \
                mResourceContext.instanceId(), Sink::Storage::DataStore::ReadOnly);
-    auto transaction = \
                mainStore->createTransaction(Sink::Storage::DataStore::ReadOnly);
-
-    Sink::Storage::EntityStore entityStore(mResourceContext);
-    auto syncStore = \
                QSharedPointer<RemoteIdMap>::create(synchronizationTransaction);
-
-    SinkTrace() << "Inspecting " << inspectionType << domainType << entityId << \
                property << expectedValue;
-
-    if (domainType == ENTITY_TYPE_MAIL) {
-        auto mail = entityStore.readLatest<Sink::ApplicationDomain::Mail>(entityId);
-        const auto filePath = \
                getFilePathFromMimeMessagePath(mail.getMimeMessagePath());
-
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::PropertyInspectionType) {
-            if (property == "unread") {
-                const auto flags = \
                KPIM::Maildir::readEntryFlags(filePath.split('/').last());
-                if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) {
-                    return KAsync::error<void>(1, "Expected unread but couldn't find \
                it.");
-                }
-                if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) {
-                    return KAsync::error<void>(1, "Expected read but couldn't find \
                it.");
-                }
-                return KAsync::null<void>();
-            }
-            if (property == "subject") {
-                KMime::Message *msg = new KMime::Message;
-                msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(filePath)));
                
-                msg->parse();
-
-                if (msg->subject(true)->asUnicodeString() != \
                expectedValue.toString()) {
-                    return KAsync::error<void>(1, "Subject not as expected: " + \
                msg->subject(true)->asUnicodeString());
-                }
-                return KAsync::null<void>();
-            }
-        }
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::ExistenceInspectionType) {
-            if (QFileInfo(filePath).exists() != expectedValue.toBool()) {
-                return KAsync::error<void>(1, "Wrong file existence: " + filePath);
-            }
-        }
-    }
-    if (domainType == ENTITY_TYPE_FOLDER) {
-        const auto remoteId = syncStore->resolveLocalId(ENTITY_TYPE_FOLDER, \
                entityId);
-        auto folder = \
                entityStore.readLatest<Sink::ApplicationDomain::Folder>(entityId);
-
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::CacheIntegrityInspectionType) {
-            SinkTrace() << "Inspecting cache integrity" << remoteId;
-            if (!QDir(remoteId).exists()) {
-                return KAsync::error<void>(1, "The directory is not existing: " + \
                remoteId);
-            }
-
-            int expectedCount = 0;
-            Index index("mail.index.folder", transaction);
-            index.lookup(entityId, [&](const QByteArray &sinkId) {
-                    expectedCount++;
-            },
-            [&](const Index::Error &error) {
-                SinkWarning() << "Error in index: " <<  error.message << property;
-            });
-
-            QDir dir(remoteId + "/cur");
-            const QFileInfoList list = dir.entryInfoList(QDir::Files);
-            if (list.size() != expectedCount) {
-                for (const auto &fileInfo : list) {
-                    SinkWarning() << "Found in cache: " << fileInfo.fileName();
-                }
-                return KAsync::error<void>(1, QString("Wrong number of files; found \
                %1 instead of %2.").arg(list.size()).arg(expectedCount));
-            }
-        }
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::ExistenceInspectionType) {
-            if (!remoteId.endsWith(folder.getName().toUtf8())) {
-                return KAsync::error<void>(1, "Wrong folder name: " + remoteId);
-            }
-            //TODO we shouldn't use the remoteId here to figure out the path, it \
                could be gone/changed already
-            if (QDir(remoteId).exists() != expectedValue.toBool()) {
-                return KAsync::error<void>(1, "Wrong folder existence: " + \
                remoteId);
-            }
-        }
-
-    }
-    return KAsync::null<void>();
-}
-
 
 MaildirResourceFactory::MaildirResourceFactory(QObject *parent)
     : Sink::ResourceFactory(parent)
diff --git a/examples/maildirresource/maildirresource.h \
b/examples/maildirresource/maildirresource.h index 4eb2042..61fe438 100644
--- a/examples/maildirresource/maildirresource.h
+++ b/examples/maildirresource/maildirresource.h
@@ -43,9 +43,8 @@ class MaildirResource : public Sink::GenericResource
 {
 public:
     MaildirResource(const Sink::ResourceContext &resourceContext);
-    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
                const QVariant &expectedValue) Q_DECL_OVERRIDE;
-private:
 
+private:
     QStringList listAvailableFolders();
     QString mMaildirPath;
     QString mDraftsFolder;
diff --git a/examples/mailtransportresource/mailtransportresource.cpp \
b/examples/mailtransportresource/mailtransportresource.cpp index c135de9..524b411 \
                100644
--- a/examples/mailtransportresource/mailtransportresource.cpp
+++ b/examples/mailtransportresource/mailtransportresource.cpp
@@ -22,7 +22,7 @@
 #include "facadefactory.h"
 #include "resourceconfig.h"
 #include "definitions.h"
-#include "domainadaptor.h"
+#include "inspector.h"
 #include <QDir>
 #include <QFileInfo>
 #include <QSettings>
@@ -124,6 +124,31 @@ public:
     MailtransportResource::Settings mSettings;
 };
 
+class MailtransportInspector : public Sink::Inspector {
+public:
+    MailtransportInspector(const Sink::ResourceContext &resourceContext)
+        : Sink::Inspector(resourceContext)
+    {
+
+    }
+
+protected:
+    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
const QVariant &expectedValue) Q_DECL_OVERRIDE +    {
+        if (domainType == ENTITY_TYPE_MAIL) {
+            if (inspectionType == \
Sink::ResourceControl::Inspection::ExistenceInspectionType) { +                auto \
path = resourceStorageLocation(mResourceContext.instanceId()) + "/test/" + entityId; \
+                if (QFileInfo::exists(path)) { +                    return \
KAsync::null<void>(); +                }
+                return KAsync::error<void>(1, "Couldn't find message: " + path);
+            }
+        }
+        return KAsync::null<void>();
+    }
+};
+
+
 MailtransportResource::MailtransportResource(const Sink::ResourceContext \
&resourceContext)  : Sink::GenericResource(resourceContext)
 {
@@ -138,30 +163,11 @@ MailtransportResource::MailtransportResource(const \
                Sink::ResourceContext &resour
     auto synchronizer = \
QSharedPointer<MailtransportSynchronizer>::create(resourceContext);  \
synchronizer->mSettings = mSettings;  setupSynchronizer(synchronizer);
+    setupInspector(QSharedPointer<MailtransportInspector>::create(resourceContext));
 
     setupPreprocessors(ENTITY_TYPE_MAIL, QVector<Sink::Preprocessor*>() << new \
MimeMessageMover << new MailPropertyExtractor);  }
 
-void MailtransportResource::removeFromDisk(const QByteArray &instanceIdentifier)
-{
-    GenericResource::removeFromDisk(instanceIdentifier);
-    Sink::Storage::DataStore(Sink::storageLocation(), instanceIdentifier + \
                ".synchronization", \
                Sink::Storage::DataStore::ReadWrite).removeFromDisk();
-}
-
-KAsync::Job<void> MailtransportResource::inspect(int inspectionType, const \
QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, \
                const QByteArray &property, const QVariant &expectedValue)
-{
-    if (domainType == ENTITY_TYPE_MAIL) {
-        if (inspectionType == \
                Sink::ResourceControl::Inspection::ExistenceInspectionType) {
-            auto path = resourceStorageLocation(mResourceContext.instanceId()) + \
                "/test/" + entityId;
-            if (QFileInfo::exists(path)) {
-                return KAsync::null<void>();
-            }
-            return KAsync::error<void>(1, "Couldn't find message: " + path);
-        }
-    }
-    return KAsync::null<void>();
-}
-
 MailtransportResourceFactory::MailtransportResourceFactory(QObject *parent)
     : Sink::ResourceFactory(parent)
 {
diff --git a/examples/mailtransportresource/mailtransportresource.h \
b/examples/mailtransportresource/mailtransportresource.h index 95a9cd7..531fcd5 \
                100644
--- a/examples/mailtransportresource/mailtransportresource.h
+++ b/examples/mailtransportresource/mailtransportresource.h
@@ -26,8 +26,6 @@ class MailtransportResource : public Sink::GenericResource
 {
 public:
     MailtransportResource(const Sink::ResourceContext &resourceContext);
-    KAsync::Job<void> inspect(int inspectionType, const QByteArray &inspectionId, \
const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, \
                const QVariant &expectedValue) Q_DECL_OVERRIDE;
-    static void removeFromDisk(const QByteArray &instanceIdentifier);
 
     struct Settings {
         QString server;


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic