001: /*
002: * $Id: XMLStreamEventReader.java,v 1.3 2004/07/12 15:38:06 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;
035:
036: import javanet.staxutils.events.EventAllocator;
037:
038: import javax.xml.stream.XMLEventReader;
039: import javax.xml.stream.XMLStreamException;
040: import javax.xml.stream.XMLStreamReader;
041: import javax.xml.stream.events.XMLEvent;
042: import javax.xml.stream.util.XMLEventAllocator;
043:
044: /**
045: * {@link XMLEventReader} implementation based on a {@link XMLStreamReader} and
046: * an {@link XMLEventAllocator}.
047: *
048: * @author Christian Niles
049: * @version $Revision: 1.3 $
050: */
051: public class XMLStreamEventReader implements XMLEventReader {
052:
053: /** The underlying stream reader. */
054: private XMLStreamReader reader;
055:
056: /** The event allocator used to create events. */
057: private XMLEventAllocator allocator;
058:
059: /** Field used to cache peek()ed events. */
060: private XMLEvent nextEvent;
061:
062: /** Whether the reader is closed or not. */
063: private boolean closed;
064:
065: public XMLStreamEventReader(XMLStreamReader reader) {
066:
067: this .reader = reader;
068: this .allocator = new EventAllocator();
069:
070: }
071:
072: public XMLStreamEventReader(XMLStreamReader reader,
073: XMLEventAllocator allocator) {
074:
075: this .reader = reader;
076: this .allocator = (allocator == null ? new EventAllocator()
077: : allocator);
078:
079: }
080:
081: /**
082: * No properties are supported, so this always throws
083: * {@link IllegalArgumentException}.
084: */
085: public Object getProperty(String name)
086: throws IllegalArgumentException {
087:
088: throw new IllegalArgumentException("Unknown property: " + name);
089:
090: }
091:
092: public synchronized boolean hasNext() {
093:
094: if (closed) {
095:
096: return false;
097:
098: }
099:
100: try {
101:
102: return reader.hasNext();
103:
104: } catch (XMLStreamException e) {
105:
106: // TODO how to handle inconsistency?
107: return false;
108:
109: }
110:
111: }
112:
113: public synchronized XMLEvent nextTag() throws XMLStreamException {
114:
115: if (closed) {
116:
117: throw new XMLStreamException("Stream has been closed");
118:
119: }
120:
121: nextEvent = null;
122: reader.nextTag();
123: return nextEvent();
124:
125: }
126:
127: public synchronized String getElementText()
128: throws XMLStreamException {
129:
130: if (closed) {
131:
132: throw new XMLStreamException("Stream has been closed");
133:
134: }
135:
136: // null the peeked event
137: this .nextEvent = null;
138: return reader.getElementText();
139:
140: }
141:
142: public synchronized XMLEvent nextEvent() throws XMLStreamException {
143:
144: if (closed) {
145:
146: throw new XMLStreamException("Stream has been closed");
147:
148: }
149:
150: XMLEvent event;
151: if (nextEvent != null) {
152:
153: event = nextEvent;
154: nextEvent = null;
155:
156: } else {
157:
158: event = allocateEvent();
159: reader.next();
160:
161: }
162:
163: return event;
164:
165: }
166:
167: public synchronized XMLEvent peek() throws XMLStreamException {
168:
169: if (closed) {
170:
171: throw new XMLStreamException("Stream has been closed");
172:
173: }
174:
175: if (nextEvent == null) {
176:
177: nextEvent = allocateEvent();
178: reader.next();
179:
180: }
181:
182: return nextEvent;
183:
184: }
185:
186: public Object next() {
187:
188: try {
189:
190: return nextEvent();
191:
192: } catch (XMLStreamException e) {
193:
194: // TODO throw a more descriptive exception?
195: throw new RuntimeException(e);
196:
197: }
198:
199: }
200:
201: public void remove() {
202:
203: throw new UnsupportedOperationException();
204:
205: }
206:
207: public synchronized void close() throws XMLStreamException {
208:
209: if (!closed) {
210:
211: reader.close();
212: closed = true;
213: nextEvent = null;
214: reader = null;
215: allocator = null;
216:
217: }
218:
219: }
220:
221: /**
222: * Reads the next event from the underlying reader.
223: *
224: * @return The allocated {@link XMLEvent}.
225: * @throws XMLStreamException If an error occurs reading the underlying stream.
226: */
227: protected XMLEvent allocateEvent() throws XMLStreamException {
228:
229: return allocator.allocate(reader);
230:
231: }
232:
233: }
|