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
27
28
29 package name.angoca.zemucan.core.graph.model;
30
31 import java.util.ArrayList;
32 import java.util.Iterator;
33 import java.util.List;
34
35 import name.angoca.zemucan.core.graph.api.NullGraphNodeException;
36
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public abstract class AbstractGraphNode implements
57 Comparable<AbstractGraphNode> {
58
59
60
61 private static final Logger LOGGER = LoggerFactory
62 .getLogger(AbstractGraphNode.class);
63
64
65
66 private final transient List<AbstractGraphNode> children;
67
68
69
70
71
72 private boolean comeFromStartingNode;
73
74
75
76
77
78 private boolean goToEndingNode;
79
80
81
82
83 private final String id;
84
85
86
87
88 private String graphName;
89
90
91
92
93
94 private final transient List<AbstractGraphNode> parents;
95
96
97
98
99
100
101
102
103
104
105
106
107 AbstractGraphNode(final String
108 assert tokenId != null;
109 assert graph != null;
110
111 this.id = tokenId;
112 this.graphName = graph.getName();
113 this.children = new ArrayList<AbstractGraphNode>();
114
115
116 this.parents = new ArrayList<AbstractGraphNode>();
117 this.comeFromStartingNode = false;
118 this.goToEndingNode = false;
119 }
120
121
122
123
124
125
126
127
128
129
130 void addChild(final AbstractGraphNode
131 throws AbstractGraphException {
132 if (node == null) {
133 throw new NullGraphNodeException();
134 } else if (node instanceof StartingNode) {
135 throw new ReferencingStartingNodeException(this.getId());
136 }
137 if (!this.children.contains(node)) {
138 this.children.add(node);
139 } else {
140 AbstractGraphNode.LOGGER.debug("Already existing child: {} in {}",
141 node.id, this.id);
142 }
143 }
144
145
146
147
148
149
150
151
152
153
154 void addParent(final AbstractGraphNode
155 throws AbstractGraphException {
156 if (node == null) {
157 throw new NullGraphNodeException();
158 } else if (node instanceof EndingNode) {
159 throw new ReferencingEndingNodeException(this.getId());
160 }
161 if (!this.parents.contains(node)) {
162 this.parents.add(node);
163 } else {
164 AbstractGraphNode.LOGGER.debug("Already existing parent: {} in {}",
165 node.id, this.id);
166 }
167 }
168
169
170
171
172
173
174
175
176 private boolean compareChildren(
177 final List<AbstractGraphNode>
178 boolean equals = true;
179 final int size = otherChildren.size();
180 for (int i = 0; (i < size) && equals; i += 1) {
181 if (!this.containsChildren(otherChildren.get(i))) {
182 equals = false;
183 }
184 }
185 return equals;
186 }
187
188
189
190
191
192
193
194
195 private boolean compareParents(
196 final List<AbstractGraphNode>
197 boolean equals = true;
198 int size;
199 size = otherParents.size();
200 for (int i = 0; (i < size) && equals; i += 1) {
201 if (!this.containsParent(otherParents.get(i))) {
202 equals = false;
203 }
204 }
205 return equals;
206 }
207
208 @Override
209 public int compareTo(final AbstractGraphNode
210 final int ret = this.id.compareTo(other.id);
211
212
213
214
215 return ret;
216 }
217
218
219
220
221
222
223
224
225
226 private boolean containsChildren(final AbstractGraphNode
227 assert graphNode != null;
228
229 final int size = this.children.size();
230 boolean ret = false;
231 for (int i = 0; (i < size) && !ret; i += 1) {
232 if (graphNode.getId().equals(this.children.get(i).getId())) {
233 ret = true;
234 }
235 }
236 return ret;
237 }
238
239
240
241
242
243
244
245
246
247 private boolean containsParent(final AbstractGraphNode
248 assert graphNode != null;
249
250 final int size = this.parents.size();
251 boolean ret = false;
252 for (int i = 0; (i < size) && !ret; i += 1) {
253 if (graphNode.getId().equals(this.parents.get(i).getId())) {
254 ret = true;
255 }
256 }
257 return ret;
258 }
259
260
261
262
263
264 @Override
265 public boolean equals(final Object
266 boolean equals = false;
267 if (object instanceof AbstractGraphNode) {
268 final AbstractGraphNode token = (AbstractGraphNode) object;
269 final List<AbstractGraphNode> otherChildren = token.children;
270 final List<AbstractGraphNode> otherParents = token.parents;
271 if (token.id.equals(this.id)
272 && (otherChildren.size() == this.children.size())
273 && (otherParents.size() == this.parents.size())) {
274 equals = this.compareChildren(otherChildren);
275 if (equals) {
276 equals = this.compareParents(otherParents);
277 }
278 }
279 }
280 return equals;
281 }
282
283
284
285
286
287
288
289 final List<AbstractGraphNode>
290 assert this.children != null;
291 boolean assertsEnabled = false;
292
293 assert assertsEnabled = true;
294 if (assertsEnabled) {
295 for (final AbstractGraphNode token : this.children) {
296 assert token != null;
297 }
298 }
299 return this.children;
300 }
301
302
303
304
305
306
307 final String
308 assert this.id != null;
309 return this.graphName + ":" + this.id;
310 }
311
312
313
314
315
316
317
318 final List<AbstractGraphNode>
319 assert this.parents != null;
320 boolean assertsEnabled = false;
321
322 assert assertsEnabled = true;
323 if (assertsEnabled) {
324 for (final AbstractGraphNode token : this.parents) {
325 assert token != null;
326 }
327 }
328 return this.parents;
329 }
330
331
332
333
334
335
336
337
338
339 public final Iterator<AbstractGraphNode>
340 final List<AbstractGraphNode> copy = new ArrayList<AbstractGraphNode>();
341 final List<AbstractGraphNode> currentChildren = this.getChildren();
342 for (final AbstractGraphNode node : currentChildren) {
343
344
345
346
347 copy.add(node);
348 }
349
350 final Iterator<AbstractGraphNode> iter = new Iterator<AbstractGraphNode>() {
351
352
353
354
355 private int indexNonReserved = 0;
356
357
358
359 private int indexReserved = 0;
360
361
362
363 private AbstractGraphNode next = null;
364
365
366
367
368
369 @Override
370 public boolean hasNext() {
371 this.next = null;
372 final int size = AbstractGraphNode.this.getChildren().size();
373 boolean found = false;
374
375 if (this.indexReserved < size) {
376 while ((this.indexReserved < size) && !found) {
377 final AbstractGraphNode node = AbstractGraphNode.this
378 .getChildren().get(this.indexReserved);
379 if (node instanceof GraphNode) {
380 this.next = node;
381 found = true;
382 }
383 this.indexReserved += 1;
384 }
385 }
386 if ((this.indexNonReserved < size) && !found) {
387
388 while ((this.indexNonReserved < size) && !found) {
389 final AbstractGraphNode node = AbstractGraphNode.this
390 .getChildren().get(this.indexNonReserved);
391 if (node instanceof NonReservedGraphNode) {
392 this.next = node;
393 found = true;
394 }
395 this.indexNonReserved += 1;
396 }
397 }
398
399 return this.next != null;
400 }
401
402
403
404
405
406 @Override
407 public AbstractGraphNode
408 assert this.next != null;
409 return this.next;
410 }
411
412
413
414
415
416 @Override
417 public void remove() {
418
419 }
420 };
421 return iter;
422 }
423
424
425
426
427
428 @Override
429 public int hashCode() {
430 final int value = this.id.hashCode() + this.graphName.hashCode()
431 - this.children.size();
432 return value;
433 }
434
435
436
437
438
439
440 boolean isComeFromStartingNode() {
441 return this.comeFromStartingNode;
442 }
443
444
445
446
447
448
449 boolean isGoToEndingNode() {
450 return this.goToEndingNode;
451 }
452
453
454
455
456
457
458
459
460
461 void removeChild(final AbstractGraphNode
462 throws NullGraphNodeException {
463 if (node == null) {
464 throw new NullGraphNodeException();
465 }
466 this.children.remove(node);
467 }
468
469
470
471
472
473
474
475
476
477 void removeParent(final AbstractGraphNode
478 throws NullGraphNodeException {
479 if (node == null) {
480 throw new NullGraphNodeException();
481 }
482 this.parents.remove(node);
483 }
484
485
486
487
488
489
490
491
492
493 public abstract boolean represent(final String
494
495
496
497
498
499
500
501
502 void setComeFromStartingNode(final boolean comes) {
503 this.comeFromStartingNode = comes;
504 }
505
506
507
508
509
510
511
512 void setGoToEndingNode(final boolean goes) {
513 this.goToEndingNode = goes;
514 }
515
516
517
518
519
520
521
522 @Override
523 public String
524 String ret = '{' + this.id + '\n' + this.parents.size();
525
526 if (this.parents.size() > 0) {
527 ret += "\t<";
528 for (final AbstractGraphNode node : this.parents) {
529 ret += node.id + "--";
530 }
531 ret = ret.substring(0, ret.length() - 2);
532 ret += '>';
533 }
534
535 ret += "\n" + this.children.size();
536 if (this.children.size() > 0) {
537 ret += "\t[";
538 for (final AbstractGraphNode node : this.children) {
539 ret += node.id + "--";
540 }
541 ret = ret.substring(0, ret.length() - 2);
542 ret += ']';
543 }
544 ret += "\n" + this.comeFromStartingNode + '|' + this.goToEndingNode
545 + '}';
546 assert ret != null;
547 return ret;
548 }
549
550
551
552
553
554
555
556 void setGraphName(final String
557 this.graphName = graphName;
558 }
559
560
561
562
563
564
565 String
566 return this.graphName;
567 }
568
569
570
571
572
573
574
575
576
577 public void addGraphName(final String
578 this.graphName = newGraphName + ':' + this.graphName;
579 }
580 }