Coverage Report - org.jaxen.expr.NodeComparator
 
Classes in this File Line Coverage Branch Coverage Complexity
NodeComparator
92%
47/51
100%
14/14
6
 
 1  
 /*
 2  
  * $Header$
 3  
  * $Revision$
 4  
  * $Date$
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  * Copyright 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 are
 13  
  * met:
 14  
  * 
 15  
  *   * Redistributions of source code must retain the above copyright
 16  
  *     notice, this list of conditions and the following disclaimer.
 17  
  * 
 18  
  *   * Redistributions in binary form must reproduce the above copyright
 19  
  *     notice, this list of conditions and the following disclaimer in the
 20  
  *     documentation and/or other materials provided with the distribution.
 21  
  * 
 22  
  *   * Neither the name of the Jaxen Project nor the names of its
 23  
  *     contributors may be used to endorse or promote products derived 
 24  
  *     from this software without specific prior written permission.
 25  
  * 
 26  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 27  
  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 28  
  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 29  
  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 30  
  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 31  
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 32  
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 33  
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 34  
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 35  
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 36  
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 37  
  *
 38  
  * ====================================================================
 39  
  * This software consists of voluntary contributions made by many 
 40  
  * individuals on behalf of the Jaxen Project and was originally 
 41  
  * created by bob mcwhirter <bob@werken.com> and 
 42  
  * James Strachan <jstrachan@apache.org>.  For more information on the 
 43  
  * Jaxen Project, please see <http://www.jaxen.org/>.
 44  
  * 
 45  
  * $Id$
 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  1874
     NodeComparator(Navigator navigator) {
 62  1874
         this.navigator = navigator;
 63  1874
     }
 64  
     
 65  
     public int compare(Object o1, Object o2) {
 66  
         
 67  21678
         if (navigator == null) return 0;
 68  
         
 69  21678
         if (isNonChild(o1) && isNonChild(o2)) {
 70  
             
 71  
             try {
 72  1798
                 Object p1 = navigator.getParentNode(o1);
 73  1798
                 Object p2 = navigator.getParentNode(o2);
 74  
             
 75  1798
                 if (p1 == p2) {
 76  854
                     if (navigator.isNamespace(o1) && navigator.isAttribute(o2)) {
 77  2
                         return -1;
 78  
                     }
 79  852
                     else if (navigator.isNamespace(o2) && navigator.isAttribute(o1)) {
 80  4
                         return 1;
 81  
                     }
 82  
                 }
 83  
 
 84  1792
                 return compare(p1, p2);
 85  
             }
 86  0
             catch (UnsupportedAxisException ex) {
 87  0
                 return 0;
 88  
             }
 89  
             
 90  
         }
 91  
 
 92  
         try {
 93  19880
             int depth1 = getDepth(o1);
 94  19880
             int depth2 = getDepth(o2);
 95  
             
 96  19880
             Object a1 = o1;
 97  19880
             Object a2 = o2;
 98  
                         
 99  20092
             while (depth1 > depth2) {
 100  212
                 a1 = navigator.getParentNode(a1);
 101  212
                 depth1--;
 102  212
             }
 103  19880
             if (a1 == o2) return 1;
 104  
             
 105  21614
             while (depth2 > depth1) {
 106  2618
                 a2 = navigator.getParentNode(a2);
 107  2618
                 depth2--;
 108  2618
             }
 109  18996
             if (a2 == o1) return -1;
 110  
             
 111  
             // a1 and a2 are now at same depth; and are not the same
 112  
             while (true) {
 113  20626
                 Object p1 = navigator.getParentNode(a1);
 114  20626
                 Object p2 = navigator.getParentNode(a2);
 115  20626
                 if (p1 == p2) {
 116  18360
                     return compareSiblings(a1, a2);
 117  
                 }
 118  2266
                 a1 = p1;
 119  2266
                 a2 = p2;
 120  2266
             }
 121  
             
 122  
         }
 123  0
         catch (UnsupportedAxisException ex) {
 124  0
             return 0; // ???? should I throw an exception instead?
 125  
         }
 126  
     }
 127  
     
 128  
 
 129  
     private boolean isNonChild(Object o) {
 130  23492
         return navigator.isAttribute(o) || navigator.isNamespace(o);
 131  
     }
 132  
 
 133  
     private int compareSiblings(Object sib1, Object sib2) 
 134  
       throws UnsupportedAxisException {
 135  
 
 136  18360
         Iterator following = navigator.getFollowingSiblingAxisIterator(sib1);
 137  72586
         while (following.hasNext()) {
 138  70860
             Object next = following.next();
 139  70860
             if (next.equals(sib2)) return -1;
 140  54226
         }
 141  1726
         return 1;
 142  
         
 143  
     }
 144  
 
 145  
     private int getDepth(Object o) throws UnsupportedAxisException {
 146  
 
 147  39760
         int depth = 0;
 148  39760
         Object parent = o;
 149  
         
 150  134558
         while ((parent = navigator.getParentNode(parent)) != null) {
 151  94798
             depth++;
 152  94798
         }
 153  39760
         return depth;
 154  
         
 155  
     }
 156  
     
 157  
 }