Clover coverage report - dom4j - 1.6.1
Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00
file stats: LOC: 412   Methods: 28
NCLOC: 154   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DocumentHelper.java 95% 75,4% 50% 72,6%
coverage coverage
 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;
 9   
 10    import java.io.StringReader;
 11    import java.util.List;
 12    import java.util.Map;
 13    import java.util.StringTokenizer;
 14   
 15    import org.dom4j.io.SAXReader;
 16    import org.dom4j.rule.Pattern;
 17   
 18    import org.jaxen.VariableContext;
 19   
 20    import org.xml.sax.InputSource;
 21   
 22    /**
 23    * <p>
 24    * <code>DocumentHelper</code> is a collection of helper methods for using
 25    * DOM4J.
 26    * </p>
 27    *
 28    * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
 29    * @version $Revision: 1.26 $
 30    */
 31    public final class DocumentHelper {
 32  0 private DocumentHelper() {
 33    }
 34   
 35  12496 private static DocumentFactory getDocumentFactory() {
 36  12496 return DocumentFactory.getInstance();
 37    }
 38   
 39    // Static helper methods
 40  412 public static Document createDocument() {
 41  412 return getDocumentFactory().createDocument();
 42    }
 43   
 44  2 public static Document createDocument(Element rootElement) {
 45  2 return getDocumentFactory().createDocument(rootElement);
 46    }
 47   
 48  2000 public static Element createElement(QName qname) {
 49  2000 return getDocumentFactory().createElement(qname);
 50    }
 51   
 52  4 public static Element createElement(String name) {
 53  4 return getDocumentFactory().createElement(name);
 54    }
 55   
 56  0 public static Attribute createAttribute(Element owner, QName qname,
 57    String value) {
 58  0 return getDocumentFactory().createAttribute(owner, qname, value);
 59    }
 60   
 61  0 public static Attribute createAttribute(Element owner, String name,
 62    String value) {
 63  0 return getDocumentFactory().createAttribute(owner, name, value);
 64    }
 65   
 66  0 public static CDATA createCDATA(String text) {
 67  0 return DocumentFactory.getInstance().createCDATA(text);
 68    }
 69   
 70  0 public static Comment createComment(String text) {
 71  0 return DocumentFactory.getInstance().createComment(text);
 72    }
 73   
 74  0 public static Text createText(String text) {
 75  0 return DocumentFactory.getInstance().createText(text);
 76    }
 77   
 78  0 public static Entity createEntity(String name, String text) {
 79  0 return DocumentFactory.getInstance().createEntity(name, text);
 80    }
 81   
 82  0 public static Namespace createNamespace(String prefix, String uri) {
 83  0 return DocumentFactory.getInstance().createNamespace(prefix, uri);
 84    }
 85   
 86  2 public static ProcessingInstruction createProcessingInstruction(String pi,
 87    String d) {
 88  2 return getDocumentFactory().createProcessingInstruction(pi, d);
 89    }
 90   
 91  0 public static ProcessingInstruction createProcessingInstruction(String pi,
 92    Map data) {
 93  0 return getDocumentFactory().createProcessingInstruction(pi, data);
 94    }
 95   
 96  0 public static QName createQName(String localName, Namespace namespace) {
 97  0 return getDocumentFactory().createQName(localName, namespace);
 98    }
 99   
 100  10000 public static QName createQName(String localName) {
 101  10000 return getDocumentFactory().createQName(localName);
 102    }
 103   
 104    /**
 105    * <p>
 106    * <code>createXPath</code> parses an XPath expression and creates a new
 107    * XPath <code>XPath</code> instance using the singleton {@link
 108    * DocumentFactory}.
 109    * </p>
 110    *
 111    * @param xpathExpression
 112    * is the XPath expression to create
 113    *
 114    * @return a new <code>XPath</code> instance
 115    *
 116    * @throws InvalidXPathException
 117    * if the XPath expression is invalid
 118    */
 119  57 public static XPath createXPath(String xpathExpression)
 120    throws InvalidXPathException {
 121  57 return getDocumentFactory().createXPath(xpathExpression);
 122    }
 123   
 124    /**
 125    * <p>
 126    * <code>createXPath</code> parses an XPath expression and creates a new
 127    * XPath <code>XPath</code> instance using the singleton {@link
 128    * DocumentFactory}.
 129    * </p>
 130    *
 131    * @param xpathExpression
 132    * is the XPath expression to create
 133    * @param context
 134    * is the variable context to use when evaluating the XPath
 135    *
 136    * @return a new <code>XPath</code> instance
 137    *
 138    * @throws InvalidXPathException
 139    * if the XPath expression is invalid
 140    */
 141  1 public static XPath createXPath(String xpathExpression,
 142    VariableContext context) throws InvalidXPathException {
 143  1 return getDocumentFactory().createXPath(xpathExpression, context);
 144    }
 145   
 146    /**
 147    * <p>
 148    * <code>createXPathFilter</code> parses a NodeFilter from the given XPath
 149    * filter expression using the singleton {@link DocumentFactory}. XPath
 150    * filter expressions occur within XPath expressions such as
 151    * <code>self::node()[ filterExpression ]</code>
 152    * </p>
 153    *
 154    * @param xpathFilterExpression
 155    * is the XPath filter expression to create
 156    *
 157    * @return a new <code>NodeFilter</code> instance
 158    */
 159  4 public static NodeFilter createXPathFilter(String xpathFilterExpression) {
 160  4 return getDocumentFactory().createXPathFilter(xpathFilterExpression);
 161    }
 162   
 163    /**
 164    * <p>
 165    * <code>createPattern</code> parses the given XPath expression to create
 166    * an XSLT style {@link Pattern}instance which can then be used in an XSLT
 167    * processing model.
 168    * </p>
 169    *
 170    * @param xpathPattern
 171    * is the XPath pattern expression to create
 172    *
 173    * @return a new <code>Pattern</code> instance
 174    */
 175  14 public static Pattern createPattern(String xpathPattern) {
 176  14 return getDocumentFactory().createPattern(xpathPattern);
 177    }
 178   
 179    /**
 180    * <p>
 181    * <code>selectNodes</code> performs the given XPath expression on the
 182    * {@link List}of {@link Node}instances appending all the results together
 183    * into a single list.
 184    * </p>
 185    *
 186    * @param xpathFilterExpression
 187    * is the XPath filter expression to evaluate
 188    * @param nodes
 189    * is the list of nodes on which to evalute the XPath
 190    *
 191    * @return the results of all the XPath evaluations as a single list
 192    */
 193  0 public static List selectNodes(String xpathFilterExpression, List nodes) {
 194  0 XPath xpath = createXPath(xpathFilterExpression);
 195   
 196  0 return xpath.selectNodes(nodes);
 197    }
 198   
 199    /**
 200    * <p>
 201    * <code>selectNodes</code> performs the given XPath expression on the
 202    * {@link List}of {@link Node}instances appending all the results together
 203    * into a single list.
 204    * </p>
 205    *
 206    * @param xpathFilterExpression
 207    * is the XPath filter expression to evaluate
 208    * @param node
 209    * is the Node on which to evalute the XPath
 210    *
 211    * @return the results of all the XPath evaluations as a single list
 212    */
 213  0 public static List selectNodes(String xpathFilterExpression, Node node) {
 214  0 XPath xpath = createXPath(xpathFilterExpression);
 215   
 216  0 return xpath.selectNodes(node);
 217    }
 218   
 219    /**
 220    * <p>
 221    * <code>sort</code> sorts the given List of Nodes using an XPath
 222    * expression as a {@link java.util.Comparator}.
 223    * </p>
 224    *
 225    * @param list
 226    * is the list of Nodes to sort
 227    * @param xpathExpression
 228    * is the XPath expression used for comparison
 229    */
 230  0 public static void sort(List list, String xpathExpression) {
 231  0 XPath xpath = createXPath(xpathExpression);
 232  0 xpath.sort(list);
 233    }
 234   
 235    /**
 236    * <p>
 237    * <code>sort</code> sorts the given List of Nodes using an XPath
 238    * expression as a {@link java.util.Comparator}and optionally removing
 239    * duplicates.
 240    * </p>
 241    *
 242    * @param list
 243    * is the list of Nodes to sort
 244    * @param expression
 245    * is the XPath expression used for comparison
 246    * @param distinct
 247    * if true then duplicate values (using the sortXPath for
 248    * comparisions) will be removed from the List
 249    */
 250  0 public static void sort(List list, String expression, boolean distinct) {
 251  0 XPath xpath = createXPath(expression);
 252  0 xpath.sort(list, distinct);
 253    }
 254   
 255    /**
 256    * <p>
 257    * <code>parseText</code> parses the given text as an XML document and
 258    * returns the newly created Document.
 259    * </p>
 260    *
 261    * @param text
 262    * the XML text to be parsed
 263    *
 264    * @return a newly parsed Document
 265    *
 266    * @throws DocumentException
 267    * if the document could not be parsed
 268    */
 269  5552 public static Document parseText(String text) throws DocumentException {
 270  5552 Document result = null;
 271   
 272  5552 SAXReader reader = new SAXReader();
 273  5552 String encoding = getEncoding(text);
 274   
 275  5552 InputSource source = new InputSource(new StringReader(text));
 276  5552 source.setEncoding(encoding);
 277   
 278  5552 result = reader.read(source);
 279   
 280    // if the XML parser doesn't provide a way to retrieve the encoding,
 281    // specify it manually
 282  5552 if (result.getXMLEncoding() == null) {
 283  5528 result.setXMLEncoding(encoding);
 284    }
 285   
 286  5552 return result;
 287    }
 288   
 289  5552 private static String getEncoding(String text) {
 290  5552 String result = null;
 291   
 292  5552 String xml = text.trim();
 293   
 294  5552 if (xml.startsWith("<?xml")) {
 295  25 int end = xml.indexOf("?>");
 296  25 String sub = xml.substring(0, end);
 297  25 StringTokenizer tokens = new StringTokenizer(sub, " =\"\'");
 298   
 299  25 while (tokens.hasMoreTokens()) {
 300  99 String token = tokens.nextToken();
 301   
 302  99 if ("encoding".equals(token)) {
 303  24 if (tokens.hasMoreTokens()) {
 304  24 result = tokens.nextToken();
 305    }
 306   
 307  24 break;
 308    }
 309    }
 310    }
 311   
 312  5552 return result;
 313    }
 314   
 315    /**
 316    * <p>
 317    * makeElement
 318    * </p>
 319    * a helper method which navigates from the given Document or Element node
 320    * to some Element using the path expression, creating any necessary
 321    * elements along the way. For example the path <code>a/b/c</code> would
 322    * get the first child &lt;a&gt; element, which would be created if it did
 323    * not exist, then the next child &lt;b&gt; and so on until finally a
 324    * &lt;c&gt; element is returned.
 325    *
 326    * @param source
 327    * is the Element or Document to start navigating from
 328    * @param path
 329    * is a simple path expression, seperated by '/' which denotes
 330    * the path from the source to the resulting element such as
 331    * a/b/c
 332    *
 333    * @return the first Element on the given path which either already existed
 334    * on the path or were created by this method.
 335    */
 336  6 public static Element makeElement(Branch source, String path) {
 337  6 StringTokenizer tokens = new StringTokenizer(path, "/");
 338  6 Element parent;
 339   
 340  6 if (source instanceof Document) {
 341  4 Document document = (Document) source;
 342  4 parent = document.getRootElement();
 343   
 344    // lets throw a NoSuchElementException
 345    // if we are given an empty path
 346  4 String name = tokens.nextToken();
 347   
 348  4 if (parent == null) {
 349  1 parent = document.addElement(name);
 350    }
 351    } else {
 352  2 parent = (Element) source;
 353    }
 354   
 355  6 Element element = null;
 356   
 357  6 while (tokens.hasMoreTokens()) {
 358  14 String name = tokens.nextToken();
 359   
 360  14 if (name.indexOf(':') > 0) {
 361  4 element = parent.element(parent.getQName(name));
 362    } else {
 363  10 element = parent.element(name);
 364    }
 365   
 366  14 if (element == null) {
 367  6 element = parent.addElement(name);
 368    }
 369   
 370  14 parent = element;
 371    }
 372   
 373  6 return element;
 374    }
 375    }
 376   
 377    /*
 378    * Redistribution and use of this software and associated documentation
 379    * ("Software"), with or without modification, are permitted provided that the
 380    * following conditions are met:
 381    *
 382    * 1. Redistributions of source code must retain copyright statements and
 383    * notices. Redistributions must also contain a copy of this document.
 384    *
 385    * 2. Redistributions in binary form must reproduce the above copyright notice,
 386    * this list of conditions and the following disclaimer in the documentation
 387    * and/or other materials provided with the distribution.
 388    *
 389    * 3. The name "DOM4J" must not be used to endorse or promote products derived
 390    * from this Software without prior written permission of MetaStuff, Ltd. For
 391    * written permission, please contact dom4j-info@metastuff.com.
 392    *
 393    * 4. Products derived from this Software may not be called "DOM4J" nor may
 394    * "DOM4J" appear in their names without prior written permission of MetaStuff,
 395    * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
 396    *
 397    * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
 398    *
 399    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
 400    * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 401    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 402    * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
 403    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 404    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 405    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 406    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 407    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 408    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 409    * POSSIBILITY OF SUCH DAMAGE.
 410    *
 411    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 412    */