View Javadoc

1   /*
2    * Copyright 2004-2005 The Apache Software Foundation or its licensors,
3    *                     as applicable.
4    *
5    * Licensed under the Apache License, Version 2.0 (the "License");
6    * you may not use this file except in compliance with the License.
7    * You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package net.sf.exorcist.midgard;
18  
19  import java.io.IOException;
20  import java.io.OutputStream;
21  
22  import javax.xml.parsers.DocumentBuilder;
23  import javax.xml.parsers.DocumentBuilderFactory;
24  import javax.xml.parsers.ParserConfigurationException;
25  import javax.xml.transform.Transformer;
26  import javax.xml.transform.TransformerConfigurationException;
27  import javax.xml.transform.TransformerException;
28  import javax.xml.transform.TransformerFactory;
29  import javax.xml.transform.dom.DOMSource;
30  import javax.xml.transform.stream.StreamResult;
31  
32  import org.w3c.dom.Document;
33  import org.w3c.dom.Element;
34  
35  /***
36   * Document builder class. This class provides an intuitive
37   * interface for incrementally building DOM documents.
38   */
39  public final class DOMBuilder {
40  
41      /*** Static factory for creating DOM DocumentBuilder instances. */
42      private static final DocumentBuilderFactory BUILDER_FACTORY =
43          DocumentBuilderFactory.newInstance();
44  
45      /*** Static factory for creating document to output stream transformers. */
46      private static final TransformerFactory TRANSFORMER_FACTORY =
47          TransformerFactory.newInstance();
48  
49      /*** The DOM document being built by this builder. */
50      private final Document document;
51      
52      private final String namespace;
53      private final String prefix;
54      
55      /*** The current element. */
56      private Element current;
57  
58      /***
59       * Creates a builder for a new DOM document. A new DOM document is
60       * instantiated and initialized to contain a root element with the given
61       * name. The root element is set as the current element of this builder.
62       *
63       * @param name name of the root element
64       * @throws ParserConfigurationException if a document cannot be created
65       */
66      public DOMBuilder(String name, String namespace, String prefix)
67              throws ParserConfigurationException  {
68          DocumentBuilder builder = BUILDER_FACTORY.newDocumentBuilder();
69          document = builder.newDocument();
70          current = document.createElementNS(namespace, prefix + ":" + name);
71          current.setAttribute("xmlns:" + prefix, namespace);
72          document.appendChild(current);
73          this.namespace = namespace;
74          this.prefix = prefix;
75      }
76  
77  
78      /***
79       * Writes the document built by this builder into the given output stream.
80       * This method is normally invoked only when the document is fully built.
81       *
82       * @param xml XML output stream
83       * @throws IOException if the document could not be written
84       */
85      public void write(OutputStream xml) throws IOException {
86          try {
87              Transformer transformer = TRANSFORMER_FACTORY.newTransformer();
88              transformer.transform(
89                      new DOMSource(document), new StreamResult(xml));
90          } catch (TransformerConfigurationException e) {
91              throw new IOException(e.getMessage());
92          } catch (TransformerException e) {
93              throw new IOException(e.getMessage());
94          }
95      }
96  
97      /***
98       * Creates a new element with the given name as the child of the
99       * current element and makes the created element current. The
100      * {@link #endElement() endElement} method needs to be called
101      * to return back to the original element.
102      *
103      * @param name name of the new element
104      */
105     public void startElement(String name) {
106         Element element = document.createElementNS(namespace, prefix + ":" + name);
107         current.appendChild(element);
108         current = element;
109     }
110 
111     /***
112      * Makes the parent element current. This method should be invoked
113      * after a child element created with the
114      * {@link #startElement(String) startElement} method has been fully
115      * built.
116      */
117     public void endElement() {
118         current = (Element) current.getParentNode();
119     }
120 
121     /***
122      * Sets the named attribute of the current element.
123      *
124      * @param name attribute name
125      * @param value attribute value
126      */
127     public void setAttribute(String name, String value) {
128         current.setAttribute(name, value);
129     }
130 
131     /***
132      * Sets the named boolean attribute of the current element.
133      *
134      * @param name attribute name
135      * @param value boolean attribute value
136      */
137     public void setAttribute(String name, boolean value) {
138         setAttribute(name, String.valueOf(value));
139     }
140 
141     /***
142      * Adds the given string as text content to the current element.
143      *
144      * @param content text content
145      */
146     public void addContent(String content) {
147         current.appendChild(document.createTextNode(content));
148     }
149 
150     /***
151      * Adds a new child element with the given name and text content.
152      * The created element will contain no attributes and no child elements
153      * of its own.
154      *
155      * @param name child element name
156      * @param content child element content
157      */
158     public void addContentElement(String name, String content) {
159         startElement(name);
160         addContent(content);
161         endElement();
162     }
163 
164 }