File indexing completed on 2024-05-12 05:26:03
0001 /* 0002 * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) version 3, or any 0008 * later version accepted by the membership of KDE e.V. (or its 0009 * successor approved by the membership of KDE e.V.), which shall 0010 * act as a proxy defined in Section 6 of version 3 of the license. 0011 * 0012 * This library is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 * Lesser General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU Lesser General Public 0018 * License along with this library. If not, see <http://www.gnu.org/licenses/>. 0019 */ 0020 0021 #pragma once 0022 0023 #include "sink_export.h" 0024 #include <QLocalSocket> 0025 #include <QObject> 0026 #include <QTimer> 0027 0028 #include <KAsync/Async> 0029 0030 #include <flatbuffers/flatbuffers.h> 0031 #include "notification.h" 0032 #include "flush.h" 0033 #include "query.h" 0034 #include "log.h" 0035 0036 namespace Sink { 0037 0038 struct QueuedCommand; 0039 0040 class SINK_EXPORT ResourceAccessInterface : public QObject 0041 { 0042 Q_OBJECT 0043 public: 0044 typedef QSharedPointer<ResourceAccessInterface> Ptr; 0045 0046 ResourceAccessInterface() 0047 : QObject() 0048 { 0049 } 0050 virtual ~ResourceAccessInterface() 0051 { 0052 } 0053 virtual KAsync::Job<void> sendCommand(int commandId) = 0; 0054 virtual KAsync::Job<void> sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb) = 0; 0055 virtual KAsync::Job<void> synchronizeResource(const Sink::QueryBase &filter) = 0; 0056 0057 virtual KAsync::Job<void> sendCreateCommand(const QByteArray &uid, const QByteArray &resourceBufferType, const QByteArray &buffer) 0058 { 0059 return KAsync::null<void>(); 0060 }; 0061 virtual KAsync::Job<void> sendModifyCommand(const QByteArray &uid, qint64 revision, const QByteArray &resourceBufferType, const QByteArrayList &deletedProperties, const QByteArray &buffer, const QByteArrayList &changedProperties, const QByteArray &newResource, bool remove) 0062 { 0063 return KAsync::null<void>(); 0064 }; 0065 virtual KAsync::Job<void> sendDeleteCommand(const QByteArray &uid, qint64 revision, const QByteArray &resourceBufferType) 0066 { 0067 return KAsync::null<void>(); 0068 }; 0069 virtual KAsync::Job<void> sendRevisionReplayedCommand(qint64 revision) 0070 { 0071 return KAsync::null<void>(); 0072 }; 0073 virtual KAsync::Job<void> 0074 sendInspectionCommand(int inspectionType, const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expecedValue) 0075 { 0076 return KAsync::null<void>(); 0077 }; 0078 0079 virtual KAsync::Job<void> sendFlushCommand(int flushType, const QByteArray &flushId) 0080 { 0081 return KAsync::null<void>(); 0082 } 0083 0084 virtual KAsync::Job<void> sendSecret(const QString &secret) 0085 { 0086 return KAsync::null<void>(); 0087 } 0088 0089 virtual KAsync::Job<void> shutdown() 0090 { 0091 return KAsync::null<void>(); 0092 } 0093 0094 int getResourceStatus() const 0095 { 0096 return mResourceStatus; 0097 } 0098 0099 signals: 0100 void ready(bool isReady); 0101 void revisionChanged(qint64 revision); 0102 void notification(Notification notification); 0103 0104 public slots: 0105 virtual void open() = 0; 0106 virtual void close() = 0; 0107 0108 protected: 0109 int mResourceStatus; 0110 }; 0111 0112 class SINK_EXPORT ResourceAccess : public ResourceAccessInterface 0113 { 0114 Q_OBJECT 0115 public: 0116 typedef QSharedPointer<ResourceAccess> Ptr; 0117 0118 ResourceAccess(const QByteArray &resourceInstanceIdentifier, const QByteArray &resourceType); 0119 virtual ~ResourceAccess() Q_DECL_OVERRIDE; 0120 0121 QByteArray resourceName() const; 0122 bool isReady() const; 0123 0124 KAsync::Job<void> sendCommand(int commandId) Q_DECL_OVERRIDE; 0125 KAsync::Job<void> sendCommand(int commandId, flatbuffers::FlatBufferBuilder &fbb) Q_DECL_OVERRIDE; 0126 KAsync::Job<void> synchronizeResource(const Sink::QueryBase &filter) Q_DECL_OVERRIDE; 0127 KAsync::Job<void> sendCreateCommand(const QByteArray &uid, const QByteArray &resourceBufferType, const QByteArray &buffer) Q_DECL_OVERRIDE; 0128 KAsync::Job<void> 0129 sendModifyCommand(const QByteArray &uid, qint64 revision, const QByteArray &resourceBufferType, const QByteArrayList &deletedProperties, const QByteArray &buffer, const QByteArrayList &changedProperties, const QByteArray &newResource, bool remove) Q_DECL_OVERRIDE; 0130 KAsync::Job<void> sendDeleteCommand(const QByteArray &uid, qint64 revision, const QByteArray &resourceBufferType) Q_DECL_OVERRIDE; 0131 KAsync::Job<void> sendRevisionReplayedCommand(qint64 revision) Q_DECL_OVERRIDE; 0132 KAsync::Job<void> 0133 sendInspectionCommand(int inspectionType,const QByteArray &inspectionId, const QByteArray &domainType, const QByteArray &entityId, const QByteArray &property, const QVariant &expecedValue) Q_DECL_OVERRIDE; 0134 KAsync::Job<void> sendFlushCommand(int flushType, const QByteArray &flushId) Q_DECL_OVERRIDE; 0135 KAsync::Job<void> sendSecret(const QString &secret) Q_DECL_OVERRIDE; 0136 KAsync::Job<void> shutdown() Q_DECL_OVERRIDE; 0137 /** 0138 * Tries to connect to server, and returns a connected socket on success. 0139 */ 0140 static KAsync::Job<QSharedPointer<QLocalSocket>> connectToServer(const QByteArray &identifier); 0141 0142 public slots: 0143 void open() Q_DECL_OVERRIDE; 0144 void close() Q_DECL_OVERRIDE; 0145 0146 private slots: 0147 // TODO: move these to the Private class 0148 void disconnected(); 0149 void connectionError(QLocalSocket::LocalSocketError error); 0150 void readResourceMessage(); 0151 bool processMessageBuffer(); 0152 0153 private: 0154 void abort(); 0155 void connected(); 0156 void registerCallback(uint messageId, const std::function<void(int error, const QString &)> &callback); 0157 0158 void sendCommand(const QSharedPointer<QueuedCommand> &command); 0159 void processCommandQueue(); 0160 void processPendingCommandQueue(); 0161 void enqueueCommand(const QSharedPointer<QueuedCommand> &command); 0162 0163 class Private; 0164 Private *const d; 0165 }; 0166 0167 /** 0168 * A factory for resource access instances that caches the instance for some time. 0169 * 0170 * This avoids constantly recreating connections, and should allow a single process to have one connection per resource. 0171 */ 0172 class SINK_EXPORT ResourceAccessFactory 0173 { 0174 public: 0175 static ResourceAccessFactory &instance(); 0176 Sink::ResourceAccess::Ptr getAccess(const QByteArray &instanceIdentifier, const QByteArray resourceType); 0177 0178 private: 0179 ResourceAccessFactory(); 0180 0181 QHash<QByteArray, QWeakPointer<Sink::ResourceAccess>> mWeakCache; 0182 QHash<QByteArray, Sink::ResourceAccess::Ptr> mCache; 0183 QHash<QByteArray, QSharedPointer<QTimer>> mTimer; 0184 }; 0185 }