Coverage Report - org.simpleframework.xml.stream.OutputDocument
 
Classes in this File Line Coverage Branch Coverage Complexity
OutputDocument
27%
12/43
33%
2/6
1.217
 
 1  
 /*
 2  
  * OutputDocument.java July 2006
 3  
  *
 4  
  * Copyright (C) 2006, Niall Gallagher <niallg@users.sf.net>
 5  
  *
 6  
  * Licensed under the Apache License, Version 2.0 (the "License");
 7  
  * you may not use this file except in compliance with the License.
 8  
  * You may obtain a copy of the License at
 9  
  *
 10  
  *     http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing, software
 13  
  * distributed under the License is distributed on an "AS IS" BASIS,
 14  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
 15  
  * implied. See the License for the specific language governing 
 16  
  * permissions and limitations under the License.
 17  
  */
 18  
 
 19  
 package org.simpleframework.xml.stream;
 20  
 
 21  
 /**
 22  
  * The <code>OutputDocument</code> object is used to represent the
 23  
  * root of an XML document. This does not actually represent anything
 24  
  * that will be written to the generated document. It is used as a
 25  
  * way to create the root document element. Once the root element has
 26  
  * been created it can be committed by using this object.
 27  
  * 
 28  
  * @author Niall Gallagher
 29  
  */ 
 30  0
 class OutputDocument implements OutputNode {
 31  
    
 32  
    /**
 33  
     * Represents a dummy output node map for the attributes.
 34  
     */ 
 35  
    private OutputNodeMap table;
 36  
         
 37  
    /**
 38  
     * Represents the writer that is used to create the element.
 39  
     */ 
 40  
    private NodeWriter writer;
 41  
    
 42  
    /**
 43  
     * This is the output stack used by the node writer object.
 44  
     */ 
 45  
    private OutputStack stack;
 46  
   
 47  
    /**
 48  
     * This represents the namespace reference used by this.
 49  
     */  
 50  
    private String reference;
 51  
    
 52  
    /**
 53  
     * This is the comment that is to be written for the node.
 54  
     */
 55  
    private String comment;
 56  
    
 57  
    /**
 58  
     * Represents the value that has been set on this document.
 59  
     */ 
 60  
    private String value;
 61  
    
 62  
    /**
 63  
     * This is the name of this output document node instance.
 64  
     */
 65  
    private String name;
 66  
    
 67  
    /**
 68  
     * This is the output mode of this output document object.
 69  
     */
 70  
    private Mode mode;
 71  
   
 72  
    /**
 73  
     * Constructor for the <code>OutputDocument</code> object. This 
 74  
     * is used to create an empty output node object that can be
 75  
     * used to create a root element for the generated document. 
 76  
     *
 77  
     * @param writer this is the node writer to write the node to
 78  
     * @param stack this is the stack that contains the open nodes
 79  
     */ 
 80  24420
    public OutputDocument(NodeWriter writer, OutputStack stack) {
 81  24420
       this.table = new OutputNodeMap(this);    
 82  24420
       this.mode = Mode.INHERIT;
 83  24420
       this.writer = writer;
 84  24420
       this.stack = stack;
 85  24420
    }  
 86  
    
 87  
    /**
 88  
     * The default for the <code>OutputDocument</code> is null as it
 89  
     * does not require a namespace. A null prefix is always used by
 90  
     * the document as it represents a virtual node that does not
 91  
     * exist and will not form any part of the resulting XML.
 92  
     *
 93  
     * @return this returns a null prefix for the output document
 94  
     */ 
 95  
    public String getPrefix() {
 96  0
       return null;
 97  
    }
 98  
    
 99  
    /**
 100  
     * The default for the <code>OutputDocument</code> is null as it
 101  
     * does not require a namespace. A null prefix is always used by
 102  
     * the document as it represents a virtual node that does not
 103  
     * exist and will not form any part of the resulting XML.
 104  
     *
 105  
     * @param inherit if there is no explicit prefix then inherit
 106  
     *
 107  
     * @return this returns a null prefix for the output document
 108  
     */  
 109  
    public String getPrefix(boolean inherit) {
 110  0
       return null;
 111  
    }
 112  
   
 113  
    /**
 114  
     * This is used to acquire the reference that has been set on
 115  
     * this output node. Typically this should be null as this node
 116  
     * does not represent anything that actually exists. However
 117  
     * if a namespace reference is set it can be acquired.
 118  
     *
 119  
     * @return this returns the namespace reference for this node
 120  
     */  
 121  
    public String getReference() {
 122  0
       return reference;
 123  
    }
 124  
 
 125  
    /**
 126  
     * This is used to set the namespace reference for the document.
 127  
     * Setting a reference for the document node has no real effect
 128  
     * as the document node is virtual and is not written to the
 129  
     * resulting XML document that is generated.
 130  
     *
 131  
     * @param reference this is the namespace reference added
 132  
     */ 
 133  
    public void setReference(String reference) {
 134  0
       this.reference = reference;
 135  0
    }
 136  
 
 137  
    /**
 138  
     * This returns the <code>NamespaceMap</code> for the document.
 139  
     * The namespace map for the document must be null as this will
 140  
     * signify the end of the resolution process for a prefix if
 141  
     * given a namespace reference.
 142  
     *
 143  
     * @return this will return a null namespace map object
 144  
     */ 
 145  
    public NamespaceMap getNamespaces() {
 146  1394239
       return null;
 147  
    }
 148  
    
 149  
    /**
 150  
     * This is used to acquire the <code>Node</code> that is the
 151  
     * parent of this node. This will return the node that is
 152  
     * the direct parent of this node and allows for siblings to
 153  
     * make use of nodes with their parents if required.  
 154  
     *   
 155  
     * @return this will always return null for this output    
 156  
     */
 157  
    public OutputNode getParent() {
 158  0
       return null;
 159  
    }
 160  
    
 161  
    /**
 162  
     * To signify that this is the document element this method will
 163  
     * return null. Any object with a handle on an output node that
 164  
     * has been created can check the name to determine its type.
 165  
     *
 166  
     * @return this returns null for the name of the node 
 167  
     */ 
 168  
    public String getName() {
 169  0
       return null;
 170  
    }
 171  
    
 172  
    /**
 173  
     * This returns the value that has been set for this document.
 174  
     * The value returned is essentially a dummy value as this node
 175  
     * is never written to the resulting XML document.
 176  
     *
 177  
     * @return the value that has been set with this document
 178  
     */ 
 179  
    public String getValue() throws Exception {
 180  0
       return value;
 181  
    }
 182  
    
 183  
    /**
 184  
     * This is used to get the text comment for the element. This can
 185  
     * be null if no comment has been set. If no comment is set on 
 186  
     * the node then no comment will be written to the resulting XML.
 187  
     * 
 188  
     * @return this is the comment associated with this element
 189  
     */
 190  
    public String getComment() {
 191  0
       return comment;
 192  
    }
 193  
    
 194  
    /**
 195  
     * This method is used to determine if this node is the root 
 196  
     * node for the XML document. The root node is the first node
 197  
     * in the document and has no sibling nodes. This will return
 198  
     * true although the document node is not strictly the root.
 199  
     * 
 200  
     * @return returns true although this is not really a root
 201  
     */
 202  
    public boolean isRoot() {
 203  0
       return true;
 204  
    }
 205  
    
 206  
    /**
 207  
     * The <code>Mode</code> is used to indicate the output mode
 208  
     * of this node. Three modes are possible, each determines
 209  
     * how a value, if specified, is written to the resulting XML
 210  
     * document. This is determined by the <code>setData</code>
 211  
     * method which will set the output to be CDATA or escaped, 
 212  
     * if neither is specified the mode is inherited.
 213  
     * 
 214  
     * @return this returns the mode of this output node object
 215  
     */
 216  
    public Mode getMode() {
 217  0
       return mode;
 218  
    }
 219  
    
 220  
    /**
 221  
     * This is used to set the output mode of this node to either
 222  
     * be CDATA, escaped, or inherited. If the mode is set to data
 223  
     * then any value specified will be written in a CDATA block, 
 224  
     * if this is set to escaped values are escaped. If however 
 225  
     * this method is set to inherited then the mode is inherited
 226  
     * from the parent node.
 227  
     * 
 228  
     * @param mode this is the output mode to set the node to 
 229  
     */
 230  
    public void setMode(Mode mode) {
 231  0
       this.mode = mode;
 232  0
    }
 233  
    
 234  
    /**
 235  
     * This method is used for convenience to add an attribute node 
 236  
     * to the attribute <code>NodeMap</code>. The attribute added
 237  
     * can be removed from the element by using the node map.
 238  
     * 
 239  
     * @param name this is the name of the attribute to be added
 240  
     * @param value this is the value of the node to be added
 241  
     * 
 242  
     * @return this returns the node that has just been added
 243  
     */ 
 244  
    public OutputNode setAttribute(String name, String value) {
 245  0
       return table.put(name, value);
 246  
    }
 247  
 
 248  
    /**
 249  
     * This returns a <code>NodeMap</code> which can be used to add
 250  
     * nodes to this node. The node map returned by this is a dummy
 251  
     * map, as this output node is never written to the XML document.
 252  
     *
 253  
     * @return returns the node map used to manipulate attributes
 254  
     */ 
 255  
    public NodeMap<OutputNode> getAttributes() {
 256  0
       return table;
 257  
    }
 258  
 
 259  
    /**
 260  
     * This is used to change the name of an output node. This will
 261  
     * only affect the name of the node if the node has not yet been
 262  
     * committed. If the node is committed then this will not be
 263  
     * reflected in the resulting XML generated.
 264  
     * 
 265  
     * @param name this is the name to change the node to
 266  
     */
 267  
    public void setName(String name) {
 268  0
       this.name = name;
 269  0
    }
 270  
    
 271  
    /**
 272  
     * This is used to set a text value to the element. This effect
 273  
     * of adding this to the document node will not change what
 274  
     * is actually written to the generated XML document.
 275  
     * 
 276  
     * @param value this is the text value to add to this element
 277  
     */  
 278  
    public void setValue(String value) {
 279  0
       this.value = value;
 280  0
    }
 281  
    
 282  
    /**
 283  
     * This is used to set a text comment to the element. This will
 284  
     * be written just before the actual element is written. Only a
 285  
     * single comment can be set for each output node written. 
 286  
     * 
 287  
     * @param comment this is the comment to set on the node
 288  
     */
 289  
    public void setComment(String comment) {
 290  0
       this.comment = comment;
 291  0
    }
 292  
    
 293  
    /**
 294  
     * This is used to set the output mode of this node to either
 295  
     * be CDATA or escaped. If this is set to true the any value
 296  
     * specified will be written in a CDATA block, if this is set
 297  
     * to false the values is escaped. If however this method is
 298  
     * never invoked then the mode is inherited from the parent.
 299  
     * 
 300  
     * @param data if true the value is written as a CDATA block
 301  
     */
 302  
    public void setData(boolean data) {
 303  0
       if(data) {
 304  0
          mode = Mode.DATA;
 305  
       } else {
 306  0
          mode = Mode.ESCAPE;
 307  
       }     
 308  0
    }
 309  
    
 310  
    /**
 311  
     * This is used to create a child element within the element that
 312  
     * this object represents. When a new child is created with this
 313  
     * method then the previous child is committed to the document.
 314  
     * The created <code>OutputNode</code> object can be used to add
 315  
     * attributes to the child element as well as other elements.
 316  
     *
 317  
     * @param name this is the name of the child element to create
 318  
     */  
 319  
    public OutputNode getChild(String name) throws Exception {
 320  24418
       return writer.writeElement(this, name);
 321  
    }
 322  
    
 323  
    /**
 324  
     * This is used to remove any uncommitted changes. Removal of an
 325  
     * output node can only be done if it has no siblings and has
 326  
     * not yet been committed. If the node is committed then this 
 327  
     * will throw an exception to indicate that it cannot be removed. 
 328  
     * 
 329  
     * @throws Exception thrown if the node cannot be removed
 330  
     */
 331  
    public void remove() throws Exception {
 332  0
       if(stack.isEmpty()) {
 333  0
          throw new NodeException("No root node");              
 334  
       }           
 335  0
       stack.bottom().remove();  
 336  0
    }
 337  
 
 338  
    /**
 339  
     * This will commit this element and any uncommitted elements
 340  
     * elements that are decendents of this node. For instance if
 341  
     * any child or grand child remains open under this element
 342  
     * then those elements will be closed before this is closed.
 343  
     *
 344  
     * @throws Exception this is thrown if there is an I/O error
 345  
     * or if a root element has not yet been created
 346  
     */ 
 347  
    public void commit() throws Exception {
 348  16
       if(stack.isEmpty()) {
 349  1
          throw new NodeException("No root node");              
 350  
       }           
 351  15
       stack.bottom().commit();
 352  15
    }
 353  
 
 354  
    /**
 355  
     * This is used to determine whether this node has been committed.
 356  
     * This will return true if no root element has been created or
 357  
     * if the root element for the document has already been commited.
 358  
     *
 359  
     * @return true if the node is committed or has not been created
 360  
     */  
 361  
    public boolean isCommitted() {
 362  0
       return stack.isEmpty();
 363  
    }
 364  
 }