KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > dom4j > util > NodeComparator


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 JavaDoc;
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 JavaDoc {
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     public int compare(Object JavaDoc o1, Object JavaDoc o2) {
79         if (o1 == o2) {
80             return 0;
81         } else if (o1 == null) {
82             // null is less
83
return -1;
84         } else if (o2 == null) {
85             return 1;
86         }
87
88         if (o1 instanceof Node) {
89             if (o2 instanceof Node) {
90                 return compare((Node) o1, (Node) o2);
91             } else {
92                 // Node implementations are greater
93
return 1;
94             }
95         } else {
96             if (o2 instanceof Node) {
97                 // Node implementations are greater
98
return -1;
99             } else {
100                 if (o1 instanceof Comparable JavaDoc) {
101                     Comparable JavaDoc c1 = (Comparable JavaDoc) o1;
102
103                     return c1.compareTo(o2);
104                 } else {
105                     String JavaDoc name1 = o1.getClass().getName();
106                     String JavaDoc name2 = o2.getClass().getName();
107
108                     return name1.compareTo(name2);
109                 }
110             }
111         }
112     }
113
114     public int compare(Node n1, Node n2) {
115         int nodeType1 = n1.getNodeType();
116         int nodeType2 = n2.getNodeType();
117         int answer = nodeType1 - nodeType2;
118
119         if (answer != 0) {
120             return answer;
121         } else {
122             switch (nodeType1) {
123                 case Node.ELEMENT_NODE:
124                     return compare((Element) n1, (Element) n2);
125
126                 case Node.DOCUMENT_NODE:
127                     return compare((Document) n1, (Document) n2);
128
129                 case Node.ATTRIBUTE_NODE:
130                     return compare((Attribute) n1, (Attribute) n2);
131
132                 case Node.TEXT_NODE:
133                     return compare((Text) n1, (Text) n2);
134
135                 case Node.CDATA_SECTION_NODE:
136                     return compare((CDATA) n1, (CDATA) n2);
137
138                 case Node.ENTITY_REFERENCE_NODE:
139                     return compare((Entity) n1, (Entity) n2);
140
141                 case Node.PROCESSING_INSTRUCTION_NODE:
142                     return compare((ProcessingInstruction) n1,
143                             (ProcessingInstruction) n2);
144
145                 case Node.COMMENT_NODE:
146                     return compare((Comment) n1, (Comment) n2);
147
148                 case Node.DOCUMENT_TYPE_NODE:
149                     return compare((DocumentType) n1, (DocumentType) n2);
150
151                 case Node.NAMESPACE_NODE:
152                     return compare((Namespace) n1, (Namespace) n2);
153
154                 default:
155                     throw new RuntimeException JavaDoc("Invalid node types. node1: "
156                             + n1 + " and node2: " + n2);
157             }
158         }
159     }
160
161     public int compare(Document n1, Document n2) {
162         int answer = compare(n1.getDocType(), n2.getDocType());
163
164         if (answer == 0) {
165             answer = compareContent(n1, n2);
166         }
167
168         return answer;
169     }
170
171     public int compare(Element n1, Element n2) {
172         int answer = compare(n1.getQName(), n2.getQName());
173
174         if (answer == 0) {
175             // lets compare attributes
176
int c1 = n1.attributeCount();
177             int c2 = n2.attributeCount();
178             answer = c1 - c2;
179
180             if (answer == 0) {
181                 for (int i = 0; i < c1; i++) {
182                     Attribute a1 = n1.attribute(i);
183                     Attribute a2 = n2.attribute(a1.getQName());
184                     answer = compare(a1, a2);
185
186                     if (answer != 0) {
187                         return answer;
188                     }
189                 }
190
191                 answer = compareContent(n1, n2);
192             }
193         }
194
195         return answer;
196     }
197
198     public int compare(Attribute n1, Attribute n2) {
199         int answer = compare(n1.getQName(), n2.getQName());
200
201         if (answer == 0) {
202             answer = compare(n1.getValue(), n2.getValue());
203         }
204
205         return answer;
206     }
207
208     public int compare(QName n1, QName n2) {
209         int answer = compare(n1.getNamespaceURI(), n2.getNamespaceURI());
210
211         if (answer == 0) {
212             answer = compare(n1.getQualifiedName(), n2.getQualifiedName());
213         }
214
215         return answer;
216     }
217
218     public int compare(Namespace n1, Namespace n2) {
219         int answer = compare(n1.getURI(), n2.getURI());
220
221         if (answer == 0) {
222             answer = compare(n1.getPrefix(), n2.getPrefix());
223         }
224
225         return answer;
226     }
227
228     public int compare(CharacterData t1, CharacterData t2) {
229         return compare(t1.getText(), t2.getText());
230     }
231
232     public int compare(DocumentType o1, DocumentType o2) {
233         if (o1 == o2) {
234             return 0;
235         } else if (o1 == null) {
236             // null is less
237
return -1;
238         } else if (o2 == null) {
239             return 1;
240         }
241
242         int answer = compare(o1.getPublicID(), o2.getPublicID());
243
244         if (answer == 0) {
245             answer = compare(o1.getSystemID(), o2.getSystemID());
246
247             if (answer == 0) {
248                 answer = compare(o1.getName(), o2.getName());
249             }
250         }
251
252         return answer;
253     }
254
255     public int compare(Entity n1, Entity n2) {
256         int answer = compare(n1.getName(), n2.getName());
257
258         if (answer == 0) {
259             answer = compare(n1.getText(), n2.getText());
260         }
261
262         return answer;
263     }
264
265     public int compare(ProcessingInstruction n1, ProcessingInstruction n2) {
266         int answer = compare(n1.getTarget(), n2.getTarget());
267
268         if (answer == 0) {
269             answer = compare(n1.getText(), n2.getText());
270         }
271
272         return answer;
273     }
274
275     public int compareContent(Branch b1, Branch b2) {
276         int c1 = b1.nodeCount();
277         int c2 = b2.nodeCount();
278         int answer = c1 - c2;
279
280         if (answer == 0) {
281             for (int i = 0; i < c1; i++) {
282                 Node n1 = b1.node(i);
283                 Node n2 = b2.node(i);
284                 answer = compare(n1, n2);
285
286                 if (answer != 0) {
287                     break;
288                 }
289             }
290         }
291
292         return answer;
293     }
294
295     public int compare(String JavaDoc o1, String JavaDoc o2) {
296         if (o1 == o2) {
297             return 0;
298         } else if (o1 == null) {
299             // null is less
300
return -1;
301         } else if (o2 == null) {
302             return 1;
303         }
304
305         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  */

345
Popular Tags