001: /*
002: * $Id: StreamEventWriter.java,v 1.4 2004/07/15 02:09:59 cniles Exp $
003: *
004: * Copyright (c) 2004, Christian Niles, unit12.net
005: * All rights reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions are met:
009: *
010: * * Redistributions of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * * Redistributions in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in the
015: * documentation and/or other materials provided with the distribution.
016: *
017: * * Neither the name of Christian Niles, Unit12, nor the names of its
018: * contributors may be used to endorse or promote products derived from
019: * this software without specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
022: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
023: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
024: * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
025: * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
026: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
027: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
028: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
029: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
030: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
031: * POSSIBILITY OF SUCH DAMAGE.
032: *
033: */
034: package javanet.staxutils.io;
035:
036: import java.io.File;
037: import java.io.FileWriter;
038: import java.io.IOException;
039: import java.io.OutputStream;
040: import java.io.OutputStreamWriter;
041: import java.io.Writer;
042:
043: import javanet.staxutils.BaseXMLEventWriter;
044:
045: import javax.xml.stream.XMLStreamException;
046: import javax.xml.stream.events.StartElement;
047: import javax.xml.stream.events.XMLEvent;
048:
049: /**
050: * {@link javax.xml.stream.XMLEventWriter} that writes events to a character stream
051: * using {@link XMLEvent#writeAsEncodedUnicode(Writer)}.
052: *
053: * @author Christian Niles
054: * @version $Revision: 1.4 $
055: */
056: public class StreamEventWriter extends BaseXMLEventWriter {
057:
058: /** The underlying {@link Writer}. */
059: private Writer writer;
060:
061: /**
062: * Constructs a new <code>StreamEventWriter</code> that writes to a file.
063: *
064: * @param file The file to write.
065: * @throws IOException If the file couldn't be opened.
066: */
067: public StreamEventWriter(File file) throws IOException {
068:
069: this (new FileWriter(file));
070:
071: }
072:
073: /**
074: * Constructs a new <code>StreamEventWriter</code> that writes to a binary
075: * stream.
076: *
077: * @param os The stream to write.
078: */
079: public StreamEventWriter(OutputStream os) {
080:
081: this (new OutputStreamWriter(os));
082:
083: }
084:
085: /**
086: * Constructs a new <code>StreamEventWriter</code> that writes to a character
087: * stream.
088: *
089: * @param writer The stream to write.
090: */
091: public StreamEventWriter(Writer writer) {
092:
093: this .writer = writer;
094:
095: }
096:
097: public synchronized void flush() throws XMLStreamException {
098:
099: super .flush();
100: try {
101:
102: writer.flush();
103:
104: } catch (IOException e) {
105:
106: throw new XMLStreamException(e);
107:
108: }
109:
110: }
111:
112: /**
113: * Saved reference to most recent start element. This is used to properly
114: * write empty elements. Each startElement event is saved here until the
115: * next event is received, at which point it will be written as a start or
116: * empty element if it is followed directly by an EndElement.
117: */
118: private StartElement savedStart;
119:
120: protected void sendEvent(XMLEvent event) throws XMLStreamException {
121:
122: try {
123:
124: // Check if we have a cached start tag. If we do, then we should
125: // check if this event is actually an end tag, so we can properly
126: // write an empty element.
127: if (savedStart != null) {
128:
129: StartElement start = savedStart;
130: savedStart = null;
131:
132: if (event.getEventType() == XMLEvent.END_ELEMENT) {
133:
134: // this end tag directly followed a start tag, so send
135: // the underlying writer an empty start element
136: XMLWriterUtils.writeStartElement(start, true,
137: writer);
138: writer.flush();
139: return;
140:
141: } else {
142:
143: // element has content, so send a regular start tag
144: XMLWriterUtils.writeStartElement(start, false,
145: writer);
146:
147: }
148:
149: }
150:
151: if (event.isStartElement()) {
152:
153: savedStart = event.asStartElement();
154:
155: } else {
156:
157: event.writeAsEncodedUnicode(writer);
158:
159: }
160:
161: } catch (IOException e) {
162:
163: throw new XMLStreamException(e);
164:
165: }
166:
167: }
168:
169: }
|