1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.scxml.semantics;
18
19 import java.io.Serializable;
20 import java.util.Comparator;
21
22 import org.apache.commons.scxml.SCXMLHelper;
23 import org.apache.commons.scxml.model.TransitionTarget;
24
25
26 /***
27 * A comparator for TransitionTarget instances.
28 *
29 */
30 final class TransitionTargetComparator implements Comparator, Serializable {
31
32 /***
33 * Serial version UID.
34 */
35 private static final long serialVersionUID = 1L;
36
37 /***
38 * Constructor.
39 */
40 TransitionTargetComparator() {
41 super();
42 }
43
44 /***
45 * Compares two instances of TransitionTarget in terms of the
46 * SCXML tree hierarchy.
47 * <p>Important Remarks:</p> does not fullfill the Comparator contract,
48 * since it returns 0 if o1 == o2 and also if they are not related to each
49 * other and at the same time the chain-to-parent length for o1 is the
50 * same length as for o2 (that is, they are equally deeply nested)
51 *
52 * @param o1 The first TransitionTarget object
53 * @param o2 The second TransitionTarget object
54 * @return int The comparation result
55 * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
56 * @see TransitionTarget
57 */
58 public int compare(final Object o1, final Object o2) {
59 TransitionTarget tt1 = (TransitionTarget) o1;
60 TransitionTarget tt2 = (TransitionTarget) o2;
61 if (tt1 == tt2) {
62 return 0;
63 } else if (SCXMLHelper.isDescendant(tt1, tt2)) {
64 return -1;
65 } else if (SCXMLHelper.isDescendant(tt2, tt1)) {
66 return 1;
67 } else {
68
69 int tc1 = countChainLength(tt1);
70 int tc2 = countChainLength(tt2);
71
72 return tc2 - tc1;
73 }
74 }
75
76 /***
77 * The "depth" at which this TransitionTarget exists in the
78 * SCXML object model.
79 *
80 * @param tt The TransitionTarget
81 * @return int The "depth"
82 */
83 private int countChainLength(final TransitionTarget tt) {
84 int count = 0;
85 TransitionTarget parent = tt.getParent();
86 while (parent != null) {
87 count++;
88 parent = parent.getParent();
89 }
90 return count;
91 }
92 }
93