##### Coverage Report - org.jaxen.expr.NodeComparator

Classes in this File | Line Coverage | Branch Coverage | Complexity
NodeComparator |
91% |
100% |
| 6.0;6

1 |  |
     /*
2 |  |
      * $Header$
3 |  |
      * $Revision$
4 |  |
      * $Date$
5 |  |
      *
6 |  |
      * ====================================================================
7 |  |
      *
8 |  |
      * Copyright (C) 2005 Elliotte Rusty Harold.
9 |  |
      * All rights reserved.
10 |  |
      *
11 |  |
      * Redistribution and use in source and binary forms, with or without
12 |  |
      * modification, are permitted provided that the following conditions
13 |  |
      * are met:
14 |  |
      *
15 |  |
      * 1. Redistributions of source code must retain the above copyright
16 |  |
      *    notice, this list of conditions, and the following disclaimer.
17 |  |
      *
18 |  |
      * 2. Redistributions in binary form must reproduce the above copyright
19 |  |
      *    notice, this list of conditions, and the disclaimer that follows
20 |  |
      *    these conditions in the documentation and/or other materials
21 |  |
      *    provided with the distribution.
22 |  |
      *
23 |  |
      * 3. The name "Jaxen" must not be used to endorse or promote products
24 |  |
      *    derived from this software without prior written permission.  For
25 |  |
      *    written permission, please contact license@jaxen.org.
26 |  |
      *
27 |  |
      * 4. Products derived from this software may not be called "Jaxen", nor
28 |  |
      *    may "Jaxen" appear in their name, without prior written permission
29 |  |
      *    from the Jaxen Project Management (pm@jaxen.org).
30 |  |
      *
31 |  |
      * In addition, we request (but do not require) that you include in the
32 |  |
      * end-user documentation provided with the redistribution and/or in the
33 |  |
      * software itself an acknowledgement equivalent to the following:
34 |  |
      *     "This product includes software developed by the
35 |  |
      *      Jaxen Project <http://www.jaxen.org/>."
36 |  |
      * Alternatively, the acknowledgment may be graphical using the logos
37 |  |
      * available at http://www.jaxen.org/
38 |  |
      *
39 |  |
      * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
40 |  |
      * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41 |  |
      * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
42 |  |
      * DISCLAIMED.  IN NO EVENT SHALL THE Jaxen AUTHORS OR THE PROJECT
43 |  |
      * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 |  |
      * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 |  |
      * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
46 |  |
      * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
47 |  |
      * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
48 |  |
      * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
49 |  |
      * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
50 |  |
      * SUCH DAMAGE.
51 |  |
      *
52 |  |
      * ====================================================================
53 |  |
      * This software consists of voluntary contributions made by many
54 |  |
      * individuals on behalf of the Jaxen Project and was originally
55 |  |
      * created by bob mcwhirter <bob@werken.com> and
56 |  |
      * James Strachan <jstrachan@apache.org>.  For more information on the
57 |  |
      * Jaxen Project, please see <http://www.jaxen.org/>.
58 |  |
      *
59 |  |
      * $Id$
60 |  |
      */
61 |  |
     package org.jaxen.expr;
62 |  |
63 |  |
     import java.util.Comparator;
64 |  |
     import java.util.Iterator;
65 |  |
66 |  |
     import org.jaxen.Navigator;
67 |  |
     import org.jaxen.UnsupportedAxisException;
68 |  |
69 |  |
70 |  |
     class NodeComparator implements Comparator {
71 |  |
72 |  |
         private Navigator navigator;
73 |  |
74 |  |
75 | 5526 |
         NodeComparator(Navigator navigator) {
76 | 5526 |
             this.navigator = navigator;
77 | 5526 |
         }
78 |  |
79 |  |
         public int compare(Object o1, Object o2) {
80 |  |
81 | 64770 |
             if (navigator == null) return 0;
82 |  |
83 | 64770 |
             if (isNonChild(o1) && isNonChild(o2)) {
84 |  |
85 |  |
                 try {
86 | 5286 |
                     Object p1 = navigator.getParentNode(o1);
87 | 5286 |
                     Object p2 = navigator.getParentNode(o2);
88 |  |
89 | 5286 |
                     if (p1 == p2) {
90 | 2484 |
                         if (navigator.isNamespace(o1) && navigator.isAttribute(o2)) {
91 | 6 |
                             return -1;
92 |  |
                         }
93 | 2478 |
                         else if (navigator.isNamespace(o2) && navigator.isAttribute(o1)) {
94 | 12 |
                             return 1;
95 |  |
                         }
96 |  |
                     }
97 |  |
98 | 5268 |
                     return compare(p1, p2);
99 |  |
                 }
100 | 0 |
                 catch (UnsupportedAxisException ex) {
101 | 0 |
                     return 0;
102 |  |
                 }
103 |  |
104 |  |
             }
105 |  |
106 |  |
             try {
107 | 59484 |
                 int depth1 = getDepth(o1);
108 | 59484 |
                 int depth2 = getDepth(o2);
109 |  |
110 | 59484 |
                 Object a1 = o1;
111 | 59484 |
                 Object a2 = o2;
112 |  |
113 | 60120 |
                 while (depth1 > depth2) {
114 | 636 |
                     a1 = navigator.getParentNode(a1);
115 | 636 |
                     depth1--;
116 |  |
                 }
117 | 59484 |
                 if (a1 == o2) return 1;
118 |  |
119 | 64734 |
                 while (depth2 > depth1) {
120 | 7824 |
                     a2 = navigator.getParentNode(a2);
121 | 7824 |
                     depth2--;
122 |  |
                 }
123 | 56910 |
                 if (a2 == o1) return -1;
124 |  |
125 |  |
                 // a1 and a2 are now at same depth; and are not the same
126 |  |
                 while (true) {
127 | 61830 |
                     Object p1 = navigator.getParentNode(a1);
128 | 61830 |
                     Object p2 = navigator.getParentNode(a2);
129 | 61830 |
                     if (p1 == p2) {
130 | 55032 |
                         return compareSiblings(a1, a2);
131 |  |
                     }
132 | 6798 |
                     a1 = p1;
133 | 6798 |
                     a2 = p2;
134 |  |
                 }
135 |  |
136 |  |
             }
137 | 0 |
             catch (UnsupportedAxisException ex) {
138 | 0 |
                 return 0; // ???? should I throw an exception instead?
139 |  |
             }
140 |  |
         }
141 |  |
142 |  |
143 |  |
         private boolean isNonChild(Object o) {
144 | 70104 |
             return navigator.isAttribute(o) || navigator.isNamespace(o);
145 |  |
         }
146 |  |
147 |  |
         private int compareSiblings(Object sib1, Object sib2)
148 |  |
           throws UnsupportedAxisException {
149 |  |
150 | 55032 |
             Iterator following = navigator.getFollowingSiblingAxisIterator(sib1);
151 | 217674 |
             while (following.hasNext()) {
152 | 212496 |
                 Object next = following.next();
153 | 212496 |
                 if (next.equals(sib2)) return -1;
154 |  |
             }
155 | 5178 |
             return 1;
156 |  |
157 |  |
         }
158 |  |
159 |  |
         private int getDepth(Object o) throws UnsupportedAxisException {
160 |  |
161 | 118968 |
             int depth = 0;
162 | 118968 |
             Object parent = o;
163 |  |
164 | 402780 |
             while ((parent = navigator.getParentNode(parent)) != null) {
165 | 283812 |
                 depth++;
166 |  |
             }
167 | 118968 |
             return depth;
168 |  |
169 |  |
         }
170 |  |
171 |  |
     }