Coverage Report - org.jaxen.xom.DocumentNavigator

Classes in this Package Line Coverage Branch Coverage Complexity
DocumentNavigator
73% 
67% 
1.8

 1  
 /*
 2  
  * $Header: /home/projects/jaxen/scm/jaxen/src/java/main/org/jaxen/xom/DocumentNavigator.java,v 1.4 2005/01/30 03:17:34 elharo Exp $
 3  
  * $Revision: 1.4 $
 4  
  * $Date: 2005/01/30 03:17:34 $
 5  
  *
 6  
  * ====================================================================
 7  
  *
 8  
  * Copyright (C) 2000-2003 bob mcwhirter & James Strachan.
 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: DocumentNavigator.java,v 1.4 2005/01/30 03:17:34 elharo Exp $
 60  
  */
 61  
 
 62  
 
 63  
 package org.jaxen.xom;
 64  
 
 65  
 
 66  
 import nu.xom.Attribute;
 67  
 import nu.xom.Comment;
 68  
 import nu.xom.Document;
 69  
 import nu.xom.Element;
 70  
 import nu.xom.ProcessingInstruction;
 71  
 import nu.xom.Text;
 72  
 import nu.xom.Node;
 73  
 import nu.xom.Builder;
 74  
 import nu.xom.NodeFactory;
 75  
 import nu.xom.ParentNode;
 76  
 
 77  
 import org.jaxen.XPath;
 78  
 import org.jaxen.UnsupportedAxisException;
 79  
 import org.jaxen.FunctionCallException;
 80  
 import org.jaxen.BaseXPath;
 81  
 import org.jaxen.JaxenConstants;
 82  
 import org.jaxen.util.SingleObjectIterator;
 83  
 
 84  
 import org.jaxen.saxpath.SAXPathException;
 85  
 
 86  
 import java.util.Iterator;
 87  
 import java.util.HashMap;
 88  
 import java.util.Map;
 89  
 
 90  
 /**
 91  
  * Interface for navigating around the XOM object model.
 92  
  *
 93  
  * <p>
 94  
  * This class is not intended for direct usage, but is
 95  
  * used by the Jaxen engine during evaluation.
 96  
  * </p>
 97  
  *
 98  
  * @see XPath
 99  
  *
 100  
  */
 101  156
 public class DocumentNavigator extends org.jaxen.DefaultNavigator
 102  
 {
 103  
     public boolean isAttribute(Object o) {
 104  6526
         return o instanceof Attribute;
 105  
     }
 106  
 
 107  
     public boolean isComment(Object o) {
 108  1072
         return o instanceof Comment;
 109  
     }
 110  
 
 111  
     public boolean isDocument(Object o) {
 112  1433
         return o instanceof Document;
 113  
     }
 114  
 
 115  
     public boolean isElement(Object o) {
 116  319058
         return o instanceof Element;
 117  
     }
 118  
 
 119  
     public boolean isNamespace(Object o) {
 120  4410
         return o instanceof XPathNamespace;
 121  
     }
 122  
 
 123  
     public boolean isProcessingInstruction(Object o) {
 124  1042
         return o instanceof ProcessingInstruction;
 125  
     }
 126  
 
 127  
     public boolean isText(Object o) {
 128  79900
         return o instanceof Text;
 129  
     }
 130  
 
 131  
     //
 132  
     
 133  
     public String getAttributeName(Object o) {
 134  455
         return (isAttribute(o) ? ((Attribute)o).getLocalName() : null);
 135  
     }
 136  
 
 137  
     public String getAttributeNamespaceUri(Object o) {
 138  455
         return (isAttribute(o) ? ((Attribute)o).getNamespaceURI() : null);
 139  
     }
 140  
 
 141  
     public String getAttributeQName(Object o) {
 142  0
         return (isAttribute(o) ? ((Attribute)o).getQualifiedName() : null);
 143  
     }
 144  
 
 145  
     public String getAttributeStringValue(Object o) {
 146  287
         return (isAttribute(o) ? ((Attribute)o).getValue() : null);
 147  
     }
 148  
 
 149  
     //
 150  
     
 151  
     public String getCommentStringValue(Object o) {
 152  0
         return (isComment(o) ? ((Comment)o).getValue() : null);
 153  
     }
 154  
 
 155  
     public String getElementName(Object o) {
 156  40076
         return (isElement(o) ? ((Element)o).getLocalName() : null);
 157  
     }
 158  
 
 159  
     public String getElementNamespaceUri(Object o) {
 160  39845
         return (isElement(o) ? ((Element)o).getNamespaceURI() : null);
 161  
     }
 162  
 
 163  
     public String getElementQName(Object o) {
 164  26
         return (isElement(o) ? ((Element)o).getQualifiedName() : null);
 165  
     }
 166  
 
 167  
     public String getElementStringValue(Object o) {
 168  0
         return (o instanceof Node ? ((Node)o).getValue() : null);
 169  
     }
 170  
 
 171  
     //
 172  
     
 173  
     public String getNamespacePrefix(Object o) {
 174  117
         if (isElement(o)) {
 175  0
             return ((Element)o).getNamespacePrefix();
 176  117
         } else if (isAttribute(o)) {
 177  0
             return ((Attribute)o).getNamespacePrefix();
 178  117
         } else if (o instanceof XPathNamespace) {
 179  117
             return ((XPathNamespace)o).getNamespacePrefix();
 180  
         }
 181  0
         return null;
 182  
     }
 183  
 
 184  
     public String getNamespaceStringValue(Object o) {
 185  0
         if (isElement(o)) {
 186  0
             return ((Element)o).getNamespaceURI();
 187  0
         } else if (isAttribute(o)) {
 188  0
             return ((Attribute)o).getNamespaceURI();
 189  0
         } else if (o instanceof XPathNamespace) {
 190  0
             return ((XPathNamespace)o).getNamespaceURI();
 191  
         }
 192  0
         return null;
 193  
     }
 194  
 
 195  
     //
 196  
     
 197  
     public String getTextStringValue(Object o) {
 198  144
         return (o instanceof Text ? ((Text)o).getValue() : null);
 199  
     }
 200  
     
 201  
     //
 202  
 
 203  
     public Object getDocument(String s) throws FunctionCallException {
 204  
         try {
 205  4
             return new Builder(new NodeFactory()).build(s);
 206  0
         } catch (Exception pe) {
 207  0
             throw new FunctionCallException(pe);
 208  
         }
 209  
     }
 210  
 
 211  
     public Object getDocumentNode(Object o) {
 212  260
         ParentNode parent = null;
 213  260
         if (o instanceof ParentNode) {
 214  260
             parent = (ParentNode)o;
 215  0
         } else if (o instanceof Node) {
 216  0
             parent = ((Node)o).getParent();
 217  
         }
 218  260
         return parent.getDocument();
 219  
     }
 220  
 
 221  
     //
 222  
     
 223  
     private abstract static class IndexIterator implements Iterator {
 224  42403
         private Object o = null;
 225  42403
         private int pos = 0, end = -1;
 226  42403
         public IndexIterator(Object o, int pos, int end) {
 227  42403
             this.o = o;
 228  42403
             this.pos = pos;
 229  42403
             this.end = end;
 230  42403
         }
 231  
         public boolean hasNext() {
 232  352692
             return pos < end;
 233  
         }
 234  
         public abstract Object get(Object o, int i); 
 235  
         
 236  
         public Object next() {
 237  198315
             return get(o, pos++);
 238  
         }
 239  
 
 240  
         public void remove() {
 241  0
             throw new UnsupportedOperationException();
 242  
         }
 243  
     }
 244  
     
 245  
     //
 246  
     
 247  
     public Iterator getAttributeAxisIterator(Object o) throws UnsupportedAxisException {
 248  645
         if (isElement(o)) {
 249  599
             return new IndexIterator(o, 0, ((Element)o).getAttributeCount()) {
 250  599
                 public Object get(Object o, int i) {
 251  455
                     return ((Element)o).getAttribute(i);
 252  
                 }
 253  
             };
 254  
         }
 255  46
         return JaxenConstants.EMPTY_ITERATOR;
 256  
     }
 257  
 
 258  
     public Iterator getChildAxisIterator(Object o) throws UnsupportedAxisException {
 259  119163
         if (isElement(o) || (o instanceof Document)) {
 260  41804
             return new IndexIterator(o, 0, ((ParentNode)o).getChildCount()) {
 261  41804
                 public Object get(Object o, int i) {
 262  197860
                     return ((ParentNode)o).getChild(i);
 263  
                 }
 264  
             };
 265  
         }
 266  77359
         return JaxenConstants.EMPTY_ITERATOR;
 267  
     }
 268  
 
 269  
     //
 270  
 
 271  
     public Iterator getParentAxisIterator(Object o) throws UnsupportedAxisException {
 272  14
         Object parent = null;
 273  14
         if (o instanceof Node) {
 274  12
             parent = ((Node)o).getParent();
 275  2
         } else if (isNamespace(o)) {
 276  2
             parent = ((XPathNamespace)o).getElement();
 277  
         }
 278  14
         return (parent != null ? new SingleObjectIterator(parent) : null);
 279  
     }
 280  
 
 281  
     public Object getParentNode(Object o) throws UnsupportedAxisException {
 282  24103
         return (o instanceof Node ? ((Node)o).getParent() : null);
 283  
     }
 284  
 
 285  
     //
 286  
 
 287  
     public Iterator getPrecedingAxisIterator(Object o) throws UnsupportedAxisException {
 288  18
         return super.getPrecedingAxisIterator(o);
 289  
     }
 290  
 
 291  
     public Iterator getPrecedingSiblingAxisIterator(Object o) throws UnsupportedAxisException {
 292  11
         return super.getPrecedingSiblingAxisIterator(o);
 293  
     }
 294  
     
 295  
     //
 296  
 
 297  
     public String getProcessingInstructionData(Object o) {
 298  3
         return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getValue() : null);
 299  
     }
 300  
 
 301  
     public String getProcessingInstructionTarget(Object o) {
 302  6
         return (o instanceof ProcessingInstruction ? ((ProcessingInstruction)o).getTarget() : null);
 303  
     }
 304  
 
 305  
     //
 306  
 
 307  
     public String translateNamespacePrefixToUri(String s, Object o) {
 308  0
         Element element = null;
 309  0
         if (o instanceof Element) {
 310  0
             element = (Element) o;
 311  0
         } else if (o instanceof ParentNode) {
 312  
         }
 313  0
         else if (o instanceof Node) {
 314  0
             element = (Element)((Node)o).getParent();
 315  
         }
 316  0
         else if (o instanceof XPathNamespace)
 317  
         {
 318  0
             element = ((XPathNamespace)o).getElement();
 319  
         }
 320  0
         if (element != null) {
 321  0
             return element.getNamespaceURI(s);
 322  
         }
 323  0
         return null;
 324  
     }
 325  
 
 326  
     //
 327  
     
 328  
     public XPath parseXPath(String s) throws SAXPathException {
 329  7
         return new BaseXPath(s, this);
 330  
     }
 331  
 
 332  
     //
 333  
     
 334  
     /** Wrapper for XOM namespace nodes to give them a parent,
 335  
      * as required by the XPath data model.
 336  
      *
 337  
      *  @author Erwin Bolwidt
 338  
      */
 339  156
     private static class XPathNamespace
 340  
     {
 341  
         private Element element;
 342  
 
 343  
         private String uri, prefix;
 344  
 
 345  
         public XPathNamespace(Element elt, String uri, String prefix)
 346  117
         {
 347  117
             element = elt;
 348  117
             this.uri = uri;
 349  117
             this.prefix = prefix;
 350  117
         }
 351  
 
 352  
         /** Returns the XOM element from which this namespace node has been 
 353  
          *  retrieved. The result may be null when the namespace node has not yet
 354  
          *  been assigned to an element.
 355  
          */
 356  
         public Element getElement()
 357  
         {
 358  2
             return element;
 359  
         }
 360  
 
 361  
         public String getNamespaceURI()
 362  
         {
 363  0
             return uri;
 364  
         }
 365  
 
 366  
         public String getNamespacePrefix()
 367  
         {
 368  117
             return prefix;
 369  
         }
 370  
 
 371  
         public String toString()
 372  
         {
 373  0
             return ( "[xmlns:" + prefix + "=\"" +
 374  
                     uri + "\", element=" +
 375  
                     element.getLocalName() + "]" );
 376  
         }
 377  
     }
 378  
 
 379  
     //
 380  
     
 381  
     private boolean addNamespaceForElement(Element elt, String uri, String prefix, Map map)
 382  
     {
 383  341
         if (uri != null && uri.length() > 0 && (! map.containsKey(prefix))) {
 384  117
             map.put(prefix, new XPathNamespace(elt, uri, prefix));
 385  117
             return true;
 386  
         }
 387  224
         return false;
 388  
     }
 389  
     
 390  
     public Iterator getNamespaceAxisIterator(Object o)
 391  
     {
 392  102
         if (! isElement(o)) {
 393  59
             return JaxenConstants.EMPTY_ITERATOR;
 394  
         }
 395  43
         Map nsMap = new HashMap();
 396  43
         Element elt = (Element)o;
 397  43
         ParentNode parent = elt;
 398  
         
 399  155
         while (parent instanceof Element) {
 400  112
             elt = (Element)parent;
 401  112
             String uri    = elt.getNamespaceURI();
 402  112
             String prefix = elt.getNamespacePrefix();
 403  112
             addNamespaceForElement(elt, uri, prefix, nsMap);
 404  112
             int count = elt.getNamespaceDeclarationCount();
 405  298
             for (int i = 0; i < count; i++) {
 406  186
                 prefix = elt.getNamespacePrefix(i);
 407  186
                 uri    = elt.getNamespaceURI(prefix);
 408  186
                 addNamespaceForElement(elt, uri, prefix, nsMap);
 409  
             }
 410  112
             parent = elt.getParent();
 411  
         }
 412  43
         addNamespaceForElement(elt, "http://www.w3.org/XML/1998/namespace", "xml", nsMap);
 413  
 
 414  43
         return nsMap.values().iterator();
 415  
     }
 416  
 }