Coverage Report - net.sf.practicalxml.builder.ElementNode
 
Classes in this File Line Coverage Branch Coverage Complexity
ElementNode
100%
43/43
92%
13/14
1.583
ElementNode$1
N/A
N/A
1.583
ElementNode$SerializationHelper
100%
5/5
N/A
1.583
 
 1  
 // Copyright 2008-2014 severally by the contributors
 2  
 //
 3  
 // Licensed under the Apache License, Version 2.0 (the "License");
 4  
 // you may not use this file except in compliance with the License.
 5  
 // You may obtain a copy of the License at
 6  
 //
 7  
 //     http://www.apache.org/licenses/LICENSE-2.0
 8  
 //
 9  
 // Unless required by applicable law or agreed to in writing, software
 10  
 // distributed under the License is distributed on an "AS IS" BASIS,
 11  
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
 // See the License for the specific language governing permissions and
 13  
 // limitations under the License.
 14  
 
 15  
 package net.sf.practicalxml.builder;
 16  
 
 17  
 import java.io.IOException;
 18  
 import java.io.OutputStream;
 19  
 import java.util.ArrayList;
 20  
 import java.util.List;
 21  
 
 22  
 import org.w3c.dom.Document;
 23  
 import org.w3c.dom.Element;
 24  
 import org.xml.sax.Attributes;
 25  
 import org.xml.sax.ContentHandler;
 26  
 import org.xml.sax.InputSource;
 27  
 import org.xml.sax.SAXException;
 28  
 import org.xml.sax.helpers.AttributesImpl;
 29  
 import org.xml.sax.helpers.XMLFilterImpl;
 30  
 
 31  
 import net.sf.practicalxml.DomUtil;
 32  
 import net.sf.practicalxml.OutputUtil;
 33  
 
 34  
 
 35  
 /**
 36  
  *  The primary class for building XML trees and converting them to different
 37  
  *  JAXP-centric forms. Callers should not create instances of this class
 38  
  *  directly; instead use the static factory methods in {@link XmlBuilder}.
 39  
  */
 40  
 public final class ElementNode
 41  
 extends Node
 42  
 {
 43  
     private static final long serialVersionUID = 2L;
 44  
 
 45  
     private String _nsUri;
 46  
     private String _qname;
 47  
     private String _lclName;
 48  2203
     private List<AttributeNode> _attribs = new ArrayList<AttributeNode>();
 49  2203
     private List<Node> _children = new ArrayList<Node>();
 50  
 
 51  
 
 52  
     ElementNode(String nsUri, String qname, Node... children)
 53  2203
     {
 54  2203
         _nsUri = nsUri;
 55  2203
         _qname = qname;
 56  2203
         _lclName = getLocalName(qname);
 57  6328
         for (Node child : children)
 58  4125
             addChild(child);
 59  2203
     }
 60  
 
 61  
 
 62  
     /**
 63  
      *  Adds a child node -- of any type -- to this element. Returns this as
 64  
      *  a convenience to caller, allowing calls to be chained.
 65  
      */
 66  
     public ElementNode addChild(Node child)
 67  
     {
 68  4126
         if (child instanceof AttributeNode)
 69  892
             _attribs.add((AttributeNode)child);
 70  3234
         else if (child != null)
 71  3234
             _children.add(child);
 72  4126
         return this;
 73  
     }
 74  
 
 75  
 
 76  
     /**
 77  
      *  Generates a new DOM document with this element as the root.
 78  
      */
 79  
     public Document toDOM()
 80  
     {
 81  595
         Element root = DomUtil.newDocument(_nsUri, _qname);
 82  595
         appendChildren(root);
 83  595
         return root.getOwnerDocument();
 84  
     }
 85  
 
 86  
 
 87  
     /**
 88  
      *  Invokes the passed <code>ContentHandler</code> for this element and
 89  
      *  its children. Note that the implementation class must also implement
 90  
      *  <code>LexicalHandler</code> to receive events from all nodes in the
 91  
      *  tree (particularly comments).
 92  
      */
 93  
     @Override
 94  
     protected void toSAX(ContentHandler handler)
 95  
     throws SAXException
 96  
     {
 97  27
         handler.startElement(_nsUri, _lclName, _qname, getAttributes());
 98  27
         for (Node child : _children)
 99  
         {
 100  18
             child.toSAX(handler);
 101  18
         }
 102  27
         handler.endElement(_nsUri, _lclName, _qname);
 103  27
     }
 104  
 
 105  
 
 106  
     /**
 107  
      *  Generates an XML string, where this node is the root element. Does
 108  
      *  not insert whitespace between elements. Note that you <em>must</em>
 109  
      *  use UTF-8 encoding or add a prologue that specifies encoding when
 110  
      *  writing this string to a stream.
 111  
      */
 112  
     @Override
 113  
     public String toString()
 114  
     {
 115  9
         return OutputUtil.compactString(new SerializationHelper());
 116  
     }
 117  
 
 118  
 
 119  
     /**
 120  
      *  Generates an XML string, where this node is the root element. Inserts
 121  
      *  whitespace between nodes, along with newlines and the specified indent
 122  
      *  between elements.
 123  
      *  <p>
 124  
      *  This is the best choice for writing log output. If you write this string
 125  
      *  to a stream, you <em>must</em> use UTF-8 encoding or attach a prologue
 126  
      *  that specifies the encoding used.
 127  
      */
 128  
     public String toString(int indentSize)
 129  
     {
 130  1
         return OutputUtil.indentedString(new SerializationHelper(), indentSize);
 131  
     }
 132  
 
 133  
 
 134  
     /**
 135  
      *  Writes the tree rooted at this element to an <code>OutputStream</code>,
 136  
      *  using UTF-8 encoding, without a prologue or whitepspace between nodes.
 137  
      *  <p>
 138  
      *  This is the best choice for writing XML that will be read by another
 139  
      *  party.
 140  
      */
 141  
     public void toStream(OutputStream out)
 142  
     {
 143  1
         OutputUtil.compactStream(new SerializationHelper(), out);
 144  1
     }
 145  
 
 146  
 
 147  
     /**
 148  
      *  Writes the tree rooted at this element to an <code>OutputStream</code>,
 149  
      *  using a specified encoding, without a prologue or whitepspace between
 150  
      *  nodes.
 151  
      */
 152  
     public void toStream(OutputStream out, String encoding)
 153  
     {
 154  1
         OutputUtil.compactStream(toDOM(), out, encoding);
 155  1
     }
 156  
 
 157  
 
 158  
 //----------------------------------------------------------------------------
 159  
 //  Internals
 160  
 //----------------------------------------------------------------------------
 161  
 
 162  
     @Override
 163  
     protected void appendToElement(Element parent)
 164  
     {
 165  1604
         appendChildren(DomUtil.appendChild(parent, _nsUri, _qname));
 166  1604
     }
 167  
 
 168  
 
 169  
     private void appendChildren(Element elem)
 170  
     {
 171  2199
         for (Node child : _attribs)
 172  
         {
 173  892
             child.appendToElement(elem);
 174  892
         }
 175  2199
         for (Node child : _children)
 176  
         {
 177  3230
             child.appendToElement(elem);
 178  3230
         }
 179  2199
     }
 180  
 
 181  
 
 182  
     private Attributes getAttributes()
 183  
     {
 184  27
         AttributesImpl result = new AttributesImpl();
 185  27
         for (AttributeNode attr : _attribs)
 186  
         {
 187  2
             attr.appendToAttributes(result);
 188  2
         }
 189  27
         return result;
 190  
     }
 191  
 
 192  
 
 193  22
     private class SerializationHelper
 194  
     extends XMLFilterImpl
 195  
     {
 196  
         @Override
 197  
         public void parse(InputSource input)
 198  
         throws SAXException, IOException
 199  
         {
 200  11
             startDocument();
 201  11
             toSAX(getContentHandler());
 202  11
             endDocument();
 203  11
         }
 204  
     }
 205  
 }