001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.xml;
014
015import java.io.*;
016
017import javax.xml.namespace.*;
018import javax.xml.stream.*;
019import javax.xml.stream.util.*;
020
021import org.apache.juneau.parser.*;
022
023/**
024 * Wrapper class around a {@link XMLStreamReader}.
025 *
026 * <p>
027 * The purpose is to encapsulate the reader with the {@link ParserPipe} object so that it can be retrieved for
028 * debugging purposes.
029 */
030public final class XmlReader implements XMLStreamReader, Positionable {
031
032   private final ParserPipe pipe;
033   private final XMLStreamReader sr;
034
035   /**
036    * Constructor.
037    *
038    * @param pipe The parser input.
039    * @param validating The value for the {@link XMLInputFactory#IS_VALIDATING} setting.
040    * @param reporter The value for the {@link XMLInputFactory#REPORTER} setting.
041    * @param resolver The value for the {@link XMLInputFactory#RESOLVER} setting.
042    * @param eventAllocator The value for the {@link XMLInputFactory#ALLOCATOR} setting.
043    * @throws IOException Thrown by underling
044    * @throws XMLStreamException Thrown by underlying XML stream.
045    */
046   protected XmlReader(ParserPipe pipe, boolean validating, XMLReporter reporter, XMLResolver resolver, XMLEventAllocator eventAllocator) throws IOException, XMLStreamException {
047      this.pipe = pipe;
048      try {
049         @SuppressWarnings("resource")
050         Reader r = pipe.getBufferedReader();
051         XMLInputFactory factory = XMLInputFactory.newInstance();
052         factory.setProperty(XMLInputFactory.IS_VALIDATING, validating);
053         factory.setProperty(XMLInputFactory.IS_COALESCING, true);
054         factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
055         factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);
056         if (factory.isPropertySupported(XMLInputFactory.REPORTER) && reporter != null)
057            factory.setProperty(XMLInputFactory.REPORTER, reporter);
058         if (factory.isPropertySupported(XMLInputFactory.RESOLVER) && resolver != null)
059            factory.setProperty(XMLInputFactory.RESOLVER, resolver);
060         if (factory.isPropertySupported(XMLInputFactory.ALLOCATOR) && eventAllocator != null)
061            factory.setProperty(XMLInputFactory.ALLOCATOR, eventAllocator);
062         sr = factory.createXMLStreamReader(r);
063         sr.nextTag();
064         pipe.setPositionable(this);
065      } catch (Error e) {
066         throw new IOException(e.getLocalizedMessage());
067      }
068   }
069
070   /**
071    * Returns the pipe passed into the constructor.
072    *
073    * @return The pipe passed into the constructor.
074    */
075   public ParserPipe getPipe() {
076      return pipe;
077   }
078
079   @Override /* XMLStreamReader */
080   public void close() throws XMLStreamException {
081      sr.close();
082   }
083
084   @Override /* XMLStreamReader */
085   public int getAttributeCount() {
086      return sr.getAttributeCount();
087   }
088
089   @Override /* XMLStreamReader */
090   public String getAttributeLocalName(int index) {
091      return sr.getAttributeLocalName(index);
092   }
093
094   @Override /* XMLStreamReader */
095   public QName getAttributeName(int index) {
096      return sr.getAttributeName(index);
097   }
098
099   @Override /* XMLStreamReader */
100   public String getAttributeNamespace(int index) {
101      return sr.getAttributeNamespace(index);
102   }
103
104   @Override /* XMLStreamReader */
105   public String getAttributePrefix(int index) {
106      return sr.getAttributePrefix(index);
107   }
108
109   @Override /* XMLStreamReader */
110   public String getAttributeType(int index) {
111      return sr.getAttributeType(index);
112   }
113
114   @Override /* XMLStreamReader */
115   public String getAttributeValue(int index) {
116      return sr.getAttributeValue(index);
117   }
118
119   @Override /* XMLStreamReader */
120   public String getAttributeValue(String namespaceURI, String localName) {
121      return sr.getAttributeValue(namespaceURI, localName);
122   }
123
124   @Override /* XMLStreamReader */
125   public String getCharacterEncodingScheme() {
126      return sr.getCharacterEncodingScheme();
127   }
128
129   @Override /* XMLStreamReader */
130   public String getElementText() throws XMLStreamException {
131      return sr.getElementText();
132   }
133
134   @Override /* XMLStreamReader */
135   public String getEncoding() {
136      return sr.getEncoding();
137   }
138
139   @Override /* XMLStreamReader */
140   public int getEventType() {
141      return sr.getEventType();
142   }
143
144   @Override /* XMLStreamReader */
145   public String getLocalName() {
146      return sr.getLocalName();
147   }
148
149   @Override /* XMLStreamReader */
150   public Location getLocation() {
151      return sr.getLocation();
152   }
153
154   @Override /* XMLStreamReader */
155   public QName getName() {
156      return sr.getName();
157   }
158
159   @Override /* XMLStreamReader */
160   public NamespaceContext getNamespaceContext() {
161      return sr.getNamespaceContext();
162   }
163
164   @Override /* XMLStreamReader */
165   public int getNamespaceCount() {
166      return sr.getNamespaceCount();
167   }
168
169   @Override /* XMLStreamReader */
170   public String getNamespacePrefix(int index) {
171      return sr.getNamespacePrefix(index);
172   }
173
174   @Override /* XMLStreamReader */
175   public String getNamespaceURI() {
176      return sr.getNamespaceURI();
177   }
178
179   @Override /* XMLStreamReader */
180   public String getNamespaceURI(String prefix) {
181      return sr.getNamespaceURI(prefix);
182   }
183
184   @Override /* XMLStreamReader */
185   public String getNamespaceURI(int index) {
186      return sr.getNamespaceURI(index);
187   }
188
189   @Override /* XMLStreamReader */
190   public String getPIData() {
191      return sr.getPIData();
192   }
193
194   @Override /* XMLStreamReader */
195   public String getPITarget() {
196      return sr.getPITarget();
197   }
198
199   @Override /* XMLStreamReader */
200   public String getPrefix() {
201      return sr.getPrefix();
202   }
203
204   @Override /* XMLStreamReader */
205   public Object getProperty(String name) throws IllegalArgumentException {
206      return sr.getProperty(name);
207   }
208
209   @Override /* XMLStreamReader */
210   public String getText() {
211      return sr.getText();
212   }
213
214   @Override /* XMLStreamReader */
215   public char[] getTextCharacters() {
216      return sr.getTextCharacters();
217   }
218
219   @Override /* XMLStreamReader */
220   public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException {
221      return sr.getTextCharacters(sourceStart, target, targetStart, length);
222   }
223
224   @Override /* XMLStreamReader */
225   public int getTextLength() {
226      return sr.getTextLength();
227   }
228
229   @Override /* XMLStreamReader */
230   public int getTextStart() {
231      return sr.getTextStart();
232   }
233
234   @Override /* XMLStreamReader */
235   public String getVersion() {
236      return sr.getVersion();
237   }
238
239   @Override /* XMLStreamReader */
240   public boolean hasName() {
241      return sr.hasName();
242   }
243
244   @Override /* XMLStreamReader */
245   public boolean hasNext() throws XMLStreamException {
246      return sr.hasNext();
247   }
248
249   @Override /* XMLStreamReader */
250   public boolean hasText() {
251      return sr.hasText();
252   }
253
254   @Override /* XMLStreamReader */
255   public boolean isAttributeSpecified(int index) {
256      return sr.isAttributeSpecified(index);
257   }
258
259   @Override /* XMLStreamReader */
260   public boolean isCharacters() {
261      return sr.isCharacters();
262   }
263
264   @Override /* XMLStreamReader */
265   public boolean isEndElement() {
266      return sr.isEndElement();
267   }
268
269   @Override /* XMLStreamReader */
270   public boolean isStandalone() {
271      return sr.isStandalone();
272   }
273
274   @Override /* XMLStreamReader */
275   public boolean isStartElement() {
276      return sr.isStartElement();
277   }
278
279   @Override /* XMLStreamReader */
280   public boolean isWhiteSpace() {
281      return sr.isWhiteSpace();
282   }
283
284   @Override /* XMLStreamReader */
285   public int next() throws XMLStreamException {
286      return sr.next();
287   }
288
289   @Override /* XMLStreamReader */
290   public int nextTag() throws XMLStreamException {
291      return sr.nextTag();
292   }
293
294   @Override /* XMLStreamReader */
295   public void require(int type, String namespaceURI, String localName) throws XMLStreamException {
296      sr.require(type, namespaceURI, localName);
297   }
298
299   @Override /* XMLStreamReader */
300   public boolean standaloneSet() {
301      return sr.standaloneSet();
302   }
303
304   @Override /* Positionable */
305   public Position getPosition() {
306      Location l = getLocation();
307      return new Position(l.getLineNumber(), l.getColumnNumber());
308   }
309}