View Javadoc

1   /*
2    * Copyright (c) 2003, Henri Yandell
3    * All rights reserved.
4    * 
5    * Redistribution and use in source and binary forms, with or 
6    * without modification, are permitted provided that the 
7    * following conditions are met:
8    * 
9    * + Redistributions of source code must retain the above copyright notice, 
10   *   this list of conditions and the following disclaimer.
11   * 
12   * + Redistributions in binary form must reproduce the above copyright notice, 
13   *   this list of conditions and the following disclaimer in the documentation 
14   *   and/or other materials provided with the distribution.
15   * 
16   * + Neither the name of XmlWriter nor the names of its contributors 
17   *   may be used to endorse or promote products derived from this software 
18   *   without specific prior written permission.
19   * 
20   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
21   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
22   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
23   * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
24   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
25   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
26   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
27   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
28   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
29   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
30   * POSSIBILITY OF SUCH DAMAGE.
31   */
32  package com.generationjava.io.xml;
33  
34  import java.io.IOException;
35  import java.io.UnsupportedEncodingException;
36  import java.io.Writer;
37  
38  import org.znerd.xmlenc.XMLOutputter;
39  
40  /***
41   * An XmlWriter implementation, meaning it actually does output,  
42   * that sits on top of the znerd.ord XmlEnc library. 
43   *
44   * This should allow for faster speed with some additional features, 
45   * though the design of this API blocks these features from the user.
46   */
47  public class XmlEncXmlWriter extends AbstractXmlWriter {
48  
49      private XMLOutputter xmlenc;      // underlying writer
50      private boolean empty;      // is the current node empty
51      private boolean closed;     // is the current node closed...
52  
53      private String namespace;   // the current default namespace
54  
55      // TODO: Remove this if XMLOutputter lets me return the writer
56      private Writer writer; // so I can return the writer
57  
58  
59      public XmlEncXmlWriter(Writer writer) {
60          this(writer, "UTF-8");
61      }
62      public XmlEncXmlWriter(Writer writer, String encoding) {
63          this.writer = writer;
64          try {
65              this.xmlenc = new XMLOutputter(writer, encoding);
66          } catch(UnsupportedEncodingException uee) {
67              throw new RuntimeException("UnsupportedEncodingException occurred in XmlEnc: "+uee.getMessage());
68          }
69          this.closed = true;
70      }
71  
72      /***
73       * The default namespace. Once this is turned on, any new entities 
74       * will have this namespace, regardless of scope.
75       *
76       * @param String nname of the namespace
77       */
78      public void setDefaultNamespace(String namespace) {
79          this.namespace = namespace;
80      }
81  
82      /***
83       * Output the version, encoding and standalone nature of an xml file.
84       */
85      public XmlWriter writeXmlVersion(String version, String encoding, String standalone) throws IOException {
86          // how do we pass things in???
87          this.xmlenc.declaration();
88          return this;
89      }
90  
91      /***
92       * Begin to write out an entity. Unlike the helper tags, this tag 
93       * will need to be ended with the endEntity method.
94       *
95       * @param name String name of tag
96       */
97      public XmlWriter writeEntity(String name) throws IOException {
98          
99          if(this.namespace == null) {
100             return openEntity(name);
101         } else {
102             return openEntity(this.namespace+":"+name);
103         }
104     }
105 
106     /***
107      * Begin to output an entity. 
108      *
109      * @param String name of entity.
110      */
111     private XmlWriter openEntity(String name) throws IOException {
112         boolean wasClosed = this.closed;
113         closeOpeningTag();
114         this.closed = false;
115         this.xmlenc.startTag(name);
116         this.empty = true;
117         return this;
118     }
119 
120     // close off the opening tag
121     private void closeOpeningTag() throws IOException {
122         if (!this.closed) {
123             this.empty = false;
124             this.closed = true;
125         }
126     }
127 
128     /***
129      * Write an attribute out for the current entity. 
130      * Any xml characters in the value are escaped.
131      * Currently it does not actually throw the exception, but 
132      * the api is set that way for future changes.
133      *
134      * @param String name of attribute.
135      * @param Object value of attribute.
136      */
137     public XmlWriter writeAttribute(String attr, Object value) throws IOException {
138 
139         // maintain api
140         if (false) throw new IOException();
141 
142         this.xmlenc.attribute(attr, ""+value);
143         return this;
144     }
145 
146     /***
147      * End the current entity. This will throw an exception 
148      * if it is called when there is not a currently open 
149      * entity.
150      */
151     public XmlWriter endEntity() throws IOException {
152         if (this.empty) {
153             this.xmlenc.endTag();
154         } else {
155             this.xmlenc.endTag();
156         }
157         this.empty = false;
158         this.closed = true;
159         return this;
160     }
161 
162     /***
163      * Close this.xmlenc. It does not close the underlying 
164      * writer, but does flush the underlying writer and 
165      * throw an exception if there are 
166      * as yet unclosed tags.
167      */
168     public void close() throws IOException {
169         this.writer.flush();
170         this.xmlenc.close();
171     }
172 
173     /***
174      * Output body text. Any xml characters are escaped. 
175      */
176     public XmlWriter writeText(Object text) throws IOException {
177         
178         closeOpeningTag();
179         this.empty = false;
180         this.xmlenc.pcdata(""+text);
181         return this;
182     }
183 
184     /***
185      * Write out a chunk of CDATA. This helper method surrounds the 
186      * passed in data with the CDATA tag.
187      *
188      * @param String of CDATA text.
189      */
190     public XmlWriter writeCData(String cdata) throws IOException {
191         
192         this.xmlenc.cdata(cdata);
193         return this;
194     }
195 
196     /***
197      * Write out a chunk of comment. This helper method surrounds the 
198      * passed in data with the xml comment tag.
199      *
200      * @param String of text to comment.
201      */
202     public XmlWriter writeComment(String comment) throws IOException {
203         
204 //        writeChunk("<!-- "+comment+" -->");
205         this.xmlenc.comment(comment);
206         return this;
207     }
208 
209     public Writer getWriter() {
210         return this.writer;
211     }
212 
213 }
214