001: /*
002: Copyright (c) 2005, Dennis M. Sosnoski.
003: All rights reserved.
004:
005: Redistribution and use in source and binary forms, with or without modification,
006: are permitted provided that the following conditions are met:
007:
008: * Redistributions of source code must retain the above copyright notice, this
009: list of conditions and the following disclaimer.
010: * Redistributions in binary form must reproduce the above copyright notice,
011: this list of conditions and the following disclaimer in the documentation
012: and/or other materials provided with the distribution.
013: * Neither the name of JiBX nor the names of its contributors may be used
014: to endorse or promote products derived from this software without specific
015: prior written permission.
016:
017: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
018: ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
019: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
021: ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028:
029: package org.jibx.runtime.impl;
030:
031: import java.io.IOException;
032:
033: import javax.xml.stream.XMLStreamException;
034: import javax.xml.stream.XMLStreamWriter;
035:
036: import org.jibx.runtime.IXMLWriter;
037:
038: /**
039: * Writer generating StAX parse event stream output.
040: *
041: * @author Dennis M. Sosnoski
042: * @version 1.0
043: */
044: public class StAXWriter extends XMLWriterNamespaceBase {
045: /** Target for parse event stream. */
046: private XMLStreamWriter m_writer;
047:
048: /**
049: * Constructor.
050: *
051: * @param uris ordered array of URIs for namespaces used in document (must
052: * be constant; the value in position 0 must always be the empty string "",
053: * and the value in position 1 must always be the XML namespace
054: * "http://www.w3.org/XML/1998/namespace")
055: */
056: public StAXWriter(String[] uris) {
057: super (uris);
058: }
059:
060: /**
061: * Constructor with writer supplied.
062: *
063: * @param uris ordered array of URIs for namespaces used in document (must
064: * be constant; the value in position 0 must always be the empty string "",
065: * and the value in position 1 must always be the XML namespace
066: * "http://www.w3.org/XML/1998/namespace")
067: * @param wrtr StAX writer for parse event output
068: */
069: public StAXWriter(String[] uris, XMLStreamWriter wrtr) {
070: this (uris);
071: m_writer = wrtr;
072: }
073:
074: /**
075: * Copy constructor. This initializes the writer and extension namespace
076: * information from an existing instance.
077: *
078: * @param base existing instance
079: * @param uris ordered array of URIs for namespaces used in document
080: */
081: public StAXWriter(StAXWriter base, String[] uris) {
082: super (base, uris);
083: m_writer = base.m_writer;
084: }
085:
086: /**
087: * Set StAX writer.
088: *
089: * @param wrtr StAX writer for parse event output
090: */
091: public void setWriter(XMLStreamWriter wrtr) {
092: m_writer = wrtr;
093: }
094:
095: /* (non-Javadoc)
096: * @see org.jibx.runtime.impl.XMLWriterNamespaceBase#defineNamespace(int, java.lang.String)
097: */
098: protected void defineNamespace(int index, String prefix)
099: throws IOException {
100: /* try {
101:
102: // inform writer of new namespace usage
103: String uri = getNamespaceUri(index);
104: if (prefix.length() == 0) {
105: m_writer.setDefaultNamespace(uri);
106: } else {
107: m_writer.setPrefix(prefix, uri);
108: }
109:
110: } catch (XMLStreamException e) {
111: throw new IOException("Error writing to stream: " + e.getMessage());
112: } */
113: }
114:
115: /* (non-Javadoc)
116: * @see org.jibx.runtime.impl.XMLWriterNamespaceBase#undefineNamespace(int)
117: */
118: protected void undefineNamespace(int index) {
119: }
120:
121: /* (non-Javadoc)
122: * @see org.jibx.runtime.IXMLWriter#setIndentSpaces(int, java.lang.String, char)
123: */
124: public void setIndentSpaces(int count, String newline, char indent) {
125: }
126:
127: /* (non-Javadoc)
128: * @see org.jibx.runtime.IXMLWriter#writeXMLDecl(java.lang.String, java.lang.String, java.lang.String)
129: */
130: public void writeXMLDecl(String version, String encoding,
131: String standalone) throws IOException {
132: try {
133: m_writer.writeStartDocument(version, encoding);
134: } catch (XMLStreamException e) {
135: throw new IOException("Error writing to stream: "
136: + e.getMessage());
137: }
138: }
139:
140: /* (non-Javadoc)
141: * @see org.jibx.runtime.IXMLWriter#startTagOpen(int, java.lang.String)
142: */
143: public void startTagOpen(int index, String name) throws IOException {
144: try {
145:
146: // write start element, without or with namespace
147: if (index == 0) {
148: m_writer.writeStartElement(name);
149: } else {
150: m_writer.writeStartElement(getNamespacePrefix(index),
151: name, getNamespaceUri(index));
152: }
153:
154: // increment nesting for any possible content
155: incrementNesting();
156:
157: } catch (XMLStreamException e) {
158: throw new IOException("Error writing to stream: "
159: + e.getMessage());
160: }
161: }
162:
163: /* (non-Javadoc)
164: * @see org.jibx.runtime.IXMLWriter#startTagNamespaces(int, java.lang.String, int[], java.lang.String[])
165: */
166: public void startTagNamespaces(int index, String name, int[] nums,
167: String[] prefs) throws IOException {
168: try {
169:
170: // find the namespaces actually being declared
171: int[] deltas = openNamespaces(nums, prefs);
172:
173: // open the start tag
174: startTagOpen(index, name);
175:
176: // write the namespace declarations
177: for (int i = 0; i < deltas.length; i++) {
178: int slot = deltas[i];
179: String prefix = getNamespacePrefix(slot);
180: String uri = getNamespaceUri(slot);
181: if (prefix.length() > 0) {
182: m_writer.writeNamespace(prefix, uri);
183: } else {
184: m_writer.writeDefaultNamespace(uri);
185: }
186: }
187:
188: } catch (XMLStreamException e) {
189: throw new IOException("Error writing to stream: "
190: + e.getMessage());
191: }
192: }
193:
194: /* (non-Javadoc)
195: * @see org.jibx.runtime.IXMLWriter#addAttribute(int, java.lang.String, java.lang.String)
196: */
197: public void addAttribute(int index, String name, String value)
198: throws IOException {
199: try {
200: if (index == 0) {
201: m_writer.writeAttribute(name, value);
202: } else {
203: m_writer.writeAttribute(getNamespacePrefix(index),
204: getNamespaceUri(index), name, value);
205: }
206: } catch (XMLStreamException e) {
207: throw new IOException("Error writing to stream: "
208: + e.getMessage());
209: }
210: }
211:
212: /* (non-Javadoc)
213: * @see org.jibx.runtime.IXMLWriter#closeStartTag()
214: */
215: public void closeStartTag() throws IOException {
216: }
217:
218: /* (non-Javadoc)
219: * @see org.jibx.runtime.IXMLWriter#closeEmptyTag()
220: */
221: public void closeEmptyTag() throws IOException {
222: try {
223: m_writer.writeEndElement();
224: decrementNesting();
225: } catch (XMLStreamException e) {
226: throw new IOException("Error writing to stream: "
227: + e.getMessage());
228: }
229: }
230:
231: /* (non-Javadoc)
232: * @see org.jibx.runtime.IXMLWriter#startTagClosed(int, java.lang.String)
233: */
234: public void startTagClosed(int index, String name)
235: throws IOException {
236: startTagOpen(index, name);
237: }
238:
239: /* (non-Javadoc)
240: * @see org.jibx.runtime.IXMLWriter#endTag(int, java.lang.String)
241: */
242: public void endTag(int index, String name) throws IOException {
243: // not valid approach in general, but okay for StAX case
244: closeEmptyTag();
245: }
246:
247: /* (non-Javadoc)
248: * @see org.jibx.runtime.IXMLWriter#writeTextContent(java.lang.String)
249: */
250: public void writeTextContent(String text) throws IOException {
251: try {
252: m_writer.writeCharacters(text);
253: } catch (XMLStreamException e) {
254: throw new IOException("Error writing to stream: "
255: + e.getMessage());
256: }
257: }
258:
259: /* (non-Javadoc)
260: * @see org.jibx.runtime.IXMLWriter#writeCData(java.lang.String)
261: */
262: public void writeCData(String text) throws IOException {
263: try {
264: m_writer.writeCData(text);
265: } catch (XMLStreamException e) {
266: throw new IOException("Error writing to stream: "
267: + e.getMessage());
268: }
269: }
270:
271: /* (non-Javadoc)
272: * @see org.jibx.runtime.IXMLWriter#writeComment(java.lang.String)
273: */
274: public void writeComment(String text) throws IOException {
275: try {
276: m_writer.writeComment(text);
277: } catch (XMLStreamException e) {
278: throw new IOException("Error writing to stream: "
279: + e.getMessage());
280: }
281: }
282:
283: /* (non-Javadoc)
284: * @see org.jibx.runtime.IXMLWriter#writeEntityRef(java.lang.String)
285: */
286: public void writeEntityRef(String name) throws IOException {
287: try {
288: m_writer.writeEntityRef(name);
289: } catch (XMLStreamException e) {
290: throw new IOException("Error writing to stream: "
291: + e.getMessage());
292: }
293: }
294:
295: /* (non-Javadoc)
296: * @see org.jibx.runtime.IXMLWriter#writeDocType(java.lang.String, java.lang.String, java.lang.String, java.lang.String)
297: */
298: public void writeDocType(String name, String sys, String pub,
299: String subset) throws IOException {
300: try {
301: StringBuffer buff = new StringBuffer();
302: buff.append("<!DOCTYPE ");
303: buff.append(name);
304: buff.append(' ');
305: if (sys != null) {
306: if (pub == null) {
307: buff.append("SYSTEM \"");
308: buff.append(sys);
309: } else {
310: buff.append("PUBLIC \"");
311: buff.append(pub);
312: buff.append("\" \"");
313: buff.append(sys);
314: }
315: buff.append('"');
316: }
317: if (subset != null) {
318: buff.append('[');
319: buff.append(subset);
320: buff.append(']');
321: }
322: buff.append('>');
323: m_writer.writeDTD(buff.toString());
324: } catch (XMLStreamException e) {
325: throw new IOException("Error writing to stream: "
326: + e.getMessage());
327: }
328: }
329:
330: /* (non-Javadoc)
331: * @see org.jibx.runtime.IXMLWriter#writePI(java.lang.String, java.lang.String)
332: */
333: public void writePI(String target, String data) throws IOException {
334: try {
335: m_writer.writeProcessingInstruction(target, data);
336: } catch (XMLStreamException e) {
337: throw new IOException("Error writing to stream: "
338: + e.getMessage());
339: }
340: }
341:
342: /* (non-Javadoc)
343: * @see org.jibx.runtime.IXMLWriter#indent()
344: */
345: public void indent() throws IOException {
346: }
347:
348: /* (non-Javadoc)
349: * @see org.jibx.runtime.IXMLWriter#flush()
350: */
351: public void flush() throws IOException {
352: // internal flush only, do not pass through to writer
353: }
354:
355: /* (non-Javadoc)
356: * @see org.jibx.runtime.IXMLWriter#close()
357: */
358: public void close() throws IOException {
359: try {
360: m_writer.close();
361: } catch (XMLStreamException e) {
362: throw new IOException("Error closing stream: "
363: + e.getMessage());
364: }
365: }
366:
367: /**
368: * Create a child writer instance to be used for a separate binding. The
369: * child writer inherits the output handling from this writer, while using
370: * the supplied namespace URIs.
371: *
372: * @param uris ordered array of URIs for namespaces used in document
373: * (see {@link #StAXWriter(String[])})
374: * @return child writer
375: */
376: public IXMLWriter createChildWriter(String[] uris) {
377: return new StAXWriter(this, uris);
378: }
379: }
|