KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jibx > runtime > impl > GenericXMLWriter


1 /*
2 Copyright (c) 2004, Dennis M. Sosnoski.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
7
8  * Redistributions of source code must retain the above copyright notice, this
9    list of conditions and the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice,
11    this list of conditions and the following disclaimer in the documentation
12    and/or other materials provided with the distribution.
13  * Neither the name of JiBX nor the names of its contributors may be used
14    to endorse or promote products derived from this software without specific
15    prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
21 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */

28
29 package org.jibx.runtime.impl;
30
31 import java.io.IOException JavaDoc;
32 import java.io.Writer JavaDoc;
33
34 import org.jibx.runtime.ICharacterEscaper;
35
36 /**
37  * Generic handler for marshalling text document to a writer. This is the
38  * most general output handler since it can be used with any character encoding
39  * and and output writer.
40  *
41  * @author Dennis M. Sosnoski
42  * @version 1.0
43  */

44
45 public class GenericXMLWriter extends XMLWriterBase
46 {
47     /** Writer for text output. */
48     private Writer JavaDoc m_writer;
49     
50     /** Escaper for character data content output. */
51     private ICharacterEscaper m_escaper;
52     
53     /** Indent tags for pretty-printed text. */
54     private boolean m_indent;
55     
56     /** Base number of characters in indent sequence (end of line only). */
57     private int m_indentBase;
58     
59     /** Number of extra characters in indent sequence per level of nesting. */
60     private int m_indentPerLevel;
61     
62     /** Raw text for indentation sequences. */
63     private char[] m_indentSequence;
64     
65     /**
66      * Constructor.
67      *
68      * @param uris ordered array of URIs for namespaces used in document (must
69      * be constant; the value in position 0 must always be the empty string "",
70      * and the value in position 1 must always be the XML namespace
71      * "http://www.w3.org/XML/1998/namespace")
72      */

73     
74     public GenericXMLWriter(String JavaDoc[] uris) {
75         super(uris);
76     }
77     
78     /**
79      * Set output writer and escaper. If an output writer is currently open when
80      * this is called the existing writer is flushed and closed, with any
81      * errors ignored.
82      *
83      * @param outw writer for document data output
84      * @param escaper character escaper for chosen encoding
85      */

86     
87     public void setOutput(Writer JavaDoc outw, ICharacterEscaper escaper) {
88         try {
89             close();
90         } catch (IOException JavaDoc e) { /* deliberately empty */ }
91         m_writer = outw;
92         m_escaper = escaper;
93         reset();
94     }
95     
96     /**
97      * Set nesting indentation. This is advisory only, and implementations of
98      * this interface are free to ignore it. The intent is to indicate that the
99      * generated output should use indenting to illustrate element nesting.
100      *
101      * @param count number of character to indent per level, or disable
102      * indentation if negative (zero means new line only)
103      * @param newline sequence of characters used for a line ending
104      * (<code>null</code> means use the single character '\n')
105      * @param indent whitespace character used for indentation
106      */

107     
108     public void setIndentSpaces(int count, String JavaDoc newline, char indent) {
109         if (count >= 0) {
110             if (newline == null) {
111                 newline = "\n";
112             }
113             m_indent = true;
114             m_indentBase = newline.length();
115             m_indentPerLevel = count;
116             int length = newline.length() + count * 10;
117             m_indentSequence = new char[length];
118             for (int i = 0; i < length; i++) {
119                 if (i < newline.length()) {
120                     m_indentSequence[i] = newline.charAt(i);
121                 } else {
122                     m_indentSequence[i] = indent;
123                 }
124             }
125         } else {
126             m_indent = false;
127         }
128     }
129     
130     /**
131      * Write markup text to output. Markup text can be written directly to the
132      * output without the need for any escaping.
133      *
134      * @param text markup text to be written
135      * @throws IOException if error writing to document
136      */

137     
138     protected void writeMarkup(String JavaDoc text) throws IOException JavaDoc {
139         m_writer.write(text);
140     }
141     
142     /**
143      * Write markup character to output. Markup text can be written directly to
144      * the output without the need for any escaping.
145      *
146      * @param chr markup character to be written
147      * @throws IOException if error writing to document
148      */

149     
150     protected void writeMarkup(char chr) throws IOException JavaDoc {
151         m_writer.write(chr);
152     }
153     
154     /**
155      * Report that namespace has been defined.
156      *
157      * @param index namespace URI index number
158      * @param prefix prefix used for namespace
159      */

160     
161     protected void defineNamespace(int index, String JavaDoc prefix) {}
162     
163     /**
164      * Report that namespace has been undefined.
165      *
166      * @param index namespace URI index number
167      */

168     
169     protected void undefineNamespace(int index) {}
170     
171     /**
172      * Write namespace prefix to output. This internal method is used to throw
173      * an exception when an undeclared prefix is used.
174      *
175      * @param index namespace URI index number
176      * @throws IOException if error writing to document
177      */

178     
179     protected void writePrefix(int index) throws IOException JavaDoc {
180         try {
181             String JavaDoc text = m_prefixes[index];
182             if (text.length() > 0) {
183                 m_writer.write(text);
184                 m_writer.write(':');
185             }
186         } catch (NullPointerException JavaDoc ex) {
187             throw new IOException JavaDoc("Namespace URI has not been declared.");
188         }
189     }
190     
191     /**
192      * Write attribute text to output. This needs to write the text with any
193      * appropriate escaping.
194      *
195      * @param text attribute value text to be written
196      * @throws IOException if error writing to document
197      */

198     
199     protected void writeAttributeText(String JavaDoc text) throws IOException JavaDoc {
200         m_escaper.writeAttribute(text, m_writer);
201     }
202     
203     /**
204      * Write ordinary character data text content to document. This needs to
205      * write the text with any appropriate escaping.
206      *
207      * @param text content value text
208      * @throws IOException on error writing to document
209      */

210
211     public void writeTextContent(String JavaDoc text) throws IOException JavaDoc {
212         m_escaper.writeContent(text, m_writer);
213         m_textSeen = m_contentSeen = true;
214     }
215     
216     /**
217      * Write CDATA text to document. This needs to write the text with any
218      * appropriate escaping.
219      *
220      * @param text content value text
221      * @throws IOException on error writing to document
222      */

223
224     public void writeCData(String JavaDoc text) throws IOException JavaDoc {
225         m_escaper.writeCData(text, m_writer);
226         m_textSeen = m_contentSeen = true;
227     }
228     
229     /**
230      * Request output indent. The writer implementation should normally indent
231      * output as appropriate. This method can be used to request indenting of
232      * output that might otherwise not be indented. The normal effect when used
233      * with a text-oriented writer should be to output the appropriate line end
234      * sequence followed by the appropriate number of indent characters for the
235      * current nesting level.
236      *
237      * @throws IOException on error writing to document
238      */

239
240     public void indent() throws IOException JavaDoc {
241         if (m_indent) {
242             int length = m_indentBase + m_nestingDepth * m_indentPerLevel;
243             if (length > m_indentSequence.length) {
244                 int use = Math.max(length,
245                     m_indentSequence.length*2 - m_indentBase);
246                 char[] grow = new char[use];
247                 System.arraycopy(m_indentSequence, 0, grow, 0,
248                     m_indentSequence.length);
249                 for (int i = m_indentSequence.length; i < use; i++) {
250                     grow[i] = grow[m_indentBase];
251                 }
252                 m_indentSequence = grow;
253             }
254             m_writer.write(m_indentSequence, 0, length);
255         }
256     }
257     
258     /**
259      * Close document output. Completes writing of document output, including
260      * closing the output medium.
261      *
262      * @throws IOException on error writing to document
263      */

264
265     public void close() throws IOException JavaDoc {
266         if (m_writer != null) {
267             indent();
268             m_writer.flush();
269             m_writer.close();
270             m_writer = null;
271         }
272     }
273 }
Popular Tags