001/*
002 * OutputNode.java July 2006
003 *
004 * Copyright (C) 2006, Niall Gallagher <niallg@users.sf.net>
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License");
007 * you may not use this file except in compliance with the License.
008 * You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 
015 * implied. See the License for the specific language governing 
016 * permissions and limitations under the License.
017 */
018
019package org.simpleframework.xml.stream;
020
021/**
022 * The <code>OutputNode</code> object is used to represent a cursor
023 * which can be used to write XML elements and attributes. Each of
024 * the output node objects represents a element, and can be used 
025 * to add attributes to that element as well as child elements.
026 *
027 * @author Niall Gallagher
028 */ 
029public interface OutputNode extends Node {
030   
031   /**
032    * This method is used to determine if this node is the root 
033    * node for the XML document. The root node is the first node
034    * in the document and has no sibling nodes. This is false
035    * if the node has a parent node or a sibling node.
036    * 
037    * @return true if this is the root node within the document
038    */
039   boolean isRoot();  
040   
041   /**
042    * This returns a <code>NodeMap</code> which can be used to add
043    * nodes to the element before that element has been committed. 
044    * Nodes can be removed or added to the map and will appear as
045    * attributes on the written element when it is committed.
046    *
047    * @return returns the node map used to manipulate attributes
048    */ 
049   NodeMap<OutputNode> getAttributes();
050   
051   /**
052    * The <code>Mode</code> is used to indicate the output mode
053    * of this node. Three modes are possible, each determines
054    * how a value, if specified, is written to the resulting XML
055    * document. This is determined by the <code>setData</code>
056    * method which will set the output to be CDATA or escaped, 
057    * if neither is specified the mode is inherited.
058    * 
059    * @return this returns the mode of this output node object
060    */
061   Mode getMode();
062   
063   /**
064    * This is used to set the output mode of this node to either
065    * be CDATA, escaped, or inherited. If the mode is set to data
066    * then any value specified will be written in a CDATA block, 
067    * if this is set to escaped values are escaped. If however 
068    * this method is set to inherited then the mode is inherited
069    * from the parent node.
070    * 
071    * @param mode this is the output mode to set the node to 
072    */
073   void setMode(Mode mode);
074   
075   /**
076    * This is used to set the output mode of this node to either
077    * be CDATA or escaped. If this is set to true the any value
078    * specified will be written in a CDATA block, if this is set
079    * to false the values is escaped. If however this method is
080    * never invoked then the mode is inherited from the parent.
081    * 
082    * @param data if true the value is written as a CDATA block
083    */
084   void setData(boolean data);
085  
086   /**
087    * This is used to acquire the prefix for this output node. If
088    * the output node is an element then this will search its parent
089    * nodes until the prefix that is currently in scope is found. 
090    * If however this node is an attribute then the hierarchy of 
091    * nodes is not searched as attributes to not inherit namespaces.
092    *
093    * @return this returns the prefix associated with this node
094    */  
095   String getPrefix();
096   
097   /**
098    * This is used to acquire the prefix for this output node. If
099    * the output node is an element then this will search its parent
100    * nodes until the prefix that is currently in scope is found. 
101    * If however this node is an attribute then the hierarchy of 
102    * nodes is not searched as attributes to not inherit namespaces.
103    *
104    * @param inherit if there is no explicit prefix then inherit
105    *
106    * @return this returns the prefix associated with this node
107    */  
108   String getPrefix(boolean inherit);
109   
110   /**
111    * This is used to acquire the namespace URI reference associated
112    * with this node. Although it is recommended that the namespace
113    * reference is a URI it does not have to be, it can be any unique
114    * identifier that can be used to distinguish the qualified names.
115    *
116    * @return this returns the namespace URI reference for this
117    */
118   String getReference();
119  
120   /**
121    * This is used to set the reference for the node. Setting the
122    * reference implies that the node is a qualified node within the
123    * XML document. Both elements and attributes can be qualified.
124    * Depending on the prefix set on this node or, failing that, any
125    * parent node for the reference, the element will appear in the
126    * XML document with that string prefixed to the node name.
127    *
128    * @param reference this is used to set the reference for the node
129    */  
130   void setReference(String reference);
131  
132   /**
133    * This returns the <code>NamespaceMap</code> for this node. Only
134    * an element can have namespaces, so if this node represents an
135    * attribute the elements namespaces will be provided when this is
136    * requested. By adding a namespace it becomes in scope for the
137    * current element all all child elements of that element.
138    *
139    * @return this returns the namespaces associated with the node
140    */  
141   NamespaceMap getNamespaces();
142   
143   /**
144    * This is used to get the text comment for the element. This can
145    * be null if no comment has been set. If no comment is set on 
146    * the node then no comment will be written to the resulting XML.
147    * 
148    * @return this is the comment associated with this element
149    */
150   String getComment();
151   
152   /**
153    * This is used to set a text comment to the element. This will
154    * be written just before the actual element is written. Only a
155    * single comment can be set for each output node written. 
156    * 
157    * @param comment this is the comment to set on the node
158    */
159   void setComment(String comment);
160   
161   /**
162    * This is used to set a text value to the element. This should
163    * be added to the element if the element contains no child
164    * elements. If the value cannot be added an exception is thrown.
165    * 
166    * @param value this is the text value to add to this element
167    *
168    * @throws Exception thrown if the text value cannot be added
169    */ 
170   void setValue(String value);
171   
172   /**
173    * This is used to change the name of an output node. This will
174    * only affect the name of the node if the node has not yet been
175    * committed. If the node is committed then this will not be
176    * reflected in the resulting XML generated.
177    * 
178    * @param name this is the name to change the node to
179    */
180   void setName(String name);
181   
182   /**
183    * This method is used for convenience to add an attribute node 
184    * to the attribute <code>NodeMap</code>. The attribute added
185    * can be removed from the element by using the node map.
186    * 
187    * @param name this is the name of the attribute to be added
188    * @param value this is the value of the node to be added
189    * 
190    * @return this returns the node that has just been added
191    */ 
192   OutputNode setAttribute(String name, String value);
193   
194   /**
195    * This is used to acquire the <code>Node</code> that is the
196    * parent of this node. This will return the node that is
197    * the direct parent of this node and allows for siblings to
198    * make use of nodes with their parents if required.  
199    *   
200    * @return this returns the parent node for this node
201    */
202   OutputNode getParent();
203   
204   /**
205    * This is used to create a child element within the element that
206    * this object represents. When a new child is created with this
207    * method then the previous child is committed to the document.
208    * The created <code>OutputNode</code> object can be used to add
209    * attributes to the child element as well as other elements.
210    *
211    * @param name this is the name of the child element to create
212    */ 
213   OutputNode getChild(String name) throws Exception;        
214
215   /**
216    * This is used to remove any uncommitted changes. Removal of an
217    * output node can only be done if it has no siblings and has
218    * not yet been committed. If the node is committed then this 
219    * will throw an exception to indicate that it cannot be removed. 
220    * 
221    * @throws Exception thrown if the node cannot be removed
222    */
223   void remove() throws Exception;
224   
225   /**
226    * The <code>commit</code> method is used flush and commit any 
227    * child nodes that have been created by this node. This allows
228    * the output to be completed when building of the XML document
229    * has been completed. If output fails an exception is thrown.
230    * 
231    * @throws Exception thrown if the node cannot be committed
232    */ 
233   void commit() throws Exception;
234
235   /**
236    * This is used to determine whether the node has been committed.
237    * If the node has been committed, then this will return true.
238    * When committed the node can no longer produce chile nodes.
239    * 
240    * @return true if this node has already been committed
241    */
242   boolean isCommitted();
243}