1 /*
2     SPDX-FileCopyrightText: 2009 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #pragma once
8 
9 #include "akthread.h"
10 #include "itemretrievalrequest.h"
11 #include "itemretriever.h"
12 #include <shared/akstd.h>
13 
14 #include <QHash>
15 class QObject;
16 #include <QReadWriteLock>
17 #include <QWaitCondition>
18 
19 #include <unordered_map>
20 
21 class OrgFreedesktopAkonadiResourceInterface;
22 
23 namespace Akonadi
24 {
25 namespace Server
26 {
27 class Collection;
28 class ItemRetrievalJob;
29 class AbstractItemRetrievalJob;
30 
31 class AbstractItemRetrievalJobFactory
32 {
33 public:
34     virtual ~AbstractItemRetrievalJobFactory() = default;
35 
36     virtual AbstractItemRetrievalJob *retrievalJob(ItemRetrievalRequest request, QObject *parent) = 0;
37 
38 protected:
39     explicit AbstractItemRetrievalJobFactory() = default;
40 
41 private:
42     Q_DISABLE_COPY_MOVE(AbstractItemRetrievalJobFactory)
43 };
44 
45 /** Manages and processes item retrieval requests. */
46 class ItemRetrievalManager : public AkThread
47 {
48     Q_OBJECT
49 public:
50     explicit ItemRetrievalManager(QObject *parent = nullptr);
51     explicit ItemRetrievalManager(std::unique_ptr<AbstractItemRetrievalJobFactory> factory, QObject *parent = nullptr);
52     ~ItemRetrievalManager() override;
53 
54     /**
55      * Added for convenience. ItemRetrievalManager takes ownership over the
56      * pointer and deletes it when the request is processed.
57      */
58     virtual void requestItemDelivery(ItemRetrievalRequest request);
59 
60     void triggerCollectionSync(const QString &resource, qint64 colId);
61     void triggerCollectionTreeSync(const QString &resource);
62 
63 Q_SIGNALS:
64     void requestFinished(const Akonadi::Server::ItemRetrievalResult &result);
65     void requestAdded();
66 
67 private:
68     OrgFreedesktopAkonadiResourceInterface *resourceInterface(const QString &id);
69     QVector<AbstractItemRetrievalJob *> scheduleJobsForIdleResourcesLocked();
70 
71 private Q_SLOTS:
72     void init() override;
73 
74     void serviceOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
75     void processRequest();
76     void retrievalJobFinished(Akonadi::Server::AbstractItemRetrievalJob *job);
77 
78 protected:
79     std::unique_ptr<AbstractItemRetrievalJobFactory> mJobFactory;
80 
81     /// Protects mPendingRequests and every Request object posted to it
82     QReadWriteLock mLock;
83     /// Used to let requesting threads wait until the request has been processed
84     QWaitCondition mWaitCondition;
85 
86     /// Pending requests queues, one per resource
87     std::unordered_map<QString, std::list<ItemRetrievalRequest>> mPendingRequests;
88     /// Currently running jobs, one per resource
89     QHash<QString, AbstractItemRetrievalJob *> mCurrentJobs;
90 
91     // resource dbus interface cache
92     std::unordered_map<QString, std::unique_ptr<OrgFreedesktopAkonadiResourceInterface>> mResourceInterfaces;
93 };
94 
95 } // namespace Server
96 } // namespace Akonadi
97 
98