1// Copyright (C) 2017 Ford Motor Company
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QREMOTEOBJECTNODE_H
6#define QREMOTEOBJECTNODE_H
7
8#include <QtCore/qsharedpointer.h>
9#include <QtCore/qmetaobject.h>
10#include <QtNetwork/qlocalserver.h>
11#include <QtRemoteObjects/qtremoteobjectglobal.h>
12#include <QtRemoteObjects/qremoteobjectregistry.h>
13#include <QtRemoteObjects/qremoteobjectdynamicreplica.h>
14
15#include <functional>
16
17QT_BEGIN_NAMESPACE
18
19class QRemoteObjectReplica;
20class SourceApiMap;
21class QAbstractItemModel;
22class QAbstractItemModelReplica;
23class QItemSelectionModel;
24class QRemoteObjectAbstractPersistedStorePrivate;
25class QRemoteObjectNodePrivate;
26class QRemoteObjectHostBasePrivate;
27class QRemoteObjectHostPrivate;
28class QRemoteObjectRegistryHostPrivate;
29
30class Q_REMOTEOBJECTS_EXPORT QRemoteObjectAbstractPersistedStore : public QObject
31{
32 Q_OBJECT
33
34public:
35 QRemoteObjectAbstractPersistedStore (QObject *parent = nullptr);
36 virtual ~QRemoteObjectAbstractPersistedStore();
37
38 virtual void saveProperties(const QString &repName, const QByteArray &repSig, const QVariantList &values) = 0;
39 virtual QVariantList restoreProperties(const QString &repName, const QByteArray &repSig) = 0;
40
41protected:
42 QRemoteObjectAbstractPersistedStore(QRemoteObjectAbstractPersistedStorePrivate &, QObject *parent);
43 Q_DECLARE_PRIVATE(QRemoteObjectAbstractPersistedStore)
44};
45
46class Q_REMOTEOBJECTS_EXPORT QRemoteObjectNode : public QObject
47{
48 Q_OBJECT
49 Q_PROPERTY(QUrl registryUrl READ registryUrl WRITE setRegistryUrl)
50 Q_PROPERTY(QRemoteObjectAbstractPersistedStore* persistedStore READ persistedStore WRITE setPersistedStore)
51 Q_PROPERTY(int heartbeatInterval READ heartbeatInterval WRITE setHeartbeatInterval NOTIFY heartbeatIntervalChanged)
52
53public:
54 enum ErrorCode{
55 NoError,
56 RegistryNotAcquired,
57 RegistryAlreadyHosted,
58 NodeIsNoServer,
59 ServerAlreadyCreated,
60 UnintendedRegistryHosting,
61 OperationNotValidOnClientNode,
62 SourceNotRegistered,
63 MissingObjectName,
64 HostUrlInvalid,
65 ProtocolMismatch,
66 ListenFailed,
67 SocketAccessError
68 };
69 Q_ENUM(ErrorCode)
70
71 QRemoteObjectNode(QObject *parent = nullptr);
72 QRemoteObjectNode(const QUrl &registryAddress, QObject *parent = nullptr);
73 ~QRemoteObjectNode() override;
74
75 Q_INVOKABLE bool connectToNode(const QUrl &address);
76 void addClientSideConnection(QIODevice *ioDevice);
77 virtual void setName(const QString &name);
78 template < class ObjectType >
79 ObjectType *acquire(const QString &name = QString())
80 {
81 return new ObjectType(this, name);
82 }
83
84 template<typename T>
85 QStringList instances() const
86 {
87 const QMetaObject *mobj = &T::staticMetaObject;
88 const int index = mobj->indexOfClassInfo(QCLASSINFO_REMOTEOBJECT_TYPE);
89 if (index == -1)
90 return QStringList();
91
92 const QString typeName = QString::fromLatin1(ba: mobj->classInfo(index).value());
93 return instances(typeName);
94 }
95 QStringList instances(QStringView typeName) const;
96
97 QRemoteObjectDynamicReplica *acquireDynamic(const QString &name);
98 QAbstractItemModelReplica *acquireModel(const QString &name, QtRemoteObjects::InitialAction action = QtRemoteObjects::FetchRootSize, const QList<int> &rolesHint = {});
99 QUrl registryUrl() const;
100 virtual bool setRegistryUrl(const QUrl &registryAddress);
101 bool waitForRegistry(int timeout = 30000);
102 const QRemoteObjectRegistry *registry() const;
103
104 QRemoteObjectAbstractPersistedStore *persistedStore() const;
105 void setPersistedStore(QRemoteObjectAbstractPersistedStore *persistedStore);
106
107 ErrorCode lastError() const;
108
109 int heartbeatInterval() const;
110 void setHeartbeatInterval(int interval);
111
112 typedef std::function<void (QUrl)> RemoteObjectSchemaHandler;
113 void registerExternalSchema(const QString &schema, RemoteObjectSchemaHandler handler);
114
115Q_SIGNALS:
116 void remoteObjectAdded(const QRemoteObjectSourceLocation &);
117 void remoteObjectRemoved(const QRemoteObjectSourceLocation &);
118
119 void error(QRemoteObjectNode::ErrorCode errorCode);
120 void heartbeatIntervalChanged(int heartbeatInterval);
121
122protected:
123 QRemoteObjectNode(QRemoteObjectNodePrivate &, QObject *parent);
124
125 void timerEvent(QTimerEvent*) override;
126
127private:
128 void initializeReplica(QRemoteObjectReplica *instance, const QString &name = QString());
129 void persistProperties(const QString &repName, const QByteArray &repSig, const QVariantList &props);
130 QVariantList retrieveProperties(const QString &repName, const QByteArray &repSig);
131
132 Q_DECLARE_PRIVATE(QRemoteObjectNode)
133 friend class QRemoteObjectReplica;
134 friend class QConnectedReplicaImplementation;
135};
136
137class Q_REMOTEOBJECTS_EXPORT QRemoteObjectHostBase : public QRemoteObjectNode
138{
139 Q_OBJECT
140public:
141 enum AllowedSchemas { BuiltInSchemasOnly, AllowExternalRegistration };
142 Q_ENUM(AllowedSchemas)
143 ~QRemoteObjectHostBase() override;
144 void setName(const QString &name) override;
145
146 template <template <typename> class ApiDefinition, typename ObjectType>
147 bool enableRemoting(ObjectType *object)
148 {
149 ApiDefinition<ObjectType> *api = new ApiDefinition<ObjectType>(object);
150 return enableRemoting(object, api);
151 }
152 Q_INVOKABLE bool enableRemoting(QObject *object, const QString &name = QString());
153 bool enableRemoting(QAbstractItemModel *model, const QString &name, const QList<int> roles, QItemSelectionModel *selectionModel = nullptr);
154 Q_INVOKABLE bool disableRemoting(QObject *remoteObject);
155 void addHostSideConnection(QIODevice *ioDevice);
156
157 typedef std::function<bool(QStringView, QStringView)> RemoteObjectNameFilter;
158 bool proxy(const QUrl &registryUrl, const QUrl &hostUrl={},
159 RemoteObjectNameFilter filter=[](QStringView, QStringView) {return true; });
160 // TODO: Currently the reverse aspect requires the registry, so this is supported only for
161 // QRemoteObjectRegistryHost for now. Consider enabling it also for QRemoteObjectHost.
162 bool reverseProxy(RemoteObjectNameFilter filter=[](QStringView, QStringView) {return true; });
163
164protected:
165 virtual QUrl hostUrl() const;
166 virtual bool setHostUrl(const QUrl &hostAddress, AllowedSchemas allowedSchemas=BuiltInSchemasOnly);
167 QRemoteObjectHostBase(QRemoteObjectHostBasePrivate &, QObject *);
168
169private:
170 bool enableRemoting(QObject *object, const SourceApiMap *, QObject *adapter = nullptr);
171 Q_DECLARE_PRIVATE(QRemoteObjectHostBase)
172};
173
174class Q_REMOTEOBJECTS_EXPORT QRemoteObjectHost : public QRemoteObjectHostBase
175{
176 Q_OBJECT
177 Q_PROPERTY(QUrl hostUrl READ hostUrl WRITE setHostUrl NOTIFY hostUrlChanged)
178
179public:
180 QRemoteObjectHost(QObject *parent = nullptr);
181 QRemoteObjectHost(const QUrl &address, const QUrl &registryAddress = QUrl(),
182 AllowedSchemas allowedSchemas=BuiltInSchemasOnly, QObject *parent = nullptr);
183 QRemoteObjectHost(const QUrl &address, QObject *parent);
184 ~QRemoteObjectHost() override;
185 QUrl hostUrl() const override;
186 bool setHostUrl(const QUrl &hostAddress, AllowedSchemas allowedSchemas=BuiltInSchemasOnly) override;
187 static void setLocalServerOptions(QLocalServer::SocketOptions options);
188
189Q_SIGNALS:
190 void hostUrlChanged();
191
192protected:
193 QRemoteObjectHost(QRemoteObjectHostPrivate &, QObject *);
194
195private:
196 Q_DECLARE_PRIVATE(QRemoteObjectHost)
197};
198
199class Q_REMOTEOBJECTS_EXPORT QRemoteObjectRegistryHost : public QRemoteObjectHostBase
200{
201 Q_OBJECT
202public:
203 QRemoteObjectRegistryHost(const QUrl &registryAddress = QUrl(), QObject *parent = nullptr);
204 ~QRemoteObjectRegistryHost() override;
205 bool setRegistryUrl(const QUrl &registryUrl) override;
206
207protected:
208 QRemoteObjectRegistryHost(QRemoteObjectRegistryHostPrivate &, QObject *);
209
210private:
211 Q_DECLARE_PRIVATE(QRemoteObjectRegistryHost)
212};
213
214QT_END_NAMESPACE
215
216#endif
217

source code of qtremoteobjects/src/remoteobjects/qremoteobjectnode.h