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