1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package org.synchronoss.cpo;
27
28 import java.io.Serializable;
29 import java.util.ArrayList;
30 import java.util.Comparator;
31 import java.util.List;
32
33
34
35
36
37
38
39
40 public class Node implements Serializable, Cloneable, Comparable<Node> {
41
42
43
44
45 private static final long serialVersionUID = 1L;
46 private static final int CHILD_NODE = 0;
47
48
49
50 private Node parent = null;
51
52
53
54 private Node firstChild = null;
55
56
57
58 private Node prevSibling = null;
59
60
61
62 private Node nextSibling = null;
63
64
65
66 private boolean allowChildren = true;
67
68
69
70
71
72 protected Node() {
73 }
74
75
76
77
78
79
80
81
82 protected Node(int nodeType) {
83 if (nodeType == CHILD_NODE) {
84 allowChildren = false;
85 }
86 }
87
88
89
90
91
92
93
94
95
96 static public Node createNode(int nodeType) {
97 return new Node(nodeType);
98 }
99
100
101
102
103 public void release() {
104
105 parent = null;
106 firstChild = null;
107 prevSibling = null;
108 nextSibling = null;
109 allowChildren = true;
110 }
111
112 protected void setAllowChildren(boolean ac) {
113 allowChildren = ac;
114 }
115
116 public boolean getAllowChildren() {
117 return this.allowChildren;
118 }
119
120
121
122
123
124
125
126
127
128 public void setParent(Node node) {
129 this.parent = node;
130 }
131
132
133
134
135
136
137
138 public void setPrevSibling(Node node) {
139 this.prevSibling = node;
140 node.nextSibling = this;
141 }
142
143
144
145
146
147
148
149 public void setNextSibling(Node node) {
150 this.nextSibling = node;
151 node.prevSibling = this;
152 }
153
154
155
156
157
158
159 public Node getParentNode() {
160 return (Node)this.parent;
161 }
162
163
164
165
166
167
168 public Node getPrevSibling() {
169 return this.prevSibling;
170 }
171
172
173
174
175
176
177 public Node getNextSibling() {
178 return this.nextSibling;
179 }
180
181
182
183
184
185
186 public boolean hasParent() {
187 return this.parent != null;
188 }
189
190
191
192
193
194
195 public boolean isLeaf() {
196 return getFirstChild() == null;
197 }
198
199
200
201
202
203
204
205 public void addChild(Node node) throws ChildNodeException {
206 if (node != null) {
207 if (!allowChildren) {
208 throw new ChildNodeException();
209 }
210
211 if (getFirstChild() == null) {
212 setFirstChild(node);
213 getFirstChild().setPrevSibling(firstChild);
214 getFirstChild().setNextSibling(firstChild);
215 } else {
216 Node lastChild = getFirstChild().getPrevSibling();
217 if (lastChild != null) {
218 lastChild.setNextSibling(node);
219 }
220 node.setNextSibling(getFirstChild());
221 }
222 node.setParent((Node)this);
223 }
224 }
225
226
227
228
229
230
231
232 public void addChildSort(Node node) throws ChildNodeException {
233 addChildSort(node, null);
234 }
235
236 public void addChildSort(Node node, Comparator<Node> c) throws ChildNodeException {
237 if (node != null) {
238 if (!allowChildren) {
239 throw new ChildNodeException();
240 }
241
242 if (isLeaf()) {
243 setFirstChild(node);
244 getFirstChild().setPrevSibling(node);
245 getFirstChild().setNextSibling(node);
246 } else {
247 boolean added = false;
248 Node currNode = getFirstChild();
249 do {
250 if (doCompare(node, currNode, c) < 0) {
251 node.setPrevSibling(currNode.getPrevSibling());
252 node.setNextSibling(currNode);
253 if (currNode == getFirstChild()) {
254 setFirstChild(node);
255 }
256 added = true;
257 break;
258 }
259
260 currNode = currNode.getNextSibling();
261 } while (currNode != getFirstChild());
262
263 if (!added) {
264 Node lastChild = getFirstChild().getPrevSibling();
265 if (lastChild != null) {
266 lastChild.setNextSibling(node);
267 }
268 node.setNextSibling(getFirstChild());
269 }
270 }
271 node.setParent((Node)this);
272 }
273 }
274
275 protected int doCompare(Node n1, Node n2, Comparator<Node> c) {
276 int rc;
277
278 if (c != null) {
279 rc = c.compare(n1, n2);
280 } else if (n1 == null && n1 == n2) {
281 rc = 0;
282 } else {
283 rc = n1.compareTo(n2);
284 }
285
286 return rc;
287 }
288
289
290
291
292
293
294 public void insertSiblingBefore(Node node) throws ChildNodeException {
295 if (node != null) {
296 node.setPrevSibling(getPrevSibling());
297 node.setNextSibling(this);
298 }
299 }
300
301
302
303
304
305
306 public void insertSiblingAfter(Node node) {
307 if (node != null) {
308 node.setNextSibling(getNextSibling());
309 node.setPrevSibling(this);
310 }
311 }
312
313
314
315
316
317
318 public void insertParentBefore(Node node) throws ChildNodeException {
319 if (node != null) {
320 if (hasParent()) {
321 getParentNode().addChild(node);
322 getParentNode().removeChild(this);
323 }
324 node.addChild(this);
325 }
326 }
327
328
329
330
331
332
333
334 public void insertParentAfter(Node node) throws ChildNodeException {
335 if (node != null) {
336
337 node.setFirstChild(getFirstChild());
338
339 setFirstChild(null);
340 addChild(node);
341 }
342 }
343
344
345
346
347
348
349 public boolean removeChild(Node node) throws ChildNodeException {
350 Node currNode = getFirstChild();
351 boolean rc = false;
352
353 if (!allowChildren) {
354 throw new ChildNodeException();
355 }
356
357 if (node != null && !isLeaf()) {
358
359 if (node == currNode && node == currNode.getNextSibling()) {
360 setFirstChild(null);
361 rc = true;
362 } else {
363
364 do {
365 if (currNode == node) {
366
367 if (node.getPrevSibling() != null) {
368 node.getPrevSibling().setNextSibling(node.getNextSibling());
369 }
370 if (node == getFirstChild()) {
371 setFirstChild(node.getNextSibling());
372 }
373
374 rc = true;
375
376
377
378
379 break;
380 }
381 currNode = currNode.getNextSibling();
382 } while (currNode != getFirstChild());
383 }
384 }
385
386 return rc;
387 }
388
389
390
391
392 public void removeChildNode() throws ChildNodeException {
393 Node parentLast;
394 Node thisLast;
395
396
397 if (!isLeaf() && hasParent()) {
398 parentLast = getParentNode().getFirstChild().getPrevSibling();
399 thisLast = getFirstChild().getPrevSibling();
400
401
402 parentLast.setNextSibling(getFirstChild());
403
404
405 thisLast.setNextSibling(getParentNode().getFirstChild());
406
407
408 getParentNode().removeChild(this);
409 }
410 }
411
412
413
414
415 public void removeAll() throws ChildNodeException {
416 if (hasParent()) {
417 getParentNode().removeChild(this);
418 }
419 }
420
421
422
423
424
425
426 public Node getFirstChild() {
427 return this.firstChild;
428 }
429
430
431
432
433
434
435 public void setFirstChild(Node node) throws ChildNodeException {
436 if (!allowChildren) {
437 throw new ChildNodeException();
438 }
439 this.firstChild = node;
440 }
441
442
443
444
445
446
447
448
449 public boolean acceptDFVisitor(NodeVisitor nv) throws Exception {
450 Node currNode;
451 boolean continueVisit = true;
452
453 if (nv != null) {
454 if (isLeaf()) {
455 continueVisit = nv.visit(this);
456 } else {
457 continueVisit = nv.visitBegin(this);
458 if (continueVisit) {
459 currNode = getFirstChild();
460 do {
461 continueVisit = currNode.acceptDFVisitor(nv);
462 if (continueVisit) {
463 currNode = currNode.getNextSibling();
464 if (currNode == getFirstChild()) {
465 break;
466 }
467 continueVisit = nv.visitMiddle(this);
468 }
469 } while (continueVisit);
470 if (continueVisit) {
471 continueVisit = nv.visitEnd(this);
472 }
473 }
474 }
475 }
476 return continueVisit;
477 }
478
479 public int getChildCount() {
480 Node currNode;
481 int count = 0;
482
483
484 if (!isLeaf()) {
485 currNode = getFirstChild();
486 do {
487 ++count;
488 currNode = currNode.getNextSibling();
489 } while (currNode != getFirstChild());
490 }
491
492 return count;
493 }
494
495 public List<Node> getChildList() {
496 Node currNode;
497 ArrayList<Node> al = new ArrayList<Node>();
498
499
500 if (!isLeaf()) {
501 currNode = getFirstChild();
502 do {
503 al.add(currNode);
504 currNode = currNode.getNextSibling();
505 } while (currNode != getFirstChild());
506 }
507
508 return al;
509 }
510
511 @Override
512 public Object clone() throws CloneNotSupportedException {
513 Node thisClone = (Node)super.clone();
514 Node currNode;
515
516 thisClone.release();
517 thisClone.setAllowChildren(getAllowChildren());
518
519
520 if (!isLeaf()) {
521 currNode = getFirstChild();
522 do {
523 try {
524 thisClone.addChild((Node)currNode.clone());
525 } catch (ChildNodeException e) {
526
527 }
528 currNode = currNode.getNextSibling();
529 } while (currNode != getFirstChild());
530 }
531
532 return thisClone;
533 }
534
535 @Override
536 public int compareTo(Node o) {
537
538 int rc;
539
540 if (this.hashCode() < o.hashCode()) {
541 rc = -1;
542 } else if (this.hashCode() > o.hashCode()) {
543 rc = 1;
544 } else {
545 rc = 0;
546 }
547
548 return rc;
549 }
550
551 public boolean equals(Node o) {
552 return this == o;
553 }
554 }