View Javadoc

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.tree;
9   
10  import java.io.IOException;
11  import java.io.StringWriter;
12  import java.io.Writer;
13  import java.util.Iterator;
14  import java.util.List;
15  import java.util.Map;
16  
17  import org.dom4j.Comment;
18  import org.dom4j.Document;
19  import org.dom4j.DocumentType;
20  import org.dom4j.Element;
21  import org.dom4j.IllegalAddException;
22  import org.dom4j.Node;
23  import org.dom4j.ProcessingInstruction;
24  import org.dom4j.QName;
25  import org.dom4j.Text;
26  import org.dom4j.Visitor;
27  import org.dom4j.io.OutputFormat;
28  import org.dom4j.io.XMLWriter;
29  
30  /***
31   * <p>
32   * <code>AbstractDocument</code> is an abstract base class for tree
33   * implementors to use for implementation inheritence.
34   * </p>
35   * 
36   * @author <a href="mailto:jstrachan@apache.org">James Strachan </a>
37   * @version $Revision: 1.33 $
38   */
39  public abstract class AbstractDocument extends AbstractBranch implements
40          Document {
41  
42      /*** The encoding of this document as stated in the XML declaration */
43      protected String encoding;
44  
45      public AbstractDocument() {
46      }
47  
48      public short getNodeType() {
49          return DOCUMENT_NODE;
50      }
51  
52      public String getPath(Element context) {
53          return "/";
54      }
55  
56      public String getUniquePath(Element context) {
57          return "/";
58      }
59  
60      public Document getDocument() {
61          return this;
62      }
63  
64      public String getXMLEncoding() {
65          return null;
66      }
67  
68      public String getStringValue() {
69          Element root = getRootElement();
70  
71          return (root != null) ? root.getStringValue() : "";
72      }
73  
74      public String asXML() {
75          OutputFormat format = new OutputFormat();
76          format.setEncoding(encoding);
77          
78          try {
79              StringWriter out = new StringWriter();
80              XMLWriter writer = new XMLWriter(out, format);
81              writer.write(this);
82              writer.flush();
83  
84              return out.toString();
85          } catch (IOException e) {
86              throw new RuntimeException("IOException while generating textual "
87                      + "representation: " + e.getMessage());
88          }
89      }
90  
91      public void write(Writer out) throws IOException {
92          OutputFormat format = new OutputFormat();
93          format.setEncoding(encoding);
94          
95          XMLWriter writer = new XMLWriter(out, format);
96          writer.write(this);
97      }
98  
99      /***
100      * <p>
101      * <code>accept</code> method is the <code>Visitor Pattern</code>
102      * method.
103      * </p>
104      * 
105      * @param visitor
106      *            <code>Visitor</code> is the visitor.
107      */
108     public void accept(Visitor visitor) {
109         visitor.visit(this);
110 
111         DocumentType docType = getDocType();
112 
113         if (docType != null) {
114             visitor.visit(docType);
115         }
116 
117         // visit content
118         List content = content();
119 
120         if (content != null) {
121             for (Iterator iter = content.iterator(); iter.hasNext();) {
122                 Object object = iter.next();
123 
124                 if (object instanceof String) {
125                     Text text = getDocumentFactory()
126                             .createText((String) object);
127                     visitor.visit(text);
128                 } else {
129                     Node node = (Node) object;
130                     node.accept(visitor);
131                 }
132             }
133         }
134     }
135 
136     public String toString() {
137         return super.toString() + " [Document: name " + getName() + "]";
138     }
139 
140     public void normalize() {
141         Element element = getRootElement();
142 
143         if (element != null) {
144             element.normalize();
145         }
146     }
147 
148     public Document addComment(String comment) {
149         Comment node = getDocumentFactory().createComment(comment);
150         add(node);
151 
152         return this;
153     }
154 
155     public Document addProcessingInstruction(String target, String data) {
156         ProcessingInstruction node = getDocumentFactory()
157                 .createProcessingInstruction(target, data);
158         add(node);
159 
160         return this;
161     }
162 
163     public Document addProcessingInstruction(String target, Map data) {
164         ProcessingInstruction node = getDocumentFactory()
165                 .createProcessingInstruction(target, data);
166         add(node);
167 
168         return this;
169     }
170 
171     public Element addElement(String name) {
172         Element element = getDocumentFactory().createElement(name);
173         add(element);
174 
175         return element;
176     }
177 
178     public Element addElement(String qualifiedName, String namespaceURI) {
179         Element element = getDocumentFactory().createElement(qualifiedName,
180                 namespaceURI);
181         add(element);
182 
183         return element;
184     }
185 
186     public Element addElement(QName qName) {
187         Element element = getDocumentFactory().createElement(qName);
188         add(element);
189 
190         return element;
191     }
192 
193     public void setRootElement(Element rootElement) {
194         clearContent();
195 
196         if (rootElement != null) {
197             super.add(rootElement);
198             rootElementAdded(rootElement);
199         }
200     }
201 
202     public void add(Element element) {
203         checkAddElementAllowed(element);
204         super.add(element);
205         rootElementAdded(element);
206     }
207 
208     public boolean remove(Element element) {
209         boolean answer = super.remove(element);
210         Element root = getRootElement();
211 
212         if ((root != null) && answer) {
213             setRootElement(null);
214         }
215 
216         element.setDocument(null);
217 
218         return answer;
219     }
220 
221     public Node asXPathResult(Element parent) {
222         return this;
223     }
224 
225     protected void childAdded(Node node) {
226         if (node != null) {
227             node.setDocument(this);
228         }
229     }
230 
231     protected void childRemoved(Node node) {
232         if (node != null) {
233             node.setDocument(null);
234         }
235     }
236 
237     protected void checkAddElementAllowed(Element element) {
238         Element root = getRootElement();
239 
240         if (root != null) {
241             throw new IllegalAddException(this, element,
242                     "Cannot add another element to this "
243                             + "Document as it already has a root "
244                             + "element of: " + root.getQualifiedName());
245         }
246     }
247 
248     /***
249      * Called to set the root element variable
250      * 
251      * @param rootElement
252      *            DOCUMENT ME!
253      */
254     protected abstract void rootElementAdded(Element rootElement);
255 
256     public void setXMLEncoding(String enc) {
257         this.encoding = enc;
258     }
259 }
260 
261 /*
262  * Redistribution and use of this software and associated documentation
263  * ("Software"), with or without modification, are permitted provided that the
264  * following conditions are met:
265  * 
266  * 1. Redistributions of source code must retain copyright statements and
267  * notices. Redistributions must also contain a copy of this document.
268  * 
269  * 2. Redistributions in binary form must reproduce the above copyright notice,
270  * this list of conditions and the following disclaimer in the documentation
271  * and/or other materials provided with the distribution.
272  * 
273  * 3. The name "DOM4J" must not be used to endorse or promote products derived
274  * from this Software without prior written permission of MetaStuff, Ltd. For
275  * written permission, please contact dom4j-info@metastuff.com.
276  * 
277  * 4. Products derived from this Software may not be called "DOM4J" nor may
278  * "DOM4J" appear in their names without prior written permission of MetaStuff,
279  * Ltd. DOM4J is a registered trademark of MetaStuff, Ltd.
280  * 
281  * 5. Due credit should be given to the DOM4J Project - http://www.dom4j.org
282  * 
283  * THIS SOFTWARE IS PROVIDED BY METASTUFF, LTD. AND CONTRIBUTORS ``AS IS'' AND
284  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
285  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
286  * ARE DISCLAIMED. IN NO EVENT SHALL METASTUFF, LTD. OR ITS CONTRIBUTORS BE
287  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
288  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
289  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
290  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
291  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
292  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
293  * POSSIBILITY OF SUCH DAMAGE.
294  * 
295  * Copyright 2001-2005 (C) MetaStuff, Ltd. All Rights Reserved.
296  */