1
1
package org .dsa .iot .dslink .node ;
2
2
3
+ import java .lang .ref .WeakReference ;
4
+ import java .util .Collections ;
5
+ import java .util .HashMap ;
6
+ import java .util .HashSet ;
7
+ import java .util .Iterator ;
8
+ import java .util .List ;
9
+ import java .util .Map ;
10
+ import java .util .Set ;
11
+ import java .util .concurrent .ConcurrentHashMap ;
3
12
import org .dsa .iot .dslink .link .Linkable ;
4
13
import org .dsa .iot .dslink .node .NodeListener .ValueUpdate ;
5
14
import org .dsa .iot .dslink .node .actions .Action ;
9
18
import org .dsa .iot .dslink .serializer .SerializationManager ;
10
19
import org .dsa .iot .dslink .util .StringUtils ;
11
20
12
- import java .lang .ref .WeakReference ;
13
- import java .util .*;
14
- import java .util .concurrent .ConcurrentHashMap ;
15
-
16
21
/**
17
22
* Contains information about a node and its data.
18
23
*
19
24
* @author Samuel Grenier
20
25
*/
21
26
public class Node {
22
27
23
- private static final char [] BANNED_CHARS = new char [] {
24
- '%' , '.' , '/' , '\\' , '?' , '*' , ':' , '|' , '<' , '>' , '$' , '@' , ','
28
+ private static final char [] BANNED_CHARS = new char []{
29
+ '%' , '.' , '/' , '\\' , '?' , '*' , ':' , '|' , '<' , '>' , '$' , '@' , ','
25
30
};
26
31
27
32
private final Object roConfigLock = new Object ();
@@ -58,15 +63,16 @@ public class Node {
58
63
private Set <String > interfaces ;
59
64
private Action action ;
60
65
private char [] pass ;
61
-
66
+ boolean building = false ;
67
+
62
68
private boolean shouldPostCachedValue = true ;
63
69
64
70
/**
65
71
* Constructs a node object.
66
72
*
67
73
* @param name Name of the node
68
74
* @param parent Parent of this node
69
- * @param link Linkable class the node is handled on
75
+ * @param link Linkable class the node is handled on
70
76
*/
71
77
public Node (String name , Node parent , Linkable link ) {
72
78
this (name , parent , link , true );
@@ -100,7 +106,7 @@ public Node(String name, Node parent, Linkable link, boolean shouldEncodeName) {
100
106
101
107
/**
102
108
* @return Parent of this node, can be null if the parent was garbage
103
- * collected or there is no parent.
109
+ * collected or there is no parent.
104
110
*/
105
111
public Node getParent () {
106
112
return parent .get ();
@@ -244,15 +250,15 @@ public void setValue(Value value, boolean externalSource) {
244
250
}
245
251
246
252
/**
247
- * @param value Value to set.
253
+ * @param value Value to set.
248
254
* @param externalSource Whether the value was set from an external source
249
255
* like an action that got invoked.
250
- * @param publish Whether to allow a publish to the network.
256
+ * @param publish Whether to allow a publish to the network.
251
257
* @return Whether a value was actually set.
252
258
*/
253
259
protected boolean setValue (Value value ,
254
- boolean externalSource ,
255
- boolean publish ) {
260
+ boolean externalSource ,
261
+ boolean publish ) {
256
262
ValueType type = valueType ;
257
263
if (type == null ) {
258
264
if (this .value != null ) {
@@ -372,24 +378,24 @@ public void setWritable(Writable writable) {
372
378
public Writable getWritable () {
373
379
return writable ;
374
380
}
375
-
381
+
376
382
/**
377
- * @return Whether the node's value should automatically
378
- * be posted in response to a subscription request.
383
+ * @return Whether the node's value should automatically
384
+ * be posted in response to a subscription request.
379
385
*/
380
386
public boolean shouldPostCachedValue () {
381
- return shouldPostCachedValue ;
387
+ return shouldPostCachedValue ;
382
388
}
383
389
384
390
/**
385
- * @param should Whether the node's value should
386
- * automatically be posted in response to a
391
+ * @param should Whether the node's value should
392
+ * automatically be posted in response to a
387
393
* subscription request. Defaults to true.
388
394
*/
389
395
public void setShouldPostCachedValue (boolean should ) {
390
- shouldPostCachedValue = should ;
396
+ shouldPostCachedValue = should ;
391
397
}
392
-
398
+
393
399
394
400
/**
395
401
* @return Children of the node, can be null
@@ -399,6 +405,13 @@ public Map<String, Node> getChildren() {
399
405
return children != null ? Collections .unmodifiableMap (children ) : null ;
400
406
}
401
407
408
+ public Iterator <Node > childIterator () {
409
+ if (children == null ) {
410
+ return Collections .emptyIterator ();
411
+ }
412
+ return Collections .unmodifiableCollection (children .values ()).iterator ();
413
+ }
414
+
402
415
/**
403
416
* Clears the children in the node.
404
417
*/
@@ -455,11 +468,12 @@ public NodeBuilder createChild(String name) {
455
468
public NodeBuilder createChild (String name , boolean encodeName ) {
456
469
return createChild (name , profile , encodeName );
457
470
}
471
+
458
472
/**
459
473
* Creates a node builder to allow setting up the node data before
460
474
* any list subscriptions can be notified.
461
475
*
462
- * @param name Name of the child.
476
+ * @param name Name of the child.
463
477
* @param profile Profile to set on the child
464
478
* @return builder
465
479
* @see NodeBuilder#build
@@ -498,27 +512,33 @@ public Node addChild(Node node) {
498
512
return children .get (name );
499
513
}
500
514
501
- SubscriptionManager manager = null ;
502
- if (link != null ) {
503
- manager = link .getSubscriptionManager ();
504
- }
505
-
506
515
if (node .getProfile () == null ) {
507
516
node .setProfile (profile );
508
517
}
509
518
children .put (name , node );
510
- if (manager != null ) {
511
- manager .postChildUpdate (node , false );
512
- }
519
+ childAdded (node );
513
520
if (node .isSerializable ()) {
514
521
markChanged ();
515
522
}
516
523
return node ;
517
524
}
518
525
}
519
526
527
+ void childAdded (Node node ) {
528
+ if (!building ) {
529
+ SubscriptionManager manager = null ;
530
+ if (link != null ) {
531
+ manager = link .getSubscriptionManager ();
532
+ }
533
+ if (manager != null ) {
534
+ manager .postChildUpdate (node , false );
535
+ }
536
+ }
537
+ }
538
+
520
539
/**
521
540
* Add multiple children at once.
541
+ *
522
542
* @param nodes Nodes to add.
523
543
*/
524
544
public void addChildren (List <Node > nodes ) {
@@ -631,8 +651,6 @@ public Node removeChild(String name, boolean encodeName) {
631
651
632
652
if (manager != null ) {
633
653
manager .postChildUpdate (child , true );
634
- manager .removeValueSub (child );
635
- manager .removePathSub (child );
636
654
}
637
655
if (isSerializable ()) {
638
656
markChanged ();
@@ -836,7 +854,7 @@ public Value getRoConfig(String name) {
836
854
/**
837
855
* Sets a read-only configuration.
838
856
*
839
- * @param name Name of the configuration.
857
+ * @param name Name of the configuration.
840
858
* @param value Value to set.
841
859
* @return The previous value, if any.
842
860
*/
0 commit comments