Clover coverage report - dom4j - 1.6.1 Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00 FRAMES NO FRAMES |
file stats: | LOC: | 344 |  | Methods: | 13
| NCLOC: | 190 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
NodeComparator.java | 50% | 67,8% | 92,3% | 64% |

1 |  | /*
2 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
3 |  | *
4 |  | * This software is open source.
5 |  | * See the bottom of this file for the licence.
6 |  | */
7 |  |
8 |  | package org.dom4j.util;
9 |  |
10 |  | import java.util.Comparator;
11 |  |
12 |  | import org.dom4j.Attribute;
13 |  | import org.dom4j.Branch;
14 |  | import org.dom4j.CDATA;
15 |  | import org.dom4j.CharacterData;
16 |  | import org.dom4j.Comment;
17 |  | import org.dom4j.Document;
18 |  | import org.dom4j.DocumentType;
19 |  | import org.dom4j.Element;
20 |  | import org.dom4j.Entity;
21 |  | import org.dom4j.Namespace;
22 |  | import org.dom4j.Node;
23 |  | import org.dom4j.ProcessingInstruction;
24 |  | import org.dom4j.QName;
25 |  | import org.dom4j.Text;
26 |  |
27 |  | /**
28 |  | * <p>
29 |  | * <code>NodeComparator</code> is a {@link Comparator}of Node instances which
30 |  | * is capable of comparing Nodes for equality based on their values.
31 |  | * </p>
32 |  | *
33 |  | * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
34 |  | * @version $Revision: 1.10 $
35 |  | */
36 |  | public class NodeComparator implements Comparator {
37 |  | /**
38 |  | * Compares its two arguments for order. Returns a negative integer, zero,
39 |  | * or a positive integer as the first argument is less than, equal to, or
40 |  | * greater than the second.
41 |  | *
42 |  | * <p>
43 |  | * The implementor must ensure that <tt>sgn(compare(x, y)) ==
44 |  | * -sgn(compare(y, x))</tt>
45 |  | * for all <tt>x</tt> and <tt>y</tt>. (This implies that
46 |  | * <tt>compare(x, y)</tt> must throw an exception if and only if
47 |  | * <tt>compare(y, x)</tt> throws an exception.)
48 |  | * </p>
49 |  | *
50 |  | * <p>
51 |  | * The implementor must also ensure that the relation is transitive:
52 |  | * <tt>((compare(x, y)&gt;0) &amp;&amp; (compare(y, z)&gt;0))</tt> implies
53 |  | * <tt>compare(x, z)&gt;0</tt>.
54 |  | * </p>
55 |  | *
56 |  | * <p>
57 |  | * Finally, the implementer must ensure that <tt>compare(x, y)==0</tt>
58 |  | * implies that <tt>sgn(compare(x, z))==sgn(compare(y, z))</tt> for all
59 |  | * <tt>z</tt>.
60 |  | * </p>
61 |  | *
62 |  | * <p>
63 |  | * It is generally the case, but <i>not </i> strictly required that
64 |  | * <tt>(compare(x, y)==0) == (x.equals(y))</tt>. Generally speaking, any
65 |  | * comparator that violates this condition should clearly indicate this
66 |  | * fact. The recommended language is "Note: this comparator imposes
67 |  | * orderings that are inconsistent with equals."
68 |  | * </p>
69 |  | *
70 |  | * @param o1
71 |  | * the first object to be compared.
72 |  | * @param o2
73 |  | * the second object to be compared.
74 |  | *
75 |  | * @return a negative integer, zero, or a positive integer as the first
76 |  | * argument is less than, equal to, or greater than the second.
77 |  | */
78 | 6 | public int compare(Object o1, Object o2) {
79 | 6 | if (o1 == o2) {
80 | 0 | return 0;
81 | 6 | } else if (o1 == null) {
82 |  | // null is less
83 | 0 | return -1;
84 | 6 | } else if (o2 == null) {
85 | 0 | return 1;
86 |  | }
87 |  |
88 | 6 | if (o1 instanceof Node) {
89 | 6 | if (o2 instanceof Node) {
90 | 6 | return compare((Node) o1, (Node) o2);
91 |  | } else {
92 |  | // Node implementations are greater
93 | 0 | return 1;
94 |  | }
95 |  | } else {
96 | 0 | if (o2 instanceof Node) {
97 |  | // Node implementations are greater
98 | 0 | return -1;
99 |  | } else {
100 | 0 | if (o1 instanceof Comparable) {
101 | 0 | Comparable c1 = (Comparable) o1;
102 |  |
103 | 0 | return c1.compareTo(o2);
104 |  | } else {
105 | 0 | String name1 = o1.getClass().getName();
106 | 0 | String name2 = o2.getClass().getName();
107 |  |
108 | 0 | return name1.compareTo(name2);
109 |  | }
110 |  | }
111 |  | }
112 |  | }
113 |  |
114 | 60643 | public int compare(Node n1, Node n2) {
115 | 60643 | int nodeType1 = n1.getNodeType();
116 | 60643 | int nodeType2 = n2.getNodeType();
117 | 60643 | int answer = nodeType1 - nodeType2;
118 |  |
119 | 60643 | if (answer != 0) {
120 | 0 | return answer;
121 |  | } else {
122 | 60643 | switch (nodeType1) {
123 | 21394 | case Node.ELEMENT_NODE:
124 | 21394 | return compare((Element) n1, (Element) n2);
125 |  |
126 | 4 | case Node.DOCUMENT_NODE:
127 | 4 | return compare((Document) n1, (Document) n2);
128 |  |
129 | 0 | case Node.ATTRIBUTE_NODE:
130 | 0 | return compare((Attribute) n1, (Attribute) n2);
131 |  |
132 | 38623 | case Node.TEXT_NODE:
133 | 38623 | return compare((Text) n1, (Text) n2);
134 |  |
135 | 90 | case Node.CDATA_SECTION_NODE:
136 | 90 | return compare((CDATA) n1, (CDATA) n2);
137 |  |
138 | 0 | case Node.ENTITY_REFERENCE_NODE:
139 | 0 | return compare((Entity) n1, (Entity) n2);
140 |  |
141 | 6 | case Node.PROCESSING_INSTRUCTION_NODE:
142 | 6 | return compare((ProcessingInstruction) n1,
143 |  | (ProcessingInstruction) n2);
144 |  |
145 | 408 | case Node.COMMENT_NODE:
146 | 408 | return compare((Comment) n1, (Comment) n2);
147 |  |
148 | 0 | case Node.DOCUMENT_TYPE_NODE:
149 | 0 | return compare((DocumentType) n1, (DocumentType) n2);
150 |  |
151 | 118 | case Node.NAMESPACE_NODE:
152 | 118 | return compare((Namespace) n1, (Namespace) n2);
153 |  |
154 | 0 | default:
155 | 0 | throw new RuntimeException("Invalid node types. node1: "
156 |  | + n1 + " and node2: " + n2);
157 |  | }
158 |  | }
159 |  | }
160 |  |
161 | 58 | public int compare(Document n1, Document n2) {
162 | 58 | int answer = compare(n1.getDocType(), n2.getDocType());
163 |  |
164 | 58 | if (answer == 0) {
165 | 58 | answer = compareContent(n1, n2);
166 |  | }
167 |  |
168 | 58 | return answer;
169 |  | }
170 |  |
171 | 21394 | public int compare(Element n1, Element n2) {
172 | 21394 | int answer = compare(n1.getQName(), n2.getQName());
173 |  |
174 | 21394 | if (answer == 0) {
175 |  | // lets compare attributes
176 | 21394 | int c1 = n1.attributeCount();
177 | 21394 | int c2 = n2.attributeCount();
178 | 21394 | answer = c1 - c2;
179 |  |
180 | 21394 | if (answer == 0) {
181 | 21393 | for (int i = 0; i < c1; i++) {
182 | 8747 | Attribute a1 = n1.attribute(i);
183 | 8747 | Attribute a2 = n2.attribute(a1.getQName());
184 | 8747 | answer = compare(a1, a2);
185 |  |
186 | 8747 | if (answer != 0) {
187 | 1 | return answer;
188 |  | }
189 |  | }
190 |  |
191 | 21392 | answer = compareContent(n1, n2);
192 |  | }
193 |  | }
194 |  |
195 | 21393 | return answer;
196 |  | }
197 |  |
198 | 8747 | public int compare(Attribute n1, Attribute n2) {
199 | 8747 | int answer = compare(n1.getQName(), n2.getQName());
200 |  |
201 | 8747 | if (answer == 0) {
202 | 8747 | answer = compare(n1.getValue(), n2.getValue());
203 |  | }
204 |  |
205 | 8747 | return answer;
206 |  | }
207 |  |
208 | 30141 | public int compare(QName n1, QName n2) {
209 | 30141 | int answer = compare(n1.getNamespaceURI(), n2.getNamespaceURI());
210 |  |
211 | 30141 | if (answer == 0) {
212 | 30141 | answer = compare(n1.getQualifiedName(), n2.getQualifiedName());
213 |  | }
214 |  |
215 | 30141 | return answer;
216 |  | }
217 |  |
218 | 118 | public int compare(Namespace n1, Namespace n2) {
219 | 118 | int answer = compare(n1.getURI(), n2.getURI());
220 |  |
221 | 118 | if (answer == 0) {
222 | 118 | answer = compare(n1.getPrefix(), n2.getPrefix());
223 |  | }
224 |  |
225 | 118 | return answer;
226 |  | }
227 |  |
228 | 39121 | public int compare(CharacterData t1, CharacterData t2) {
229 | 39121 | return compare(t1.getText(), t2.getText());
230 |  | }
231 |  |
232 | 58 | public int compare(DocumentType o1, DocumentType o2) {
233 | 58 | if (o1 == o2) {
234 | 58 | return 0;
235 | 0 | } else if (o1 == null) {
236 |  | // null is less
237 | 0 | return -1;
238 | 0 | } else if (o2 == null) {
239 | 0 | return 1;
240 |  | }
241 |  |
242 | 0 | int answer = compare(o1.getPublicID(), o2.getPublicID());
243 |  |
244 | 0 | if (answer == 0) {
245 | 0 | answer = compare(o1.getSystemID(), o2.getSystemID());
246 |  |
247 | 0 | if (answer == 0) {
248 | 0 | answer = compare(o1.getName(), o2.getName());
249 |  | }
250 |  | }
251 |  |
252 | 0 | return answer;
253 |  | }
254 |  |
255 | 0 | public int compare(Entity n1, Entity n2) {
256 | 0 | int answer = compare(n1.getName(), n2.getName());
257 |  |
258 | 0 | if (answer == 0) {
259 | 0 | answer = compare(n1.getText(), n2.getText());
260 |  | }
261 |  |
262 | 0 | return answer;
263 |  | }
264 |  |
265 | 6 | public int compare(ProcessingInstruction n1, ProcessingInstruction n2) {
266 | 6 | int answer = compare(n1.getTarget(), n2.getTarget());
267 |  |
268 | 6 | if (answer == 0) {
269 | 6 | answer = compare(n1.getText(), n2.getText());
270 |  | }
271 |  |
272 | 6 | return answer;
273 |  | }
274 |  |
275 | 21450 | public int compareContent(Branch b1, Branch b2) {
276 | 21450 | int c1 = b1.nodeCount();
277 | 21450 | int c2 = b2.nodeCount();
278 | 21450 | int answer = c1 - c2;
279 |  |
280 | 21450 | if (answer == 0) {
281 | 21448 | for (int i = 0; i < c1; i++) {
282 | 60637 | Node n1 = b1.node(i);
283 | 60637 | Node n2 = b2.node(i);
284 | 60637 | answer = compare(n1, n2);
285 |  |
286 | 60637 | if (answer != 0) {
287 | 6 | break;
288 |  | }
289 |  | }
290 |  | }
291 |  |
292 | 21450 | return answer;
293 |  | }
294 |  |
295 | 108398 | public int compare(String o1, String o2) {
296 | 108398 | if (o1 == o2) {
297 | 66175 | return 0;
298 | 42223 | } else if (o1 == null) {
299 |  | // null is less
300 | 0 | return -1;
301 | 42223 | } else if (o2 == null) {
302 | 0 | return 1;
303 |  | }
304 |  |
305 | 42223 | return o1.compareTo(o2);
306 |  | }
307 |  | }
308 |  |
309 |  | /*
310 |  | * Redistribution and use of this software and associated documentation
311 |  | * ("Software"), with or without modification, are permitted provided that the
312 |  | * following conditions are met:
313 |  | *
314 |  | * 1. Redistributions of source code must retain copyright statements and
315 |  | * notices. Redistributions must also contain a copy of this document.
316 |  | *
317 |  | * 2. Redistributions in binary form must reproduce the above copyright notice,
318 |  | * this list of conditions and the following disclaimer in the documentation
319 |  | * and/or other materials provided with the distribution.
320 |  | *
321 |  | * 3. The name "DOM4J" must not be used to endorse or promote products derived
322 |  | * from this Software without prior written permission of MetaStuff, Ltd. For
323 |  | * written permission, please contact dom4j-info@metastuff.com.
324 |  | *
325 |  | * 4. Products derived from this Software may not be called "DOM4J" nor may
326 |  | * "DOM4J" appear in their names without prior written permission of MetaStuff,
327 |  | * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
328 |  | *
329 |  | * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
330 |  | *
331 |  | * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
332 |  | * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
333 |  | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
334 |  | * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
335 |  | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
336 |  | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
337 |  | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
338 |  | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
339 |  | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
340 |  | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
341 |  | * POSSIBILITY OF SUCH DAMAGE.
342 |  | *
343 |  | * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
344 |  | */