Remoto - VFS: VFS_node.h Source File
Remoto - VFS
VFS_node.h
Go to the documentation of this file.
1 
2 #ifndef VFS_NODE_H
3 #define VFS_NODE_H
4 
5 #include <QObject>
6 #include <QStringList>
7 #include <QMetaMethod>
8 #include <QMutex>
9 #include <QMap>
10 #include <QVariantMap>
11 #include <QSet>
12 #include <QJsonDocument>
13 #include <QJsonObject>
14 #include <QJsonArray>
15 
16 #define POST_ID_NONE 0
17 #define POST_ID_PING 1
18 #define POST_ID_SESSION_DATA 2
19 #define POST_ID_DIFF 7
20 #define POST_ID_CODE_DIRECTORY 16
21 #define POST_ID_START 256
22 #define POST_ID_MAX 65000
23 
24 typedef quint16 postID;
25 
26 Q_DECLARE_METATYPE(postID)
27 
28 class VFS_node;
29 class VFS_session;
30 
31 //typedef QMap<VFS_node *, qint32> VFS_subscriptionCounter;
32 //typedef QMap<QString, QMap<VFS_node *, qint32> > VFS_subscriptionOrigin;
33 //typedef QMap<QString, QMap<QString, QMap<VFS_node *, qint32> > > VFS_subscriptionType;
34 typedef QMap<VFS_node *, qint32> VFS_subscriptionCounter;
35 typedef QMap<QString, VFS_subscriptionCounter > VFS_subscriptionOrigin;
36 typedef QMap<QString, VFS_subscriptionOrigin > VFS_subscriptionType;
37 
38 typedef QMap<QString, VFS_node *> VFS_children;
39 typedef QMap<QString, VFS_node *>::iterator VFS_childrenIterator;
40 typedef QMap<QString, VFS_node *>::const_iterator VFS_childrenConstIterator;
41 
42 typedef QPair<VFS_node *, QString> notifyException;
43 
44 //uncomment this line to enable VFS_request debugging
45 //#define DEBUG_DANGLING_REQUESTS
46 
47 #ifdef DEBUG_DANGLING_REQUESTS
48 class VFS_request : public QObject
49 {
50  Q_OBJECT
51 
52 #else
54 {
55 #endif
56  friend class VFS_node;
57 
58  public:
59 
63  {
64  none = 0,
65  ls,
67  rm,
68  read,
71  diff,
75  acl,
79  code,
81  };
82 
83  VFS_request(requestType type=VFS_request::none, VFS_node *origin=nullptr, QString path="", QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false);
84  VFS_request(const VFS_request &c);
85  virtual ~VFS_request();
86 
88 
90  QString _originPath;
91 
93  QString _initialPath;
94  QStringList _prefixPath;
95  QString _path;
96 
98  bool _isCallback;
99  bool hasCallback();
100 
101  QJsonObject _metadata;
102  QJsonDocument _data;
103  QByteArray _rawData;
104 
106  QString _user;
107  bool _success;
108  QString _reason;
109 
110  QList<notifyException> _notifyExceptions;
111 
112  bool _dontDelete;
113 
114  virtual void setCallback(VFS_request *c);
115  virtual VFS_request *getCallback(VFS_node *receiver);
116  virtual void copyCallback(VFS_request *d);
117  virtual VFS_request *createDiff(VFS_node *origin, QString originPath);
118 
119  virtual QByteArray toJson(postID id=0, bool ignoreSuccess=false, bool includeInitialPath=false);
120  virtual void fromJsonObject(QJsonObject json, bool includeInitialPath=false);
121 
122  static long _refcount;
123  static quint32 _sampleCount;
124  static QMutex _sampleLock;
125  static quint32 getSample();
126 
127  static const char* requestTypeStrings[];
128 
129 #ifdef DEBUG_DANGLING_REQUESTS
130  protected slots:
131 #endif
132  virtual void timerEvent(QTimerEvent *e=nullptr);
133 
134  protected:
135  virtual void execute();
136 };
137 
138 Q_DECLARE_METATYPE(VFS_request*)
139 Q_DECLARE_METATYPE(VFS_request::requestType)
140 
141 
142 class VFS_node : public QObject
143 {
144  Q_OBJECT
145 
146  friend class VFS_session;
147  friend class VFS_thread;
148 
149  public:
150  Q_INVOKABLE explicit VFS_node();
151  virtual ~VFS_node();
152 
153  //navigation functions
154  VFS_node *find(QString path);
155  virtual VFS_node *find(VFS_request *r);
156 
157  //code functions
158  static QString code(QString nodename, QString libname, QString &error);
159 
160  //children functions
161  virtual VFS_node *append(QString name, VFS_node *node, bool containerCheck=true, QString user="server");
162  QString uniqueChildName(QString name);
163  VFS_node *findChildWithName(QString name);
164  virtual bool validChildName(QString name);
165 
166  virtual VFS_request *createRequest(VFS_request::requestType type, QString path, QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false);
167 
168  virtual bool isContainer();
169  QString className();
170  virtual QString reportDetails();
171 
172  virtual VFS_node *mount();
173  virtual VFS_node *unmount();
174 
175  static bool __isNode(VFS_node *);
176 
177  protected:
178  mutable QMutex _lock;
181 
182  virtual QByteArray icon();
183 
184  //from the current thread, issue a request/response to the slot in the target's thread with the request attached
185  virtual void issueRequest( VFS_request *t );
186  virtual void issueRequest( VFS_node *target, VFS_request *t );
187  virtual void issueResponse( VFS_request *t );
188 
189  //subscription functions
190  virtual void subscribe(VFS_request *r);
191  virtual void unsubscribe(VFS_request *r);
192  virtual void unsubscribePath(QString path);
193 
194  //operation functions
195  virtual void ls(VFS_request *r);
196  virtual void read(VFS_request *r);
197  virtual void write(VFS_request *r);
198  virtual void metadata(VFS_request *r);
199  virtual void report(VFS_request *r);
200  virtual void submit(VFS_request *r);
201  virtual void rm(VFS_request *r);
202  virtual void requestLock(VFS_request *r);
203  virtual void releaseLock(VFS_request *r);
204  virtual void aclDefaults(VFS_request *r);
205 
206  //acl functions
207  void addACLDefault( QJsonObject &acl, bool value, QString description="" );
208  void addACLGroup( QJsonObject &acl, QString group, bool value );
209  void addACLUser( QJsonObject &acl, QString user, bool value );
210  void addACLFeature( QJsonObject &acl, QString feature, bool value, QString description="" );
211  void addACLFeatureGroup( QJsonObject &acl, QString feature, QString group, bool value );
212  void addACLFeatureUser( QJsonObject &acl, QString feature, QString user, bool value );
213 
214  private:
215  static QSet<VFS_node *> __allNodes;
216  static QMutex __allNodesMutex;
217  static void __addNode(VFS_node *);
218  static bool __removeNode(VFS_node *);
219 
220  signals:
221  void mounted();
222  void unmounted(VFS_node *self);
223  void finished(bool andDelete=false);
224 
225  void diff(VFS_node *origin, VFS_request *t);
226 
227  public slots:
228  void remove(bool andDelete);
229  virtual void remove(VFS_node *node=nullptr, QString *name=nullptr, QString user="server");
230 
231  //slot to receive request
232  virtual void subtreeRequest(VFS_request *t);
233 
234  //slot for received request to actually execute
235  virtual void executeRequest(VFS_request *t);
236 
237  //slot for satisfied request to post to _receiver
238  virtual void receiveResponse(VFS_request *t);
239 
240  void notifySubscribers(VFS_node *origin, VFS_request *t);
241  virtual void unsubscribeAll(VFS_node *n);
242  virtual void applyDiff(VFS_request *r);
243 
244  protected slots:
245 };
246 
247 #endif //VFS_NODE_H
248 
QMap< QString, VFS_subscriptionOrigin > VFS_subscriptionType
Definition: VFS_node.h:36
QPair< VFS_node *, QString > notifyException
Definition: VFS_node.h:42
QMap< QString, VFS_node * > VFS_children
Definition: VFS_node.h:38
quint16 postID
Definition: VFS_node.h:24
QMap< QString, VFS_node * >::const_iterator VFS_childrenConstIterator
Definition: VFS_node.h:40
QMap< VFS_node *, qint32 > VFS_subscriptionCounter
Definition: VFS_node.h:29
QMap< QString, VFS_node * >::iterator VFS_childrenIterator
Definition: VFS_node.h:39
QMap< QString, VFS_subscriptionCounter > VFS_subscriptionOrigin
Definition: VFS_node.h:35
VFS_node is the base class from which all other VFS_node classes derive.
Definition: VFS_node.h:143
virtual bool validChildName(QString name)
Check if a node name is valid.
Definition: VFS_node.cpp:2101
virtual VFS_request * createRequest(VFS_request::requestType type, QString path, QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false)
Create a new VFS_request with this object as _origin.
Definition: VFS_node.cpp:1913
VFS_children _children
This node's children.
Definition: VFS_node.h:179
virtual void issueResponse(VFS_request *t)
Once a request has been completed, issue a response.
Definition: VFS_node.cpp:1981
void addACLGroup(QJsonObject &acl, QString group, bool value)
Add a group to the acl object.
Definition: VFS_node.cpp:2148
static bool __removeNode(VFS_node *)
Remove a node from the global registry.
Definition: VFS_node.cpp:617
virtual void requestLock(VFS_request *r)
Request a lock on this node.
Definition: VFS_node.cpp:1065
QString uniqueChildName(QString name)
Generate a unique child name.
Definition: VFS_node.cpp:2054
virtual void unsubscribeAll(VFS_node *n)
Remove all references to a subscriber from this node.
Definition: VFS_node.cpp:1336
virtual void issueRequest(VFS_request *t)
A convenience function.
Definition: VFS_node.cpp:1933
static bool __isNode(VFS_node *)
Check to see if a node is in the global registry.
Definition: VFS_node.cpp:588
void addACLFeatureUser(QJsonObject &acl, QString feature, QString user, bool value)
Add a feature user to the acl object.
Definition: VFS_node.cpp:2227
void addACLFeature(QJsonObject &acl, QString feature, bool value, QString description="")
Add a feature to the acl object.
Definition: VFS_node.cpp:2183
VFS_node * findChildWithName(QString name)
Check if a child with a given name exists.
Definition: VFS_node.cpp:2078
virtual void releaseLock(VFS_request *r)
Release a lock on this node.
Definition: VFS_node.cpp:1081
virtual QByteArray icon()
Fetch the icon for a node.
Definition: VFS_node.cpp:655
void mounted()
Emitted when a node is mount()ed.
void unmounted(VFS_node *self)
Emitted when a node is unmount()ed.
void diff(VFS_node *origin, VFS_request *t)
Emit a diff, which will trigger notifySubscribers() for a mounted node.
QString className()
Return the class name of a node.
Definition: VFS_node.cpp:2039
VFS_subscriptionType _subscribers
This node's subscribers. These subscribers will receive diff notifications.
Definition: VFS_node.h:180
void remove(bool andDelete)
Remove a child node.
Definition: VFS_node.cpp:1629
void addACLFeatureGroup(QJsonObject &acl, QString feature, QString group, bool value)
Add a feature group to the acl object.
Definition: VFS_node.cpp:2205
void addACLUser(QJsonObject &acl, QString user, bool value)
Add a user to the acl object.
Definition: VFS_node.cpp:2165
virtual ~VFS_node()
VFS_node destructor.
Definition: VFS_node.cpp:531
void addACLDefault(QJsonObject &acl, bool value, QString description="")
Add a default value to the acl object.
Definition: VFS_node.cpp:2131
virtual void unsubscribePath(QString path)
Unsubscribe all references to a subpath.
Definition: VFS_node.cpp:1384
QMutex _lock
A recursive mutex that is local to this node.
Definition: VFS_node.h:178
void notifySubscribers(VFS_node *origin, VFS_request *t)
Propagate a diff to subscribers.
Definition: VFS_node.cpp:1497
static void __addNode(VFS_node *)
Add a node to the global registry.
Definition: VFS_node.cpp:603
static QSet< VFS_node * > __allNodes
The static global registry for all exiting nodes, used for thread safety checks.
Definition: VFS_node.h:215
virtual void applyDiff(VFS_request *r)
Apply a diff received via subscription.
Definition: VFS_node.cpp:1463
virtual void aclDefaults(VFS_request *r)
Return default values and features associated wth this node.
Definition: VFS_node.cpp:918
virtual QString reportDetails()
Additional details for a generated report.
Definition: VFS_node.cpp:900
static QMutex __allNodesMutex
The global registry mutex, which will lock when node creation or deletion is being performed.
Definition: VFS_node.h:216
void finished(bool andDelete=false)
Emitted if a thread fails to create its node, or a node is rm()'d, or any other reason a node has com...
virtual void receiveResponse(VFS_request *t)
Once a VFS_request has been completed, a response will be issued back to its _origin.
Definition: VFS_node.cpp:1870
The base class for all requests between nodes.
Definition: VFS_node.h:54
static const char * requestTypeStrings[]
A printable string for each request type.
Definition: VFS_node.h:127
requestType
Requests perform one of these actions.
Definition: VFS_node.h:63
@ diff
send a diff (7)
Definition: VFS_node.h:71
@ read
read full contents (4)
Definition: VFS_node.h:68
@ report
provide node report, for debugging (12)
Definition: VFS_node.h:76
@ requestlock
request a lock (13)
Definition: VFS_node.h:77
@ unsubscribe
unsubscribe from a path (10)
Definition: VFS_node.h:74
@ ls
list children of a node (1)
Definition: VFS_node.h:65
@ acl
return the ACL defaults for this node (11)
Definition: VFS_node.h:75
@ metadata
read metadata (6)
Definition: VFS_node.h:70
@ create
create a new file/path (2)
Definition: VFS_node.h:66
@ write
write full contents (5)
Definition: VFS_node.h:69
@ code
request code from a node (15)
Definition: VFS_node.h:79
@ codeDirectory
request a listing of code served by a node (16)
Definition: VFS_node.h:80
@ releaselock
release a lock (14)
Definition: VFS_node.h:78
@ subscribe
subscribe to a path (9)
Definition: VFS_node.h:73
@ submit
apply a diff (8)
Definition: VFS_node.h:72
@ rm
delete an existing file/path (3)
Definition: VFS_node.h:67
virtual ~VFS_request()
VFS_request destructor.
Definition: VFS_node.cpp:187
VFS_node * _responder
the receiver of the request
Definition: VFS_node.h:92
static QMutex _sampleLock
A mutex to protect thread safety of samples.
Definition: VFS_node.h:124
VFS_node * _origin
the origin of the request
Definition: VFS_node.h:89
virtual void setCallback(VFS_request *c)
Chain a callback onto this request.
Definition: VFS_node.cpp:286
QByteArray _rawData
the request payload, but raw data
Definition: VFS_node.h:103
bool hasCallback()
Check if this request has a callback set.
Definition: VFS_node.cpp:336
VFS_request(requestType type=VFS_request::none, VFS_node *origin=nullptr, QString path="", QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false)
VFS_request constructor.
Definition: VFS_node.cpp:74
requestType _requestType
the action this request is performing or requesting
Definition: VFS_node.h:87
static quint32 getSample()
Get the current sample count and clear the counter.
Definition: VFS_node.cpp:235
static quint32 _sampleCount
A count of the number of VFS_requests since the last sample was taken.
Definition: VFS_node.h:123
QString _initialPath
the target path when the request was made (relative to the responder)
Definition: VFS_node.h:93
QStringList _prefixPath
the prefix elements found while searching for the target
Definition: VFS_node.h:94
bool _dontDelete
A rarely used flag that will cause VFS_node::receiveResponse to not delete the node,...
Definition: VFS_node.h:112
QString _user
who initiated this request, mostly for logging
Definition: VFS_node.h:106
virtual void copyCallback(VFS_request *d)
Copy the data from a callback to this VFS_request.
Definition: VFS_node.cpp:355
virtual void fromJsonObject(QJsonObject json, bool includeInitialPath=false)
Deserialize a JSON string into a VFS_request.
Definition: VFS_node.cpp:466
virtual void execute()
after a request has completed, a request may have a special execute function.
Definition: VFS_node.cpp:255
VFS_session * _session
The session associated with this request. This is an optional value, and care should be taken to chec...
Definition: VFS_node.h:105
QString _reason
if something (probably bad) happened, this is the reason
Definition: VFS_node.h:108
friend class VFS_node
Definition: VFS_node.h:56
QString _path
the target path remnant... the remaining path element once the request has found its target
Definition: VFS_node.h:95
bool _isCallback
whether or not to issue a response (IE, another request is chained to this request,...
Definition: VFS_node.h:98
virtual VFS_request * createDiff(VFS_node *origin, QString originPath)
VFS_request::createDiff.
Definition: VFS_node.cpp:391
QString _originPath
the subpath of the origin node
Definition: VFS_node.h:90
QList< notifyException > _notifyExceptions
a list of nodes not to send responses to for this transaction. For instance if a node submits to a no...
Definition: VFS_node.h:110
bool _success
if the request was successfully completed
Definition: VFS_node.h:107
QJsonDocument _data
the request payload
Definition: VFS_node.h:102
virtual VFS_request * getCallback(VFS_node *receiver)
Create and chain a VFS_request for a receiver.
Definition: VFS_node.cpp:316
VFS_request * _callback
request to execute once this request completes
Definition: VFS_node.h:97
virtual QByteArray toJson(postID id=0, bool ignoreSuccess=false, bool includeInitialPath=false)
Serialize this request.
Definition: VFS_node.cpp:415
virtual void timerEvent(QTimerEvent *e=nullptr)
The callback for when a request times out.
Definition: VFS_node.cpp:220
static long _refcount
A reference counter for VFS_request instances, used for debugging to ensure all instances are properl...
Definition: VFS_node.h:122
QJsonObject _metadata
the request payload
Definition: VFS_node.h:101
The VFS_session object represents a single session.
Definition: VFS_session.h:14
A thread interface for creating multithreaded applications.
Definition: VFS_thread.h:32
virtual void subtreeRequest(VFS_request *t)
Subclass implementation of VFS_node::subtreeRequest()
Definition: VFS_thread.cpp:299
virtual void executeRequest(VFS_request *t)
Execute the VFS_request.
Definition: VFS_thread.cpp:319
virtual bool isContainer()
The container-ness of the thread node.
Definition: VFS_thread.cpp:231
virtual VFS_node * mount()
Mount the node, and mount the thread node if it exists.
Definition: VFS_thread.cpp:200
virtual VFS_node * unmount()
Unmount the node and the thread node if it exists.
Definition: VFS_thread.cpp:214
virtual VFS_node * append(QString name, VFS_node *node, bool containerCheck=true, QString user="unknown")
A dummy entry used to warn a developer of illegal use.
Definition: VFS_thread.cpp:178
virtual VFS_node * find(VFS_request *r)
Subclass implementation of VFS_node::find(), which is the path lookup mechanism.
Definition: VFS_thread.cpp:283