Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DataSource.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
4using System.Windows.Input;
5using System.Windows.Media;
6using System.Xml;
9
11{
15 public class DataSource : TreeNode
16 {
17 private readonly Dictionary<string, Node> nodes = new Dictionary<string, Node>();
18 private DateTime timer = DateTime.MinValue;
19 private readonly string key;
20 private readonly string header;
21 private readonly bool hasChildSources;
22 private bool unsubscribed = false;
23
24 public DataSource(TreeNode Parent, string Key, string Header, bool HasChildSources)
25 : base(Parent)
26 {
27 this.key = Key;
28 this.header = Header;
29 this.hasChildSources = HasChildSources;
30
31 this.children = new SortedDictionary<string, TreeNode>()
32 {
33 { string.Empty, new Loading(this) }
34 };
35 }
36
37 public override void Dispose()
38 {
39 if (this.timer > DateTime.MinValue)
40 {
41 MainWindow.Scheduler?.Remove(this.timer);
42 this.timer = DateTime.MinValue;
43 }
44
45 base.Dispose();
46 }
47
48 public override string Key => this.key;
49 public override string Header => this.header;
50 public override string ToolTip => "Data source";
51 public override string TypeName => "Data Source";
52 public override bool CanAddChildren => false;
53 public override bool CanEdit => false;
54 public override bool CanDelete => false;
55 public override bool CanRecycle => false;
56
57 public override ImageSource ImageResource
58 {
59 get
60 {
61 if (this.IsExpanded)
62 return XmppAccountNode.folderYellowOpen;
63 else
64 return XmppAccountNode.folderYellowClosed;
65 }
66 }
67
68 public override void Write(XmlWriter Output)
69 {
70 // Don't output.
71 }
72
73 public XmppConcentrator Concentrator
74 {
75 get
76 {
77 TreeNode Loop = this.Parent;
78
79 while (!(Loop is null))
80 {
81 if (Loop is XmppConcentrator Concentrator)
82 return Concentrator;
83
84 Loop = Loop.Parent;
85 }
86
87 return null;
88 }
89 }
90
91 private bool loadingChildren = false;
92
93 protected override void LoadChildren()
94 {
95 if (!this.loadingChildren && !this.IsLoaded)
96 {
97 string FullJid = this.Concentrator?.FullJid;
98
99 if (!string.IsNullOrEmpty(FullJid))
100 {
101 Mouse.OverrideCursor = Cursors.Wait;
102
103 if (this.hasChildSources)
104 {
105 this.loadingChildren = true;
106 this.Concentrator.XmppAccountNode.ConcentratorClient.GetChildDataSources(FullJid, this.key, (Sender, e) =>
107 {
108 this.loadingChildren = false;
109 MainWindow.MouseDefault();
110
111 if (e.Ok)
112 {
113 SortedDictionary<string, TreeNode> Children = new SortedDictionary<string, TreeNode>();
114
115 foreach (DataSourceReference Ref in e.DataSources)
116 {
117 DataSource DataSource = new DataSource(this, Ref.SourceID, Ref.SourceID, Ref.HasChildren);
118 Children[Ref.SourceID] = DataSource;
119
120 DataSource.SubscribeToEvents();
121 }
122
123 this.children = Children;
124
125 this.OnUpdated();
126 this.Concentrator?.NodesAdded(Children.Values, this);
127 }
128
129 return Task.CompletedTask;
130 }, null);
131 }
132 else
133 {
134 this.loadingChildren = true;
135 this.Concentrator.XmppAccountNode.ConcentratorClient.GetRootNodes(FullJid, this.key, true, true,
136 "en", string.Empty, string.Empty, string.Empty, (Sender, e) =>
137 {
138 this.loadingChildren = false;
139 MainWindow.MouseDefault();
140
141 if (e.Ok)
142 {
143 SortedDictionary<string, TreeNode> Children = new SortedDictionary<string, TreeNode>();
144
145 foreach (NodeInformation Ref in e.NodesInformation)
146 Children[Ref.NodeId] = new Node(this, Ref);
147
148 this.children = Children;
149
150 this.OnUpdated();
151 this.NodesAdded(Children.Values, this);
152 }
153
154 return Task.CompletedTask;
155 }, null);
156 }
157 }
158 }
159
160 base.LoadChildren();
161 }
162
163 public void NodesAdded(IEnumerable<TreeNode> Nodes, TreeNode Parent)
164 {
165 lock (this.nodes)
166 {
167 foreach (TreeNode Node in Nodes)
168 {
169 if (Node is Node Node2)
170 {
171 string Key = Node2.Partition + " " + Node2.NodeId;
172 this.nodes[Key] = Node2;
173 }
174 }
175 }
176
177 this.Concentrator?.NodesAdded(Nodes, Parent);
178 }
179
180 public void NodesRemoved(IEnumerable<TreeNode> Nodes, TreeNode Parent)
181 {
182 lock (this.nodes)
183 {
184 foreach (TreeNode Node in Nodes)
185 {
186 if (Node is Node Node2)
187 {
188 string Key = Node2.Partition + " " + Node2.NodeId;
189 this.nodes.Remove(Key);
190 }
191 }
192 }
193
194 this.Concentrator?.NodesRemoved(Nodes, Parent);
195 }
196
197 public void SubscribeToEvents()
198 {
199 this.SubscribeToEvents(true);
200 }
201
202 private void SubscribeToEvents(object State)
203 {
204 if (this.unsubscribed)
205 return;
206
207 if (!(State is bool))
208 return;
209
210 XmppConcentrator Concentrator = this.Concentrator;
211 XmppAccountNode XmppAccountNode = Concentrator?.XmppAccountNode;
213
214 if (Concentrator is null || XmppAccountNode is null || ConcentratorClient is null)
215 return;
216
217 string FullJid = Concentrator.FullJid;
218
219 if (this.timer > DateTime.MinValue)
220 {
221 MainWindow.Scheduler?.Remove(this.timer);
222 this.timer = DateTime.MinValue;
223 }
224
225 ConcentratorClient.Subscribe(FullJid, this.key, 600, SourceEventType.All, true, true, "en",
226 string.Empty, string.Empty, string.Empty, (Sender, e) =>
227 {
228 if (e.Ok)
229 this.timer = MainWindow.Scheduler.Add(DateTime.Now.AddMinutes(5), this.SubscribeToEvents, false);
230 else
231 this.timer = MainWindow.Scheduler.Add(DateTime.Now.AddMinutes(1), this.SubscribeToEvents, false);
232
233 return Task.CompletedTask;
234 }, null);
235 }
236
237 public void UnsubscribeFromEvents()
238 {
239 this.unsubscribed = true;
240
241 if (this.timer > DateTime.MinValue)
242 {
243 MainWindow.Scheduler?.Remove(this.timer);
244 this.timer = DateTime.MinValue;
245 }
246
247 XmppConcentrator Concentrator = this.Concentrator;
248 if (Concentrator is null)
249 return;
250
251 XmppAccountNode XmppAccountNode = Concentrator.XmppAccountNode;
252 if (XmppAccountNode is null)
253 return;
254
255 string FullJid = Concentrator.FullJid;
257 if (ConcentratorClient is null)
258 return;
259
260 XmppAccountNode.ConcentratorClient.Unsubscribe(FullJid, this.key, SourceEventType.All, "en",
261 string.Empty, string.Empty, string.Empty, null, null);
262 }
263
264 protected override void UnloadChildren()
265 {
266 base.UnloadChildren();
267
268 if (this.IsLoaded)
269 {
270 if (!(this.children is null))
271 this.NodesRemoved(this.children.Values, this);
272
273 this.children = new SortedDictionary<string, TreeNode>()
274 {
275 { string.Empty, new Loading(this) }
276 };
277
278 this.OnUpdated();
279 }
280 }
281
282 internal Task ConcentratorClient_OnEvent(object Sender, SourceEventMessageEventArgs EventMessage)
283 {
284 SourceEvent Event = EventMessage.Event;
285 string Key, ParentKey;
286 Node Node;
287
288 switch (Event.EventType)
289 {
290 case SourceEventType.NodeAdded:
291 if (Event is NodeAdded NodeAdded)
292 {
293 Key = NodeAdded.Partition + " " + NodeAdded.NodeId;
294 ParentKey = NodeAdded.ParentPartition + " " + NodeAdded.ParentId;
295 Node Parent;
296
297 lock (this.nodes)
298 {
299 if (this.nodes.ContainsKey(Key))
300 return Task.CompletedTask; // Already added
301
302 if (!this.nodes.TryGetValue(ParentKey, out Parent))
303 return Task.CompletedTask; // Parent not loaded.
304
310
311 this.nodes[Key] = Node;
312 }
313
314 Parent.Add(Node);
315 }
316 break;
317
318 case SourceEventType.NodeUpdated:
319 if (Event is NodeUpdated NodeUpdated)
320 {
321 Key = NodeUpdated.Partition + " " + NodeUpdated.NodeId;
322
323 lock (this.nodes)
324 {
325 if (!this.nodes.TryGetValue(Key, out Node))
326 {
327 if (string.IsNullOrEmpty(NodeUpdated.OldId))
328 return Task.CompletedTask; // Parent not loaded.
329
330 string OldKey = NodeUpdated.Partition + " " + NodeUpdated.OldId;
331 if (!this.nodes.TryGetValue(OldKey, out Node))
332 return Task.CompletedTask; // Parent not loaded.
333
334 this.nodes.Remove(OldKey);
335 this.nodes[Key] = Node;
336 }
337 }
338
340 Node.NodeInformation.NodeType, Node.NodeInformation.DisplayName, NodeUpdated.State, NodeUpdated.LocalId, NodeUpdated.LogId,
342 NodeUpdated.HasCommands, Node.NodeInformation.Sniffable, NodeUpdated.ParentId, NodeUpdated.ParentPartition,
344
345 Node.OnUpdated();
346 }
347 break;
348
349 case SourceEventType.NodeRemoved:
350 if (Event is NodeRemoved NodeRemoved)
351 {
352 Key = NodeRemoved.Partition + " " + NodeRemoved.NodeId;
353
354 lock (this.nodes)
355 {
356 if (!this.nodes.TryGetValue(Key, out Node))
357 return Task.CompletedTask; // Parent not loaded.
358
359 this.nodes.Remove(Key);
360 }
361
362 Node.Parent.RemoveChild(Node);
363 this.NodesRemoved(new TreeNode[] { Node }, Node.Parent);
364 }
365 break;
366
367 case SourceEventType.NodeStatusChanged:
369 {
370 Key = NodeStatusChanged.Partition + " " + NodeStatusChanged.NodeId;
371
372 lock (this.nodes)
373 {
374 if (!this.nodes.TryGetValue(Key, out Node))
375 return Task.CompletedTask; // Parent not loaded.
376 }
377
379 Node.NodeInformation.NodeType, Node.NodeInformation.DisplayName, NodeStatusChanged.State, NodeStatusChanged.LocalId, NodeStatusChanged.LogId,
380 Node.NodeInformation.HasChildren, Node.NodeInformation.ChildrenOrdered, Node.NodeInformation.IsReadable, Node.NodeInformation.IsControllable,
381 Node.NodeInformation.HasCommands, Node.NodeInformation.Sniffable, Node.NodeInformation.ParentId, Node.NodeInformation.ParentPartition,
382 Node.NodeInformation.LastChanged, Node.NodeInformation.ParameterList, null);
383
384 Node.OnUpdated();
385 }
386 break;
387
388 case SourceEventType.NodeMovedUp:
389 if (Event is NodeMovedUp NodeMovedUp)
390 {
391 Key = NodeMovedUp.Partition + " " + NodeMovedUp.NodeId;
392
393 lock (this.nodes)
394 {
395 if (!this.nodes.TryGetValue(Key, out Node))
396 return Task.CompletedTask; // Parent not loaded.
397 }
398
399 // TODO: Node.Parent?.MoveUp(Node);
400 }
401 break;
402
403 case SourceEventType.NodeMovedDown:
404 if (Event is NodeMovedDown NodeMovedDown)
405 {
406 Key = NodeMovedDown.Partition + " " + NodeMovedDown.NodeId;
407
408 lock (this.nodes)
409 {
410 if (!this.nodes.TryGetValue(Key, out Node))
411 return Task.CompletedTask; // Parent not loaded.
412 }
413
414 // TODO: Node.Parent?.MoveDown(Node);
415 }
416 break;
417 }
418
419 return Task.CompletedTask;
420 }
421
422 }
423}
Interaction logic for xaml
Represents a data source in a concentrator.
Definition: DataSource.cs:16
override void UnloadChildren()
Method is called to notify children can be unloaded.
Definition: DataSource.cs:264
override void Write(XmlWriter Output)
Saves the object to a file.
Definition: DataSource.cs:68
override void LoadChildren()
Method is called to make sure children are loaded.
Definition: DataSource.cs:93
override void Dispose()
Disposes of the node and its resources.
Definition: DataSource.cs:37
Represents a node in a concentrator.
Definition: Node.cs:33
override void Add()
Is called when the user wants to add a node to the current node.
Definition: Node.cs:422
Represents a data source in a concentrator.
Definition: Loading.cs:11
Abstract base class for tree nodes in the connection view.
Definition: TreeNode.cs:24
TreeNode[] Children
Children of the node. If null, children are not loaded.
Definition: TreeNode.cs:72
TreeNode Parent
Parent node. May be null if a root node.
Definition: TreeNode.cs:107
virtual void OnUpdated()
Raises the Updated event.
Definition: TreeNode.cs:224
bool IsExpanded
If the node is expanded.
Definition: TreeNode.cs:233
Class representing a normal XMPP account.
Implements an XMPP concentrator client interface.
Task Subscribe(string To, string SourceID, int TimeoutSeconds, SourceEventType EventTypes, bool Parameters, bool Messages, string Language, string ServiceToken, string DeviceToken, string UserToken, EventHandlerAsync< IqResultEventArgs > Callback, object State)
Subscribes to data source events.
ConcentratorClient(XmppClient Client)
Implements an XMPP concentrator client interface.
Task GetChildDataSources(string To, string SourceID, EventHandlerAsync< DataSourcesEventArgs > Callback, object State)
Gets all child data sources for a data source on the server.
Task GetRootNodes(string To, string SourceID, bool Parameters, bool Messages, string Language, string ServiceToken, string DeviceToken, string UserToken, EventHandlerAsync< NodesInformationEventArgs > Callback, object State)
Gets information about all root nodes in a data source.
string DisplayName
Display name.
Definition: NodeAdded.cs:123
string NodeType
Type of node, at time of event.
Definition: NodeAdded.cs:133
bool Sniffable
If node was sniffable, at time of event.
Definition: NodeAdded.cs:143
string NodeId
Node identity.
Definition: NodeEvent.cs:29
string LogId
Log identity, if different from NodeId.
Definition: NodeEvent.cs:51
string Partition
Optional partition.
Definition: NodeEvent.cs:40
string LocalId
Local identity, if different from NodeId.
Definition: NodeEvent.cs:62
string ParentPartition
Partition of parent of node, at time of event.
string ParentId
Parent identity of node, at time of event.
bool HasChildren
If node had children, at time of event.
bool ChildrenOrdered
If node children was ordered, at time of event.
bool IsControllable
If node was controllable, at time of event.
Parameter[] Parameters
Displayable parameters.
DateTime Updated
When node was last updated, at time of event.
bool HasCommands
If node had commands, at time of event.
bool IsReadable
If node was readable, at time of event.
NodeState State
State of node, at time of event.
string OldId
If renamed, this property contains the node identity before the node was renamed.
Definition: NodeUpdated.cs:110
Abstract base class for all data source events.
Definition: SourceEvent.cs:13
abstract SourceEventType EventType
Type of data source event.
Definition: SourceEvent.cs:59
string SourceId
Data source identity.
Definition: SourceEvent.cs:40
SourceEventType
Data Source event types