File indexing completed on 2025-02-16 04:50:11
0001 /* 0002 SPDX-FileCopyrightText: 2015-2020 Krzysztof Nowicki <krissn@op.pl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include <QSet> 0010 #include <QString> 0011 #include <QTimer> 0012 0013 #include "ewsid.h" 0014 0015 class EwsClient; 0016 class KJob; 0017 class EwsEventRequestBase; 0018 class EwsSettings; 0019 0020 /** 0021 * @brief Mailbox update subscription manager class 0022 * 0023 * This class is responsible for retrieving update notifications from the Exchange server. 0024 * 0025 * The Exchange server has the ability to incrementally inform the client about changes made to 0026 * selected folders in the mailbox. Each update informs about creation, modification or removal 0027 * of an item or folder. Additionally Exchange has the ability to notify about free/busy status 0028 * updates. 0029 * 0030 * Notifications can be delivered in 3 ways: 0031 * - pull (i.e. polling) - the client needs to periodically question the server. 0032 * - push - the server issues a callback connection to the client with events (not supported) 0033 * - streaming - a combination of pull and push, where the client makes the connection, but the 0034 * server keeps it open for a specified period of time and keeps delivering events 0035 * over this connection (supported since Exchange 2010 SP2). 0036 * 0037 * The responsibility of this class is to retrieve and act upon change events from the Exchange 0038 * server. The current implementation is simplified: 0039 * - when an item update is received the folder containing the update is asked to synchronize 0040 * itself. 0041 * - when a folder update is received a full collection tree sync is performed. 0042 * 0043 * The above implementation has a major drawback in that operations performed by the resource 0044 * itself are also notified back as update events. This means that when for ex. an item is deleted 0045 * it is removed from Akonadi database, but subsequently a delete event is received which will try 0046 * to delete an item that has already been deleted from Akonadi. 0047 */ 0048 class EwsSubscriptionManager : public QObject 0049 { 0050 Q_OBJECT 0051 public: 0052 EwsSubscriptionManager(EwsClient &client, const EwsId &rootId, EwsSettings *settings, QObject *parent); 0053 ~EwsSubscriptionManager() override; 0054 void start(); 0055 Q_SIGNALS: 0056 void foldersModified(EwsId::List folders); 0057 void folderTreeModified(); 0058 void fullSyncRequested(); 0059 void connectionError(); 0060 0061 private: 0062 void subscribeRequestFinished(KJob *job); 0063 void verifySubFoldersRequestFinished(KJob *job); 0064 void getEventsRequestFinished(KJob *job); 0065 void streamingEventsReceived(KJob *job); 0066 void getEvents(); 0067 void streamingConnectionTimeout(); 0068 0069 private: 0070 void cancelSubscription(); 0071 void setupSubscription(); 0072 void setupSubscriptionReq(const EwsId::List &ids); 0073 void reset(); 0074 void resetSubscription(); 0075 void processEvents(EwsEventRequestBase *req, bool finished); 0076 0077 EwsClient &mEwsClient; 0078 QTimer mPollTimer; 0079 EwsId mMsgRootId; 0080 0081 QSet<EwsId> mUpdatedFolderIds; 0082 bool mFolderTreeChanged; 0083 bool mStreamingEvents; 0084 QTimer mStreamingTimer; 0085 EwsEventRequestBase *mEventReq = nullptr; 0086 EwsSettings *mSettings = nullptr; 0087 };