Clover coverage report - dom4j - 1.6.1
Coverage timestamp: ma mei 16 2005 14:23:01 GMT+01:00
file stats: LOC: 402   Methods: 21
NCLOC: 254   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
DOMWriter.java 69,2% 65,6% 71,4% 67,2%
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.io;
 9   
 10    import java.util.List;
 11   
 12    import org.dom4j.Attribute;
 13    import org.dom4j.CDATA;
 14    import org.dom4j.Comment;
 15    import org.dom4j.Document;
 16    import org.dom4j.DocumentException;
 17    import org.dom4j.Element;
 18    import org.dom4j.Entity;
 19    import org.dom4j.Namespace;
 20    import org.dom4j.ProcessingInstruction;
 21    import org.dom4j.Text;
 22    import org.dom4j.tree.NamespaceStack;
 23   
 24    import org.w3c.dom.DOMImplementation;
 25   
 26    /**
 27    * <p>
 28    * <code>DOMWriter</code> takes a DOM4J tree and outputs it as a W3C DOM
 29    * object
 30    * </p>
 31    *
 32    * @author <a href="mailto:james.strachan@metastuff.com">James Strachan </a>
 33    * @version $Revision: 1.17 $
 34    */
 35    public class DOMWriter {
 36    private static boolean loggedWarning = false;
 37   
 38    private static final String[] DEFAULT_DOM_DOCUMENT_CLASSES = {
 39    "org.apache.xerces.dom.DocumentImpl", // Xerces
 40    "gnu.xml.dom.DomDocument", // GNU JAXP
 41    "org.apache.crimson.tree.XmlDocument", // Crimson
 42    "com.sun.xml.tree.XmlDocument", // Sun's Project X
 43    "oracle.xml.parser.v2.XMLDocument", // Oracle V2
 44    "oracle.xml.parser.XMLDocument", // Oracle V1
 45    "org.dom4j.dom.DOMDocument" // Internal DOM implementation
 46    };
 47   
 48    // the Class used to create new DOM Document instances
 49    private Class domDocumentClass;
 50   
 51    /** stack of <code>Namespace</code> objects */
 52    private NamespaceStack namespaceStack = new NamespaceStack();
 53   
 54  14 public DOMWriter() {
 55    }
 56   
 57  2 public DOMWriter(Class domDocumentClass) {
 58  2 this.domDocumentClass = domDocumentClass;
 59    }
 60   
 61  0 public Class getDomDocumentClass() throws DocumentException {
 62  0 Class result = domDocumentClass;
 63   
 64  0 if (result == null) {
 65    // lets try and find one in the classpath
 66  0 int size = DEFAULT_DOM_DOCUMENT_CLASSES.length;
 67   
 68  0 for (int i = 0; i < size; i++) {
 69  0 try {
 70  0 String name = DEFAULT_DOM_DOCUMENT_CLASSES[i];
 71  0 result = Class.forName(name, true, DOMWriter.class
 72    .getClassLoader());
 73   
 74  0 if (result != null) {
 75  0 break;
 76    }
 77    } catch (Exception e) {
 78    // could not load class correctly
 79    // lets carry on to the next one
 80    }
 81    }
 82    }
 83   
 84  0 return result;
 85    }
 86   
 87    /**
 88    * Sets the DOM {@link org.w3c.dom.Document}implementation class used by
 89    * the writer when creating DOM documents.
 90    *
 91    * @param domDocumentClass
 92    * is the Class implementing the {@linkorg.w3c.dom.Document}
 93    * interface
 94    */
 95  0 public void setDomDocumentClass(Class domDocumentClass) {
 96  0 this.domDocumentClass = domDocumentClass;
 97    }
 98   
 99    /**
 100    * Sets the DOM {@link org.w3c.dom.Document}implementation class name used
 101    * by the writer when creating DOM documents.
 102    *
 103    * @param name
 104    * is the name of the Class implementing the {@link
 105    * org.w3c.dom.Document} interface
 106    *
 107    * @throws DocumentException
 108    * if the class could not be loaded
 109    */
 110  0 public void setDomDocumentClassName(String name) throws DocumentException {
 111  0 try {
 112  0 this.domDocumentClass = Class.forName(name, true, DOMWriter.class
 113    .getClassLoader());
 114    } catch (Exception e) {
 115  0 throw new DocumentException("Could not load the DOM Document "
 116    + "class: " + name, e);
 117    }
 118    }
 119   
 120  16 public org.w3c.dom.Document write(Document document)
 121    throws DocumentException {
 122  16 if (document instanceof org.w3c.dom.Document) {
 123  1 return (org.w3c.dom.Document) document;
 124    }
 125   
 126  15 resetNamespaceStack();
 127   
 128  15 org.w3c.dom.Document domDocument = createDomDocument(document);
 129  15 appendDOMTree(domDocument, domDocument, document.content());
 130  15 namespaceStack.clear();
 131   
 132  15 return domDocument;
 133    }
 134   
 135  0 public org.w3c.dom.Document write(Document document,
 136    org.w3c.dom.DOMImplementation domImpl) throws DocumentException {
 137  0 if (document instanceof org.w3c.dom.Document) {
 138  0 return (org.w3c.dom.Document) document;
 139    }
 140   
 141  0 resetNamespaceStack();
 142   
 143  0 org.w3c.dom.Document domDocument = createDomDocument(document, domImpl);
 144  0 appendDOMTree(domDocument, domDocument, document.content());
 145  0 namespaceStack.clear();
 146   
 147  0 return domDocument;
 148    }
 149   
 150  4838 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 151    org.w3c.dom.Node domCurrent, List content) {
 152  4838 int size = content.size();
 153   
 154  4838 for (int i = 0; i < size; i++) {
 155  13249 Object object = content.get(i);
 156   
 157  13249 if (object instanceof Element) {
 158  4823 appendDOMTree(domDocument, domCurrent, (Element) object);
 159  8426 } else if (object instanceof String) {
 160  0 appendDOMTree(domDocument, domCurrent, (String) object);
 161  8426 } else if (object instanceof Text) {
 162  8293 Text text = (Text) object;
 163  8293 appendDOMTree(domDocument, domCurrent, text.getText());
 164  133 } else if (object instanceof CDATA) {
 165  30 appendDOMTree(domDocument, domCurrent, (CDATA) object);
 166  103 } else if (object instanceof Comment) {
 167  68 appendDOMTree(domDocument, domCurrent, (Comment) object);
 168  35 } else if (object instanceof Entity) {
 169  0 appendDOMTree(domDocument, domCurrent, (Entity) object);
 170  35 } else if (object instanceof ProcessingInstruction) {
 171  2 appendDOMTree(domDocument, domCurrent,
 172    (ProcessingInstruction) object);
 173    }
 174    }
 175    }
 176   
 177  4823 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 178    org.w3c.dom.Node domCurrent, Element element) {
 179  4823 String elUri = element.getNamespaceURI();
 180  4823 String elName = element.getQualifiedName();
 181  4823 org.w3c.dom.Element domElement = domDocument.createElementNS(elUri,
 182    elName);
 183   
 184  4823 int stackSize = namespaceStack.size();
 185   
 186    // add the namespace of the element first
 187  4823 Namespace elementNamespace = element.getNamespace();
 188   
 189  4823 if (isNamespaceDeclaration(elementNamespace)) {
 190  27 namespaceStack.push(elementNamespace);
 191  27 writeNamespace(domElement, elementNamespace);
 192    }
 193   
 194    // add the additional declared namespaces
 195  4823 List declaredNamespaces = element.declaredNamespaces();
 196   
 197  4823 for (int i = 0, size = declaredNamespaces.size(); i < size; i++) {
 198  33 Namespace namespace = (Namespace) declaredNamespaces.get(i);
 199   
 200  33 if (isNamespaceDeclaration(namespace)) {
 201  6 namespaceStack.push(namespace);
 202  6 writeNamespace(domElement, namespace);
 203    }
 204    }
 205   
 206    // add the attributes
 207  4823 for (int i = 0, size = element.attributeCount(); i < size; i++) {
 208  2492 Attribute attribute = (Attribute) element.attribute(i);
 209  2492 String attUri = attribute.getNamespaceURI();
 210  2492 String attName = attribute.getQualifiedName();
 211  2492 String value = attribute.getValue();
 212  2492 domElement.setAttributeNS(attUri, attName, value);
 213    }
 214   
 215    // add content
 216  4823 appendDOMTree(domDocument, domElement, element.content());
 217   
 218  4823 domCurrent.appendChild(domElement);
 219   
 220  4823 while (namespaceStack.size() > stackSize) {
 221  33 namespaceStack.pop();
 222    }
 223    }
 224   
 225  30 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 226    org.w3c.dom.Node domCurrent, CDATA cdata) {
 227  30 org.w3c.dom.CDATASection domCDATA = domDocument
 228    .createCDATASection(cdata.getText());
 229  30 domCurrent.appendChild(domCDATA);
 230    }
 231   
 232  68 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 233    org.w3c.dom.Node domCurrent, Comment comment) {
 234  68 org.w3c.dom.Comment domComment = domDocument.createComment(comment
 235    .getText());
 236  68 domCurrent.appendChild(domComment);
 237    }
 238   
 239  8293 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 240    org.w3c.dom.Node domCurrent, String text) {
 241  8293 org.w3c.dom.Text domText = domDocument.createTextNode(text);
 242  8293 domCurrent.appendChild(domText);
 243    }
 244   
 245  0 protected void appendDOMTree(org.w3c.dom.Document domDocument,
 246    org.w3c.dom.Node domCurrent, Entity entity) {
 247  0 org.w3c.dom.EntityReference domEntity = domDocument
 248    .createEntityReference(entity.getName());
 249  0 domCurrent.appendChild(domEntity);
 250    }
 251   
 252  2 protected void appendDOMTree(org.w3c.dom.Document domDoc,
 253    org.w3c.dom.Node domCurrent, ProcessingInstruction pi) {
 254  2 org.w3c.dom.ProcessingInstruction domPI = domDoc
 255    .createProcessingInstruction(pi.getTarget(), pi.getText());
 256  2 domCurrent.appendChild(domPI);
 257    }
 258   
 259  33 protected void writeNamespace(org.w3c.dom.Element domElement,
 260    Namespace namespace) {
 261  33 String attributeName = attributeNameForNamespace(namespace);
 262   
 263    // domElement.setAttributeNS("", attributeName, namespace.getURI());
 264  33 domElement.setAttribute(attributeName, namespace.getURI());
 265    }
 266   
 267  33 protected String attributeNameForNamespace(Namespace namespace) {
 268  33 String xmlns = "xmlns";
 269  33 String prefix = namespace.getPrefix();
 270   
 271  33 if (prefix.length() > 0) {
 272  22 return xmlns + ":" + prefix;
 273    }
 274   
 275  11 return xmlns;
 276    }
 277   
 278  15 protected org.w3c.dom.Document createDomDocument(Document document)
 279    throws DocumentException {
 280  15 org.w3c.dom.Document result = null;
 281   
 282    // use the given domDocumentClass (if not null)
 283  15 if (domDocumentClass != null) {
 284  2 try {
 285  2 result = (org.w3c.dom.Document) domDocumentClass.newInstance();
 286    } catch (Exception e) {
 287  0 throw new DocumentException(
 288    "Could not instantiate an instance "
 289    + "of DOM Document with class: "
 290    + domDocumentClass.getName(), e);
 291    }
 292    } else {
 293    // lets try JAXP first before using the hardcoded default parsers
 294  13 result = createDomDocumentViaJAXP();
 295   
 296  13 if (result == null) {
 297  0 Class theClass = getDomDocumentClass();
 298   
 299  0 try {
 300  0 result = (org.w3c.dom.Document) theClass.newInstance();
 301    } catch (Exception e) {
 302  0 throw new DocumentException("Could not instantiate an "
 303    + "instance of DOM Document " + "with class: "
 304    + theClass.getName(), e);
 305    }
 306    }
 307    }
 308   
 309  15 return result;
 310    }
 311   
 312  13 protected org.w3c.dom.Document createDomDocumentViaJAXP()
 313    throws DocumentException {
 314  13 try {
 315  13 return JAXPHelper.createDocument(false, true);
 316    } catch (Throwable e) {
 317  0 if (!loggedWarning) {
 318  0 loggedWarning = true;
 319   
 320  0 if (SAXHelper.isVerboseErrorReporting()) {
 321    // log all exceptions as warnings and carry
 322    // on as we have a default SAX parser we can use
 323  0 System.out.println("Warning: Caught exception attempting "
 324    + "to use JAXP to create a W3C DOM " + "document");
 325  0 System.out.println("Warning: Exception was: " + e);
 326  0 e.printStackTrace();
 327    } else {
 328  0 System.out.println("Warning: Error occurred using JAXP to "
 329    + "create a DOM document.");
 330    }
 331    }
 332    }
 333   
 334  0 return null;
 335    }
 336   
 337  0 protected org.w3c.dom.Document createDomDocument(Document document,
 338    DOMImplementation domImpl) throws DocumentException {
 339  0 String namespaceURI = null;
 340  0 String qualifiedName = null;
 341  0 org.w3c.dom.DocumentType docType = null;
 342   
 343  0 return domImpl.createDocument(namespaceURI, qualifiedName, docType);
 344    }
 345   
 346  4856 protected boolean isNamespaceDeclaration(Namespace ns) {
 347  4856 if ((ns != null) && (ns != Namespace.NO_NAMESPACE)
 348    && (ns != Namespace.XML_NAMESPACE)) {
 349  172 String uri = ns.getURI();
 350   
 351  172 if ((uri != null) && (uri.length() > 0)) {
 352  172 if (!namespaceStack.contains(ns)) {
 353  33 return true;
 354    }
 355    }
 356    }
 357   
 358  4823 return false;
 359    }
 360   
 361  15 protected void resetNamespaceStack() {
 362  15 namespaceStack.clear();
 363  15 namespaceStack.push(Namespace.XML_NAMESPACE);
 364    }
 365    }
 366   
 367    /*
 368    * Redistribution and use of this software and associated documentation
 369    * ("Software"), with or without modification, are permitted provided that the
 370    * following conditions are met:
 371    *
 372    * 1. Redistributions of source code must retain copyright statements and
 373    * notices. Redistributions must also contain a copy of this document.
 374    *
 375    * 2. Redistributions in binary form must reproduce the above copyright notice,
 376    * this list of conditions and the following disclaimer in the documentation
 377    * and/or other materials provided with the distribution.
 378    *
 379    * 3. The name "DOM4J" must not be used to endorse or promote products derived
 380    * from this Software without prior written permission of MetaStuff, Ltd. For
 381    * written permission, please contact dom4j-info@metastuff.com.
 382    *
 383    * 4. Products derived from this Software may not be called "DOM4J" nor may
 384    * "DOM4J" appear in their names without prior written permission of MetaStuff,
 385    * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
 386    *
 387    * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
 388    *
 389    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
 390    * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 391    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 392    * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
 393    * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 394    * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 395    * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 396    * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 397    * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 398    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 399    * POSSIBILITY OF SUCH DAMAGE.
 400    *
 401    * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
 402    */