Clover coverage report - dom4j - 1.5
Coverage timestamp: vr sep 3 2004 20:47:03 GMT+01:00
file stats: LOC: 387   Methods: 35
NCLOC: 179   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DocumentFactory.java 75% 84,4% 88,6% 85%
coverage coverage
 1    /*
 2    * Copyright 2001-2004 (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    * $Id: DocumentFactory.java,v 1.40 2004/07/11 10:49:36 maartenc Exp $
 8    */
 9   
 10    package org.dom4j;
 11   
 12    import java.io.IOException;
 13    import java.io.ObjectInputStream;
 14    import java.io.Serializable;
 15    import java.util.List;
 16    import java.util.Map;
 17   
 18    import org.dom4j.rule.Pattern;
 19    import org.dom4j.tree.DefaultAttribute;
 20    import org.dom4j.tree.DefaultCDATA;
 21    import org.dom4j.tree.DefaultComment;
 22    import org.dom4j.tree.DefaultDocument;
 23    import org.dom4j.tree.DefaultDocumentType;
 24    import org.dom4j.tree.DefaultElement;
 25    import org.dom4j.tree.DefaultEntity;
 26    import org.dom4j.tree.DefaultProcessingInstruction;
 27    import org.dom4j.tree.DefaultText;
 28    import org.dom4j.tree.QNameCache;
 29    import org.dom4j.xpath.DefaultXPath;
 30    import org.dom4j.xpath.XPathPattern;
 31    import org.jaxen.VariableContext;
 32   
 33    /** <p><code>DocumentFactory</code> is a collection of factory methods to allow
 34    * easy custom building of DOM4J trees. The default tree that is built uses
 35    * a doubly linked tree. </p>
 36    *
 37    * <p>The tree built allows full XPath expressions from anywhere on the
 38    * tree.</p>
 39    *
 40    * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
 41    * @version $Revision: 1.40 $
 42    */
 43    public class DocumentFactory implements Serializable {
 44   
 45    /** The Singleton instance */
 46    //private static transient DocumentFactory singleton;
 47    private final static ThreadLocal singlePerThread=new ThreadLocal();
 48    private static String documentFactoryClassName=null;
 49   
 50    protected transient QNameCache cache;
 51   
 52    /** Default namespace prefix -> URI mappings for XPath expressions to use */
 53    private Map xpathNamespaceURIs;
 54   
 55    static {
 56  170 try {
 57  170 documentFactoryClassName = System.getProperty(
 58    "org.dom4j.factory",
 59    "org.dom4j.DocumentFactory"
 60    );
 61    }
 62    catch (Exception e) {
 63  0 documentFactoryClassName = "org.dom4j.DocumentFactory";
 64    }
 65  170 getInstance(); //create first one
 66    }
 67   
 68    /** <p>Access to singleton implementation of DocumentFactory which
 69    * is used if no DocumentFactory is specified when building using the
 70    * standard builders.</p>
 71    *
 72    * @return the default singleon instance
 73    */
 74  53060 public static DocumentFactory getInstance() {
 75  53060 DocumentFactory fact = (DocumentFactory)singlePerThread.get();
 76  53060 if (fact==null) {
 77  188 fact=createSingleton( documentFactoryClassName ); //create first instance
 78  188 singlePerThread.set(fact);
 79    }
 80  53060 return fact;
 81    }
 82   
 83  1098 public DocumentFactory() {
 84  1098 init();
 85    }
 86   
 87   
 88    // Factory methods
 89   
 90  11986 public Document createDocument() {
 91  11986 DefaultDocument answer = new DefaultDocument();
 92  11986 answer.setDocumentFactory( this );
 93  11986 return answer;
 94    }
 95   
 96    /**
 97    * @since 1.5
 98    */
 99  11602 public Document createDocument(String encoding) {
 100    // to keep the DocumentFactory backwards compatible, we have to do this
 101    // in this not so nice way, since subclasses only need to extend the
 102    // createDocument() method.
 103  11602 Document answer = createDocument();
 104  11602 if (answer instanceof DefaultDocument) {
 105  11602 ((DefaultDocument) answer).setXMLEncoding(encoding);
 106    }
 107  11602 return answer;
 108    }
 109   
 110  2 public Document createDocument(Element rootElement) {
 111  2 Document answer = createDocument();
 112  2 answer.setRootElement(rootElement);
 113  2 return answer;
 114    }
 115   
 116  22 public DocumentType createDocType(String name, String publicId, String systemId) {
 117  22 return new DefaultDocumentType( name, publicId, systemId );
 118    }
 119   
 120  181638 public Element createElement(QName qname) {
 121  181638 return new DefaultElement(qname);
 122    }
 123   
 124  392 public Element createElement(String name) {
 125  392 return createElement(createQName(name));
 126    }
 127   
 128  8 public Element createElement(String qualifiedName, String namespaceURI) {
 129  8 return createElement(createQName(qualifiedName, namespaceURI));
 130    }
 131   
 132  23922 public Attribute createAttribute(Element owner, QName qname, String value) {
 133  23922 return new DefaultAttribute(qname, value);
 134    }
 135   
 136  1188 public Attribute createAttribute(Element owner, String name, String value) {
 137  1188 return createAttribute(owner, createQName(name), value);
 138    }
 139   
 140  170 public CDATA createCDATA(String text) {
 141  170 return new DefaultCDATA(text);
 142    }
 143   
 144  944 public Comment createComment(String text) {
 145  944 return new DefaultComment(text);
 146    }
 147   
 148  212538 public Text createText(String text) {
 149  212538 if ( text == null ) {
 150  0 throw new IllegalArgumentException( "Adding text to an XML document must not be null" );
 151    }
 152  212538 return new DefaultText(text);
 153    }
 154   
 155   
 156  8 public Entity createEntity(String name, String text) {
 157  8 return new DefaultEntity(name, text);
 158    }
 159   
 160  196356 public Namespace createNamespace(String prefix, String uri) {
 161  196356 return Namespace.get(prefix, uri);
 162    }
 163   
 164  30 public ProcessingInstruction createProcessingInstruction(String target, String data) {
 165  30 return new DefaultProcessingInstruction(target, data);
 166    }
 167   
 168  0 public ProcessingInstruction createProcessingInstruction(String target, Map data) {
 169  0 return new DefaultProcessingInstruction(target, data);
 170    }
 171   
 172  201910 public QName createQName(String localName, Namespace namespace) {
 173  201910 return cache.get(localName, namespace);
 174    }
 175   
 176  22910 public QName createQName(String localName) {
 177  22910 return cache.get(localName);
 178    }
 179   
 180  32 public QName createQName(String name, String prefix, String uri) {
 181  32 return cache.get(name, Namespace.get( prefix, uri ));
 182    }
 183   
 184  28 public QName createQName(String qualifiedName, String uri) {
 185  28 return cache.get(qualifiedName, uri);
 186    }
 187   
 188    /** <p><code>createXPath</code> parses an XPath expression
 189    * and creates a new XPath <code>XPath</code> instance.</p>
 190    *
 191    * @param xpathExpression is the XPath expression to create
 192    * @return a new <code>XPath</code> instance
 193    * @throws InvalidXPathException if the XPath expression is invalid
 194    */
 195  1612 public XPath createXPath(String xpathExpression) throws InvalidXPathException {
 196  1612 DefaultXPath xpath = new DefaultXPath( xpathExpression );
 197  1604 if ( xpathNamespaceURIs != null ) {
 198  6 xpath.setNamespaceURIs( xpathNamespaceURIs );
 199    }
 200  1604 return xpath;
 201    }
 202   
 203    /** <p><code>createXPath</code> parses an XPath expression
 204    * and creates a new XPath <code>XPath</code> instance.</p>
 205    *
 206    * @param xpathExpression is the XPath expression to create
 207    * @param variableContext is the variable context to use when evaluating the XPath
 208    * @return a new <code>XPath</code> instance
 209    * @throws InvalidXPathException if the XPath expression is invalid
 210    */
 211  12 public XPath createXPath(String xpathExpression, VariableContext variableContext) {
 212  12 XPath xpath = createXPath( xpathExpression );
 213  12 xpath.setVariableContext( variableContext );
 214  12 return xpath;
 215    }
 216   
 217    /** <p><code>createXPathFilter</code> parses a NodeFilter
 218    * from the given XPath filter expression.
 219    * XPath filter expressions occur within XPath expressions such as
 220    * <code>self::node()[ filterExpression ]</code></p>
 221    *
 222    * @param xpathFilterExpression is the XPath filter expression
 223    * to create
 224    * @param variableContext is the variable context to use when evaluating the XPath
 225    * @return a new <code>NodeFilter</code> instance
 226    */
 227  0 public NodeFilter createXPathFilter(String xpathFilterExpression, VariableContext variableContext) {
 228  0 XPath answer = createXPath( xpathFilterExpression );
 229    //DefaultXPath answer = new DefaultXPath( xpathFilterExpression );
 230  0 answer.setVariableContext( variableContext );
 231  0 return answer;
 232    }
 233   
 234    /** <p><code>createXPathFilter</code> parses a NodeFilter
 235    * from the given XPath filter expression.
 236    * XPath filter expressions occur within XPath expressions such as
 237    * <code>self::node()[ filterExpression ]</code></p>
 238    *
 239    * @param xpathFilterExpression is the XPath filter expression
 240    * to create
 241    * @return a new <code>NodeFilter</code> instance
 242    */
 243  44 public NodeFilter createXPathFilter(String xpathFilterExpression) {
 244  44 return createXPath( xpathFilterExpression );
 245    //return new DefaultXPath( xpathFilterExpression );
 246    }
 247   
 248    /** <p><code>createPattern</code> parses the given
 249    * XPath expression to create an XSLT style {@link Pattern} instance
 250    * which can then be used in an XSLT processing model.</p>
 251    *
 252    * @param xpathPattern is the XPath pattern expression
 253    * to create
 254    * @return a new <code>Pattern</code> instance
 255    */
 256  72 public Pattern createPattern(String xpathPattern) {
 257  72 return new XPathPattern( xpathPattern );
 258    }
 259   
 260   
 261    // Properties
 262    //-------------------------------------------------------------------------
 263   
 264    /** Returns a list of all the QName instances currently used by this document factory
 265    */
 266  2 public List getQNames() {
 267  2 return cache.getQNames();
 268    }
 269   
 270    /** @return the Map of namespace URIs that will be used by by XPath expressions
 271    * to resolve namespace prefixes into namespace URIs. The map is keyed by
 272    * namespace prefix and the value is the namespace URI. This value could well be
 273    * null to indicate no namespace URIs are being mapped.
 274    */
 275  0 public Map getXPathNamespaceURIs() {
 276  0 return xpathNamespaceURIs;
 277    }
 278   
 279    /** Sets the namespace URIs to be used by XPath expressions created by this factory
 280    * or by nodes associated with this factory. The keys are namespace prefixes and the
 281    * values are namespace URIs.
 282    */
 283  4 public void setXPathNamespaceURIs(Map xpathNamespaceURIs) {
 284  4 this.xpathNamespaceURIs = xpathNamespaceURIs;
 285    }
 286   
 287    // Implementation methods
 288    //-------------------------------------------------------------------------
 289   
 290   
 291    /** <p><code>createSingleton</code> creates the singleton instance
 292    * from the given class name.</p>
 293    *
 294    * @param className is the name of the DocumentFactory class to use
 295    * @return a new singleton instance.
 296    */
 297  188 protected static DocumentFactory createSingleton(String className) {
 298    // let's try and class load an implementation?
 299  188 try {
 300    // I'll use the current class loader
 301    // that loaded me to avoid problems in J2EE and web apps
 302  188 Class theClass = Class.forName(
 303    className,
 304    true,
 305    DocumentFactory.class.getClassLoader()
 306    );
 307  188 return (DocumentFactory) theClass.newInstance();
 308    }
 309    catch (Throwable e) {
 310  0 System.out.println( "WARNING: Cannot load DocumentFactory: " + className );
 311  0 return new DocumentFactory();
 312    }
 313    }
 314   
 315    /** @return the cached QName instance if there is one or adds the given
 316    * qname to the cache if not
 317    */
 318  0 protected QName intern(QName qname) {
 319  0 return cache.intern(qname);
 320    }
 321   
 322    /** Factory method to create the QNameCache. This method should be overloaded
 323    * if you wish to use your own derivation of QName.
 324    */
 325  1104 protected QNameCache createQNameCache() {
 326  1104 return new QNameCache(this);
 327    }
 328   
 329   
 330   
 331  6 private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
 332  6 in.defaultReadObject();
 333  6 init();
 334    }
 335   
 336  1104 protected void init() {
 337  1104 cache = createQNameCache();
 338    }
 339    }
 340   
 341   
 342   
 343   
 344    /*
 345    * Redistribution and use of this software and associated documentation
 346    * ("Software"), with or without modification, are permitted provided
 347    * that the following conditions are met:
 348    *
 349    * 1. Redistributions of source code must retain copyright
 350    * statements and notices. Redistributions must also contain a
 351    * copy of this document.
 352    *
 353    * 2. Redistributions in binary form must reproduce the
 354    * above copyright notice, this list of conditions and the
 355    * following disclaimer in the documentation and/or other
 356    * materials provided with the distribution.
 357    *
 358    * 3. The name "DOM4J" must not be used to endorse or promote
 359    * products derived from this Software without prior written
 360    * permission of MetaStuff, Ltd. For written permission,
 361    * please contact dom4j-info@metastuff.com.
 362    *
 363    * 4. Products derived from this Software may not be called "DOM4J"
 364    * nor may "DOM4J" appear in their names without prior written
 365    * permission of MetaStuff, Ltd. DOM4J is a registered
 366    * trademark of MetaStuff, Ltd.
 367    *
 368    * 5. Due credit should be given to the DOM4J Project -
 369    * http://www.dom4j.org
 370    *
 371    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
 372    * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 373    * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 374    * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 375    * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 376    * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 377    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 378    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 379    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 380    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 381    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 382    * OF THE POSSIBILITY OF SUCH DAMAGE.
 383    *
 384    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 385    *
 386    * $Id: DocumentFactory.java,v 1.40 2004/07/11 10:49:36 maartenc Exp $
 387    */