Clover coverage report - dom4j - 1.5
Coverage timestamp: vr sep 3 2004 20:47:03 GMT+01:00
file stats: LOC: 617   Methods: 42
NCLOC: 240   Classes: 3
 
 Source file Conditionals Statements Methods TOTAL
STAXEventWriter.java 75% 34% 38,1% 36,2%
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: STAXEventWriter.java,v 1.6 2004/07/14 19:32:23 maartenc Exp $
 8    */
 9   
 10    package org.dom4j.io;
 11   
 12    import java.io.File;
 13    import java.io.FileWriter;
 14    import java.io.IOException;
 15    import java.io.OutputStream;
 16    import java.io.StringWriter;
 17    import java.io.Writer;
 18    import java.util.Iterator;
 19   
 20    import javax.xml.namespace.QName;
 21    import javax.xml.stream.XMLEventFactory;
 22    import javax.xml.stream.XMLOutputFactory;
 23    import javax.xml.stream.XMLStreamException;
 24    import javax.xml.stream.events.Characters;
 25    import javax.xml.stream.events.DTD;
 26    import javax.xml.stream.events.EndDocument;
 27    import javax.xml.stream.events.EndElement;
 28    import javax.xml.stream.events.EntityReference;
 29    import javax.xml.stream.events.StartDocument;
 30    import javax.xml.stream.events.StartElement;
 31    import javax.xml.stream.util.XMLEventConsumer;
 32   
 33    import org.dom4j.Attribute;
 34    import org.dom4j.Branch;
 35    import org.dom4j.CDATA;
 36    import org.dom4j.Comment;
 37    import org.dom4j.Document;
 38    import org.dom4j.DocumentType;
 39    import org.dom4j.Element;
 40    import org.dom4j.Entity;
 41    import org.dom4j.Namespace;
 42    import org.dom4j.Node;
 43    import org.dom4j.ProcessingInstruction;
 44    import org.dom4j.Text;
 45   
 46    /**
 47    * Writes DOM4J {@link Node}s to a StAX event stream. In addition the
 48    * <code>createXXX</code> methods are provided to directly create STAX events
 49    * from DOM4J nodes.
 50    *
 51    * @author Christian Niles
 52    */
 53    public class STAXEventWriter {
 54   
 55    /** The event stream to which events are written. */
 56    private XMLEventConsumer consumer;
 57   
 58    /** The event factory used to construct events. */
 59    private XMLEventFactory factory = XMLEventFactory.newInstance();
 60   
 61    private XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
 62   
 63  0 public STAXEventWriter() {
 64    }
 65   
 66    /**
 67    * Constructs a <code>STAXEventWriter</code> that writes events to the
 68    * provided file.
 69    *
 70    * @param file The file to which events will be written.
 71    * @throws XMLStreamException If an error occurs creating an event writer from
 72    * the file.
 73    * @throws IOException If an error occurs openin the file for writing.
 74    */
 75  0 public STAXEventWriter(File file) throws XMLStreamException, IOException {
 76  0 consumer = outputFactory.createXMLEventWriter(new FileWriter(file));
 77    }
 78   
 79    /**
 80    * Constructs a <code>STAXEventWriter</code> that writes events to the
 81    * provided character stream.
 82    *
 83    * @param writer The character stream to which events will be written.
 84    * @throws XMLStreamException If an error occurs constructing an event writer
 85    * from the character stream.
 86    */
 87  2 public STAXEventWriter(Writer writer) throws XMLStreamException {
 88  2 consumer = outputFactory.createXMLEventWriter(writer);
 89    }
 90   
 91    /**
 92    * Constructs a <code>STAXEventWriter</code> that writes events to the
 93    * provided stream.
 94    *
 95    * @param stream The output stream to which events will be written.
 96    * @throws XMLStreamException If an error occurs constructing an event writer
 97    * from the stream.
 98    */
 99  0 public STAXEventWriter(OutputStream stream) throws XMLStreamException {
 100  0 consumer = outputFactory.createXMLEventWriter(stream);
 101    }
 102   
 103    /**
 104    * Constructs a <code>STAXEventWriter</code> that writes events to the
 105    * provided event stream.
 106    *
 107    * @param consumer The event stream to which events will be written.
 108    */
 109  0 public STAXEventWriter(XMLEventConsumer consumer) {
 110  0 this.consumer = consumer;
 111    }
 112   
 113    /**
 114    * Returns a reference to the underlying event consumer to which events are
 115    * written.
 116    *
 117    * @return The underlying event consumer to which events are written.
 118    */
 119  0 public XMLEventConsumer getConsumer() {
 120  0 return consumer;
 121    }
 122   
 123    /**
 124    * Sets the underlying event consumer to which events are written.
 125    *
 126    * @param consumer The event consumer to which events should be written.
 127    */
 128  0 public void setConsumer(XMLEventConsumer consumer) {
 129  0 this.consumer = consumer;
 130    }
 131   
 132    /**
 133    * Returns a reference to the event factory used to construct STAX events.
 134    *
 135    * @return The event factory used to construct STAX events.
 136    */
 137  0 public XMLEventFactory getEventFactory() {
 138  0 return factory;
 139    }
 140   
 141    /**
 142    * Sets the event factory used to construct STAX events.
 143    *
 144    * @param factory The new event factory.
 145    */
 146  0 public void setEventFactory(XMLEventFactory factory) {
 147  0 this.factory = factory;
 148    }
 149   
 150    /**
 151    * Writes a DOM4J {@link Node} to the stream. This method is simply a
 152    * gateway to the overloaded methods such as {@link #writeElement(Element)}.
 153    *
 154    * @param n The DOM4J {@link Node} to write to the stream.
 155    * @throws XMLStreamException If an error occurs writing to the stream.
 156    */
 157  48 public void writeNode(Node n) throws XMLStreamException {
 158  48 switch (n.getNodeType()) {
 159   
 160  16 case Node.ELEMENT_NODE :
 161  16 writeElement((Element) n);
 162  16 break;
 163   
 164  32 case Node.TEXT_NODE :
 165  32 writeText((Text) n);
 166  32 break;
 167   
 168  0 case Node.ATTRIBUTE_NODE :
 169  0 writeAttribute((Attribute) n);
 170  0 break;
 171   
 172  0 case Node.NAMESPACE_NODE :
 173  0 writeNamespace((Namespace) n);
 174  0 break;
 175   
 176  0 case Node.COMMENT_NODE :
 177  0 writeComment((Comment) n);
 178  0 break;
 179   
 180  0 case Node.CDATA_SECTION_NODE :
 181  0 writeCDATA((CDATA) n);
 182  0 break;
 183   
 184  0 case Node.PROCESSING_INSTRUCTION_NODE :
 185  0 writeProcessingInstruction((ProcessingInstruction) n);
 186  0 break;
 187   
 188  0 case Node.ENTITY_REFERENCE_NODE :
 189  0 writeEntity((Entity) n);
 190  0 break;
 191   
 192  0 case Node.DOCUMENT_NODE :
 193  0 writeDocument((Document) n);
 194  0 break;
 195   
 196  0 case Node.DOCUMENT_TYPE_NODE :
 197  0 writeDocumentType((DocumentType) n);
 198  0 break;
 199   
 200  0 default :
 201  0 throw new XMLStreamException("Unsupported DOM4J Node: " + n);
 202    }
 203    }
 204   
 205    /**
 206    * Writes each child node within the provided {@link Branch} instance. This
 207    * method simply iterates through the {@link Branch}'s nodes and calls
 208    * {@link #writeNode(Node)}.
 209    *
 210    * @param branch The node whose children will be written to the stream.
 211    * @throws XMLStreamException If an error occurs writing to the stream.
 212    */
 213  18 public void writeChildNodes(Branch branch) throws XMLStreamException {
 214  18 for (int i = 0, s = branch.nodeCount(); i < s; i++) {
 215  48 Node n = branch.node(i);
 216  48 writeNode(n);
 217    }
 218    }
 219   
 220    /**
 221    * Writes a DOM4J {@link Element} node and its children to the stream.
 222    *
 223    * @param elem The {@link Element} node to write to the stream.
 224    * @throws XMLStreamException If an error occurs writing to the stream.
 225    */
 226  16 public void writeElement(Element elem) throws XMLStreamException {
 227  16 consumer.add(createStartElement(elem));
 228  16 writeChildNodes(elem);
 229  16 consumer.add(createEndElement(elem));
 230    }
 231   
 232    /**
 233    * Constructs a STAX {@link StartElement} event from a DOM4J
 234    * {@link Element}.
 235    *
 236    * @param elem The {@link Element} from which to construct the event.
 237    * @return The newly constructed {@link StartElement} event.
 238    */
 239  16 public StartElement createStartElement(Element elem) {
 240   
 241    // create name
 242  16 QName tagName = createQName(elem.getQName());
 243   
 244    // create attribute & namespace iterators
 245  16 Iterator attrIter = new AttributeIterator(elem.attributeIterator());
 246  16 Iterator nsIter = new NamespaceIterator(
 247    elem.declaredNamespaces().iterator());
 248   
 249    // create start event
 250  16 return factory.createStartElement(tagName, attrIter, nsIter);
 251    }
 252   
 253    /**
 254    * Constructs a STAX {@link EndElement} event from a DOM4J {@link Element}.
 255    *
 256    * @param elem The {@link Element} from which to construct the event.
 257    * @return The newly constructed {@link EndElement} event.
 258    */
 259  16 public EndElement createEndElement(Element elem) {
 260  16 QName tagName = createQName(elem.getQName());
 261  16 Iterator nsIter = new NamespaceIterator(
 262    elem.declaredNamespaces().iterator());
 263   
 264  16 return factory.createEndElement(tagName, nsIter);
 265    }
 266   
 267    /**
 268    * Writes a DOM4J {@link Attribute} to the stream.
 269    *
 270    * @param attr The {@link Attribute} to write to the stream.
 271    * @throws XMLStreamException If an error occurs writing to the stream.
 272    */
 273  0 public void writeAttribute(Attribute attr) throws XMLStreamException {
 274  0 consumer.add(createAttribute(attr));
 275    }
 276   
 277    /**
 278    * Constructs a STAX {@link javax.xml.stream.events.Attribute} event from
 279    * a DOM4J {@link Attribute}.
 280    *
 281    * @param attr The {@link Attribute} from which to construct the event.
 282    * @return The newly constructed {@link javax.xml.stream.events.Attribute}
 283    * event.
 284    */
 285  0 public javax.xml.stream.events.Attribute createAttribute(Attribute attr) {
 286  0 QName attrName = createQName(attr.getQName());
 287  0 String value = attr.getValue();
 288   
 289  0 return factory.createAttribute(attrName, value);
 290    }
 291   
 292    /**
 293    * Writes a DOM4J {@link Namespace} to the stream.
 294    *
 295    * @param ns The {@link Namespace} to write to the stream.
 296    * @throws XMLStreamException If an error occurs writing to the stream.
 297    */
 298  0 public void writeNamespace(Namespace ns) throws XMLStreamException {
 299  0 consumer.add(createNamespace(ns));
 300    }
 301   
 302    /**
 303    * Constructs a STAX {@link javax.xml.stream.events.Namespace} event from
 304    * a DOM4J {@link Namespace}.
 305    *
 306    * @param ns The {@link Namespace} from which to construct the event.
 307    * @return The constructed {@link javax.xml.stream.events.Namespace} event.
 308    */
 309  0 public javax.xml.stream.events.Namespace createNamespace(Namespace ns) {
 310  0 String prefix = ns.getPrefix();
 311  0 String uri = ns.getURI();
 312   
 313  0 return factory.createNamespace(prefix, uri);
 314    }
 315   
 316    /**
 317    * Writes a DOM4J {@link Text} to the stream.
 318    *
 319    * @param text The {@link Text} to write to the stream.
 320    * @throws XMLStreamException If an error occurs writing to the stream.
 321    */
 322  32 public void writeText(Text text) throws XMLStreamException {
 323  32 consumer.add(createCharacters(text));
 324    }
 325   
 326    /**
 327    * Constructs a STAX {@link Characters} event from a DOM4J {@link Text}.
 328    *
 329    * @param text The {@link Text} from which to construct the event.
 330    * @return The constructed {@link Characters} event.
 331    */
 332  32 public Characters createCharacters(Text text) {
 333  32 return factory.createCharacters(text.getText());
 334    }
 335   
 336    /**
 337    * Writes a DOM4J {@link CDATA} to the event stream.
 338    *
 339    * @param cdata The {@link CDATA} to write to the stream.
 340    * @throws XMLStreamException If an error occurs writing to the stream.
 341    */
 342  0 public void writeCDATA(CDATA cdata) throws XMLStreamException {
 343  0 consumer.add(createCharacters(cdata));
 344    }
 345   
 346    /**
 347    * Constructs a STAX {@link Characters} event from a DOM4J {@link CDATA}.
 348    *
 349    * @param cdata The {@link CDATA} from which to construct the event.
 350    * @return The newly constructed {@link Characters} event.
 351    */
 352  0 public Characters createCharacters(CDATA cdata) {
 353  0 return factory.createCData(cdata.getText());
 354    }
 355   
 356    /**
 357    * Writes a DOM4J {@link Comment} to the stream.
 358    *
 359    * @param comment The {@link Comment} to write to the stream.
 360    * @throws XMLStreamException If an error occurs writing to the stream.
 361    */
 362  0 public void writeComment(Comment comment) throws XMLStreamException {
 363  0 consumer.add(createComment(comment));
 364    }
 365   
 366    /**
 367    * Constructs a STAX {@link javax.xml.stream.events.Comment} event from a
 368    * DOM4J {@link Comment}.
 369    *
 370    * @param comment The {@link Comment} from which to construct the event.
 371    * @return The constructed {@link javax.xml.stream.events.Comment} event.
 372    */
 373  0 public javax.xml.stream.events.Comment createComment(Comment comment) {
 374  0 return factory.createComment(comment.getText());
 375    }
 376   
 377    /**
 378    * Writes a DOM4J {@link ProcessingInstruction} to the stream.
 379    *
 380    * @param pi The {@link ProcessingInstruction} to write to the stream.
 381    * @throws XMLStreamException If an error occurs writing to the stream.
 382    */
 383  0 public void writeProcessingInstruction(ProcessingInstruction pi) throws XMLStreamException {
 384  0 consumer.add(createProcessingInstruction(pi));
 385    }
 386   
 387    /**
 388    * Constructs a STAX {@link javax.xml.stream.events.ProcessingInstruction}
 389    * event from a DOM4J {@link ProcessingInstruction}.
 390    *
 391    * @param pi The {@link ProcessingInstruction} from which to construct the
 392    * event.
 393    * @return The constructed
 394    * {@link javax.xml.stream.events.ProcessingInstruction} event.
 395    */
 396  0 public javax.xml.stream.events.ProcessingInstruction createProcessingInstruction(
 397    ProcessingInstruction pi) {
 398   
 399  0 String target = pi.getTarget();
 400  0 String data = pi.getText();
 401   
 402  0 return factory.createProcessingInstruction(target, data);
 403    }
 404   
 405    /**
 406    * Writes a DOM4J {@link Entity} to the stream.
 407    *
 408    * @param entity The {@link Entity} to write to the stream.
 409    * @throws XMLStreamException If an error occurs writing to the stream.
 410    */
 411  0 public void writeEntity(Entity entity) throws XMLStreamException {
 412  0 consumer.add(createEntityReference(entity));
 413    }
 414   
 415    /**
 416    * Constructs a STAX {@link EntityReference} event from a DOM4J
 417    * {@link Entity}.
 418    *
 419    * @param entity The {@link Entity} from which to construct the event.
 420    * @return The constructed {@link EntityReference} event.
 421    */
 422  0 private EntityReference createEntityReference(Entity entity) {
 423  0 return factory.createEntityReference(entity.getName(), null);
 424    }
 425   
 426    /**
 427    * Writes a DOM4J {@link DocumentType} to the stream.
 428    *
 429    * @param docType The {@link DocumentType} to write to the stream.
 430    * @throws XMLStreamException If an error occurs writing to the stream.
 431    */
 432  0 public void writeDocumentType(DocumentType docType) throws XMLStreamException {
 433  0 consumer.add(createDTD(docType));
 434    }
 435   
 436    /**
 437    * Constructs a STAX {@link DTD} event from a DOM4J {@link DocumentType}.
 438    *
 439    * @param docType The {@link DocumentType} from which to construct the
 440    * event.
 441    * @return The constructed {@link DTD} event.
 442    */
 443  0 public DTD createDTD(DocumentType docType) {
 444  0 StringWriter decl = new StringWriter();
 445  0 try {
 446  0 docType.write(decl);
 447    } catch (IOException e) {
 448  0 throw new RuntimeException("Error writing DTD", e);
 449    }
 450   
 451  0 return factory.createDTD(decl.toString());
 452    }
 453   
 454    /**
 455    * Writes a DOM4J {@link Document} node, and all its contents, to the
 456    * stream.
 457    *
 458    * @param doc The {@link Document} to write to the stream.
 459    * @throws XMLStreamException If an error occurs writing to the stream.
 460    */
 461  2 public void writeDocument(Document doc) throws XMLStreamException {
 462  2 consumer.add(createStartDocument(doc));
 463   
 464  2 writeChildNodes(doc);
 465   
 466  2 consumer.add(createEndDocument(doc));
 467    }
 468   
 469    /**
 470    * Constructs a STAX {@link StartDocument} event from a DOM4J
 471    * {@link Document}.
 472    *
 473    * @param doc The {@link Document} from which to construct the event.
 474    * @return The constructed {@link StartDocument} event.
 475    */
 476  2 public StartDocument createStartDocument(Document doc) {
 477  2 String encoding = doc.getXMLEncoding();
 478  2 if (encoding != null) {
 479  2 return factory.createStartDocument(encoding);
 480    } else {
 481  0 return factory.createStartDocument();
 482    }
 483    }
 484   
 485    /**
 486    * Constructs a STAX {@link EndDocument} event from a DOM4J
 487    * {@link Document}.
 488    *
 489    * @param doc The {@link Document} from which to construct the event.
 490    * @return The constructed {@link EndDocument} event.
 491    */
 492  2 public EndDocument createEndDocument(Document doc) {
 493  2 return factory.createEndDocument();
 494    }
 495   
 496    /**
 497    * Constructs a STAX {@link QName} from a DOM4J {@link org.dom4j.QName}.
 498    *
 499    * @param qname The {@link org.dom4j.QName} from which to construct the
 500    * STAX {@link QName}.
 501    * @return The constructed {@link QName}.
 502    */
 503  32 public QName createQName(org.dom4j.QName qname) {
 504  32 return new QName(qname.getNamespaceURI(), qname.getName(),
 505    qname.getNamespacePrefix());
 506    }
 507   
 508    /**
 509    * Internal {@link Iterator} implementation used to pass DOM4J
 510    * {@link Attribute}s to the stream.
 511    */
 512    private class AttributeIterator implements Iterator {
 513   
 514    /** The underlying DOm4J attribute iterator. */
 515    private Iterator iter;
 516   
 517  16 public AttributeIterator(Iterator iter) {
 518  16 this.iter = iter;
 519    }
 520   
 521  16 public boolean hasNext() {
 522  16 return iter.hasNext();
 523    }
 524   
 525  0 public Object next() {
 526  0 Attribute attr = (Attribute) iter.next();
 527  0 QName attrName = createQName(attr.getQName());
 528  0 String value = attr.getValue();
 529   
 530  0 return factory.createAttribute(attrName, value);
 531    }
 532   
 533  0 public void remove() {
 534  0 throw new UnsupportedOperationException();
 535    }
 536   
 537    }
 538   
 539    /**
 540    * Internal {@link Iterator} implementation used to pass DOM4J
 541    * {@link Namespace}s to the stream.
 542    */
 543    private class NamespaceIterator implements Iterator {
 544   
 545    private Iterator iter;
 546   
 547  32 public NamespaceIterator(Iterator iter) {
 548  32 this.iter = iter;
 549    }
 550   
 551  32 public boolean hasNext() {
 552  32 return iter.hasNext();
 553    }
 554   
 555  0 public Object next() {
 556  0 Namespace ns = (Namespace) iter.next();
 557  0 String prefix = ns.getPrefix();
 558  0 String nsURI = ns.getURI();
 559   
 560  0 return factory.createNamespace(prefix, nsURI);
 561    }
 562   
 563  0 public void remove() {
 564  0 throw new UnsupportedOperationException();
 565    }
 566   
 567    }
 568   
 569    }
 570   
 571   
 572   
 573   
 574    /*
 575    * Redistribution and use of this software and associated documentation
 576    * ("Software"), with or without modification, are permitted provided
 577    * that the following conditions are met:
 578    *
 579    * 1. Redistributions of source code must retain copyright
 580    * statements and notices. Redistributions must also contain a
 581    * copy of this document.
 582    *
 583    * 2. Redistributions in binary form must reproduce the
 584    * above copyright notice, this list of conditions and the
 585    * following disclaimer in the documentation and/or other
 586    * materials provided with the distribution.
 587    *
 588    * 3. The name "DOM4J" must not be used to endorse or promote
 589    * products derived from this Software without prior written
 590    * permission of MetaStuff, Ltd. For written permission,
 591    * please contact dom4j-info@metastuff.com.
 592    *
 593    * 4. Products derived from this Software may not be called "DOM4J"
 594    * nor may "DOM4J" appear in their names without prior written
 595    * permission of MetaStuff, Ltd. DOM4J is a registered
 596    * trademark of MetaStuff, Ltd.
 597    *
 598    * 5. Due credit should be given to the DOM4J Project -
 599    * http://www.dom4j.org
 600    *
 601    * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS
 602    * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
 603    * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 604    * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 605    * METASTUFF, LTD. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 606    * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 607    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 608    * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 609    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 610    * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 611    * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 612    * OF THE POSSIBILITY OF SUCH DAMAGE.
 613    *
 614    * Copyright 2001-2004 (C) MetaStuff, Ltd. All Rights Reserved.
 615    *
 616    * $Id: STAXEventWriter.java,v 1.6 2004/07/14 19:32:23 maartenc Exp $
 617    */