1/*
2 * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 * THIS FILE WAS MODIFIED BY SUN MICROSYSTEMS, INC.
26 */
27
28package com.sun.xml.internal.fastinfoset.stax.events;
29
30import com.sun.xml.internal.fastinfoset.stax.*;
31import java.util.NoSuchElementException;
32import javax.xml.stream.XMLInputFactory;
33import javax.xml.stream.XMLStreamException;
34import javax.xml.stream.XMLStreamReader;
35import javax.xml.stream.events.XMLEvent;
36import javax.xml.stream.util.XMLEventAllocator;
37import com.sun.xml.internal.fastinfoset.CommonResourceBundle;
38
39
40
41public class StAXEventReader implements javax.xml.stream.XMLEventReader{
42    protected XMLStreamReader _streamReader ;
43    protected XMLEventAllocator _eventAllocator;
44    private XMLEvent _currentEvent;     //the current event
45    private XMLEvent[] events = new XMLEvent[3];
46    private int size = 3;
47    private int currentIndex = 0;
48    private boolean hasEvent = false;   //true when current event exists, false initially & at end
49
50    //only constructor will do because we delegate everything to underlying XMLStreamReader
51    public StAXEventReader(XMLStreamReader reader) throws  XMLStreamException {
52        _streamReader = reader ;
53        _eventAllocator = (XMLEventAllocator)reader.getProperty(XMLInputFactory.ALLOCATOR);
54        if(_eventAllocator == null){
55            _eventAllocator = new StAXEventAllocatorBase();
56        }
57        //initialize
58        if (_streamReader.hasNext())
59        {
60            _streamReader.next();
61            _currentEvent =_eventAllocator.allocate(_streamReader);
62            events[0] = _currentEvent;
63            hasEvent = true;
64        } else {
65            throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.noElement"));
66        }
67    }
68
69    public boolean hasNext() {
70        return hasEvent;
71    }
72
73    public XMLEvent nextEvent() throws XMLStreamException {
74        XMLEvent event = null;
75        XMLEvent nextEvent = null;
76        if (hasEvent)
77        {
78            event = events[currentIndex];
79            events[currentIndex] = null;
80            if (_streamReader.hasNext())
81            {
82                //advance and read the next
83                _streamReader.next();
84                nextEvent = _eventAllocator.allocate(_streamReader);
85                if (++currentIndex==size)
86                    currentIndex = 0;
87                events[currentIndex] = nextEvent;
88                hasEvent = true;
89            } else {
90                _currentEvent = null;
91                hasEvent = false;
92            }
93            return event;
94        }
95        else{
96            throw new NoSuchElementException();
97        }
98    }
99
100    public void remove(){
101        //stream reader is read-only.
102        throw new java.lang.UnsupportedOperationException();
103    }
104
105
106    public void close() throws XMLStreamException {
107        _streamReader.close();
108    }
109
110    /** Reads the content of a text-only element. Precondition:
111     * the current event is START_ELEMENT. Postcondition:
112     * The current event is the corresponding END_ELEMENT.
113     * @throws XMLStreamException if the current event is not a START_ELEMENT
114     * or if a non text element is encountered
115     */
116    public String getElementText() throws XMLStreamException {
117        if(!hasEvent) {
118            throw new NoSuchElementException();
119        }
120
121        if(!_currentEvent.isStartElement()) {
122            StAXDocumentParser parser = (StAXDocumentParser)_streamReader;
123            return parser.getElementText(true);
124        } else {
125            return _streamReader.getElementText();
126        }
127    }
128
129    /** Get the value of a feature/property from the underlying implementation
130     * @param name The name of the property
131     * @return The value of the property
132     * @throws IllegalArgumentException if the property is not supported
133     */
134    public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException {
135        return _streamReader.getProperty(name) ;
136    }
137
138    /** Skips any insignificant space events until a START_ELEMENT or
139     * END_ELEMENT is reached. If anything other than space characters are
140     * encountered, an exception is thrown. This method should
141     * be used when processing element-only content because
142     * the parser is not able to recognize ignorable whitespace if
143     * the DTD is missing or not interpreted.
144     * @throws XMLStreamException if anything other than space characters are encountered
145     */
146    public XMLEvent nextTag() throws XMLStreamException {
147        if(!hasEvent) {
148            throw new NoSuchElementException();
149        }
150        StAXDocumentParser parser = (StAXDocumentParser)_streamReader;
151        parser.nextTag(true);
152        return _eventAllocator.allocate(_streamReader);
153    }
154
155    //XMLEventReader extends Iterator;
156    public Object next() {
157        try{
158            return nextEvent();
159        }catch(XMLStreamException streamException){
160            return null;
161        }
162    }
163
164    public XMLEvent peek() throws XMLStreamException{
165        if (!hasEvent)
166             throw new XMLStreamException(CommonResourceBundle.getInstance().getString("message.noElement"));
167        _currentEvent = events[currentIndex];
168        return _currentEvent;
169    }
170
171    public void setAllocator(XMLEventAllocator allocator) {
172        if (allocator == null)
173            throw new IllegalArgumentException(CommonResourceBundle.getInstance().getString("message.nullXMLEventAllocator"));
174
175        _eventAllocator = allocator;
176    }
177
178
179}
180