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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 package org.jaxen.expr;
48
49 import java.util.Comparator;
50 import java.util.Iterator;
51
52 import org.jaxen.Navigator;
53 import org.jaxen.UnsupportedAxisException;
54
55
56 class NodeComparator implements Comparator {
57
58 private Navigator navigator;
59
60
61 NodeComparator(Navigator navigator) {
62 this.navigator = navigator;
63 }
64
65 public int compare(Object o1, Object o2) {
66
67 if (o1 == o2) return 0;
68
69
70 if (navigator == null) return 0;
71
72 if (isNonChild(o1) && isNonChild(o2)) {
73
74 try {
75 Object p1 = navigator.getParentNode(o1);
76 Object p2 = navigator.getParentNode(o2);
77
78 if (p1 == p2) {
79 if (navigator.isNamespace(o1) && navigator.isAttribute(o2)) {
80 return -1;
81 }
82 else if (navigator.isNamespace(o2) && navigator.isAttribute(o1)) {
83 return 1;
84 }
85 else if (navigator.isNamespace(o1)) {
86 String prefix1 = navigator.getNamespacePrefix(o1);
87 String prefix2 = navigator.getNamespacePrefix(o2);
88 return prefix1.compareTo(prefix2);
89 }
90 else if (navigator.isAttribute(o1)) {
91 String name1 = navigator.getAttributeQName(o1);
92 String name2 = navigator.getAttributeQName(o2);
93 return name1.compareTo(name2);
94 }
95 }
96
97 return compare(p1, p2);
98 }
99 catch (UnsupportedAxisException ex) {
100 return 0;
101 }
102
103 }
104
105 try {
106 int depth1 = getDepth(o1);
107 int depth2 = getDepth(o2);
108
109 Object a1 = o1;
110 Object a2 = o2;
111
112 while (depth1 > depth2) {
113 a1 = navigator.getParentNode(a1);
114 depth1--;
115 }
116 if (a1 == o2) return 1;
117
118 while (depth2 > depth1) {
119 a2 = navigator.getParentNode(a2);
120 depth2--;
121 }
122 if (a2 == o1) return -1;
123
124
125 while (true) {
126 Object p1 = navigator.getParentNode(a1);
127 Object p2 = navigator.getParentNode(a2);
128 if (p1 == p2) {
129 return compareSiblings(a1, a2);
130 }
131 a1 = p1;
132 a2 = p2;
133 }
134
135 }
136 catch (UnsupportedAxisException ex) {
137 return 0;
138 }
139 }
140
141
142 private boolean isNonChild(Object o) {
143 return navigator.isAttribute(o) || navigator.isNamespace(o);
144 }
145
146 private int compareSiblings(Object sib1, Object sib2)
147 throws UnsupportedAxisException {
148
149
150 if (isNonChild(sib1)) {
151 return 1;
152 } else if (isNonChild(sib2)) {
153 return -1;
154 }
155
156 Iterator following = navigator.getFollowingSiblingAxisIterator(sib1);
157 while (following.hasNext()) {
158 Object next = following.next();
159 if (next.equals(sib2)) return -1;
160 }
161 return 1;
162
163 }
164
165 private int getDepth(Object o) throws UnsupportedAxisException {
166
167 int depth = 0;
168 Object parent = o;
169
170 while ((parent = navigator.getParentNode(parent)) != null) {
171 depth++;
172 }
173 return depth;
174
175 }
176
177 }