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.commons.utils.ThrowableUtils.*; 020import static org.apache.juneau.commons.utils.Utils.*; 021 022import java.io.*; 023 024import javax.xml.namespace.*; 025import javax.xml.stream.*; 026import javax.xml.stream.util.*; 027 028import org.apache.juneau.parser.*; 029 030/** 031 * Wrapper class around a {@link XMLStreamReader}. 032 * 033 * <p> 034 * The purpose is to encapsulate the reader with the {@link ParserPipe} object so that it can be retrieved for 035 * debugging purposes. 036 * 037 * <h5 class='section'>See Also:</h5><ul> 038 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/XmlBasics">XML Basics</a> 039 * </ul> 040 */ 041public class XmlReader implements XMLStreamReader, Positionable { 042 043 private final ParserPipe pipe; 044 private final XMLStreamReader sr; 045 046 /** 047 * Constructor. 048 * 049 * @param pipe The parser input. 050 * @param validating The value for the {@link XMLInputFactory#IS_VALIDATING} setting. 051 * @param reporter The value for the {@link XMLInputFactory#REPORTER} setting. 052 * @param resolver The value for the {@link XMLInputFactory#RESOLVER} setting. 053 * @param eventAllocator The value for the {@link XMLInputFactory#ALLOCATOR} setting. 054 * @throws IOException Thrown by underling 055 * @throws XMLStreamException Thrown by underlying XML stream. 056 */ 057 protected XmlReader(ParserPipe pipe, boolean validating, XMLReporter reporter, XMLResolver resolver, XMLEventAllocator eventAllocator) throws IOException, XMLStreamException { 058 this.pipe = pipe; 059 try { 060 @SuppressWarnings("resource") 061 Reader r = pipe.getBufferedReader(); 062 var factory = XMLInputFactory.newInstance(); 063 factory.setProperty(XMLInputFactory.IS_VALIDATING, validating); 064 factory.setProperty(XMLInputFactory.IS_COALESCING, true); 065 factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false); 066 factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false); 067 if (factory.isPropertySupported(XMLInputFactory.REPORTER) && nn(reporter)) 068 factory.setProperty(XMLInputFactory.REPORTER, reporter); 069 if (factory.isPropertySupported(XMLInputFactory.RESOLVER) && nn(resolver)) 070 factory.setProperty(XMLInputFactory.RESOLVER, resolver); 071 if (factory.isPropertySupported(XMLInputFactory.ALLOCATOR) && nn(eventAllocator)) 072 factory.setProperty(XMLInputFactory.ALLOCATOR, eventAllocator); 073 sr = factory.createXMLStreamReader(r); 074 sr.nextTag(); 075 pipe.setPositionable(this); 076 } catch (Error e) { 077 throw castException(IOException.class, e); 078 } 079 } 080 081 @Override /* Overridden from XMLStreamReader */ 082 public void close() throws XMLStreamException { 083 sr.close(); 084 } 085 086 @Override /* Overridden from XMLStreamReader */ 087 public int getAttributeCount() { return sr.getAttributeCount(); } 088 089 @Override /* Overridden from XMLStreamReader */ 090 public String getAttributeLocalName(int index) { 091 return sr.getAttributeLocalName(index); 092 } 093 094 @Override /* Overridden from XMLStreamReader */ 095 public QName getAttributeName(int index) { 096 return sr.getAttributeName(index); 097 } 098 099 @Override /* Overridden from XMLStreamReader */ 100 public String getAttributeNamespace(int index) { 101 return sr.getAttributeNamespace(index); 102 } 103 104 @Override /* Overridden from XMLStreamReader */ 105 public String getAttributePrefix(int index) { 106 return sr.getAttributePrefix(index); 107 } 108 109 @Override /* Overridden from XMLStreamReader */ 110 public String getAttributeType(int index) { 111 return sr.getAttributeType(index); 112 } 113 114 @Override /* Overridden from XMLStreamReader */ 115 public String getAttributeValue(int index) { 116 return sr.getAttributeValue(index); 117 } 118 119 @Override /* Overridden from XMLStreamReader */ 120 public String getAttributeValue(String namespaceURI, String localName) { 121 return sr.getAttributeValue(namespaceURI, localName); 122 } 123 124 @Override /* Overridden from XMLStreamReader */ 125 public String getCharacterEncodingScheme() { return sr.getCharacterEncodingScheme(); } 126 127 @Override /* Overridden from XMLStreamReader */ 128 public String getElementText() throws XMLStreamException { return sr.getElementText(); } 129 130 @Override /* Overridden from XMLStreamReader */ 131 public String getEncoding() { return sr.getEncoding(); } 132 133 @Override /* Overridden from XMLStreamReader */ 134 public int getEventType() { return sr.getEventType(); } 135 136 @Override /* Overridden from XMLStreamReader */ 137 public String getLocalName() { return sr.getLocalName(); } 138 139 @Override /* Overridden from XMLStreamReader */ 140 public Location getLocation() { return sr.getLocation(); } 141 142 @Override /* Overridden from XMLStreamReader */ 143 public QName getName() { return sr.getName(); } 144 145 @Override /* Overridden from XMLStreamReader */ 146 public NamespaceContext getNamespaceContext() { return sr.getNamespaceContext(); } 147 148 @Override /* Overridden from XMLStreamReader */ 149 public int getNamespaceCount() { return sr.getNamespaceCount(); } 150 151 @Override /* Overridden from XMLStreamReader */ 152 public String getNamespacePrefix(int index) { 153 return sr.getNamespacePrefix(index); 154 } 155 156 @Override /* Overridden from XMLStreamReader */ 157 public String getNamespaceURI() { return sr.getNamespaceURI(); } 158 159 @Override /* Overridden from XMLStreamReader */ 160 public String getNamespaceURI(int index) { 161 return sr.getNamespaceURI(index); 162 } 163 164 @Override /* Overridden from XMLStreamReader */ 165 public String getNamespaceURI(String prefix) { 166 return sr.getNamespaceURI(prefix); 167 } 168 169 @Override /* Overridden from XMLStreamReader */ 170 public String getPIData() { return sr.getPIData(); } 171 172 /** 173 * Returns the pipe passed into the constructor. 174 * 175 * @return The pipe passed into the constructor. 176 */ 177 public ParserPipe getPipe() { return pipe; } 178 179 @Override /* Overridden from XMLStreamReader */ 180 public String getPITarget() { return sr.getPITarget(); } 181 182 @Override /* Overridden from Positionable */ 183 public Position getPosition() { 184 var l = getLocation(); 185 return new Position(l.getLineNumber(), l.getColumnNumber()); 186 } 187 188 @Override /* Overridden from XMLStreamReader */ 189 public String getPrefix() { return sr.getPrefix(); } 190 191 @Override /* Overridden from XMLStreamReader */ 192 public Object getProperty(String name) throws IllegalArgumentException { 193 return sr.getProperty(name); 194 } 195 196 @Override /* Overridden from XMLStreamReader */ 197 public String getText() { return sr.getText(); } 198 199 @Override /* Overridden from XMLStreamReader */ 200 public char[] getTextCharacters() { return sr.getTextCharacters(); } 201 202 @Override /* Overridden from XMLStreamReader */ 203 public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) throws XMLStreamException { 204 return sr.getTextCharacters(sourceStart, target, targetStart, length); 205 } 206 207 @Override /* Overridden from XMLStreamReader */ 208 public int getTextLength() { return sr.getTextLength(); } 209 210 @Override /* Overridden from XMLStreamReader */ 211 public int getTextStart() { return sr.getTextStart(); } 212 213 @Override /* Overridden from XMLStreamReader */ 214 public String getVersion() { return sr.getVersion(); } 215 216 @Override /* Overridden from XMLStreamReader */ 217 public boolean hasName() { 218 return sr.hasName(); 219 } 220 221 @Override /* Overridden from XMLStreamReader */ 222 public boolean hasNext() throws XMLStreamException { 223 return sr.hasNext(); 224 } 225 226 @Override /* Overridden from XMLStreamReader */ 227 public boolean hasText() { 228 return sr.hasText(); 229 } 230 231 @Override /* Overridden from XMLStreamReader */ 232 public boolean isAttributeSpecified(int index) { 233 return sr.isAttributeSpecified(index); 234 } 235 236 @Override /* Overridden from XMLStreamReader */ 237 public boolean isCharacters() { return sr.isCharacters(); } 238 239 @Override /* Overridden from XMLStreamReader */ 240 public boolean isEndElement() { return sr.isEndElement(); } 241 242 @Override /* Overridden from XMLStreamReader */ 243 public boolean isStandalone() { return sr.isStandalone(); } 244 245 @Override /* Overridden from XMLStreamReader */ 246 public boolean isStartElement() { return sr.isStartElement(); } 247 248 @Override /* Overridden from XMLStreamReader */ 249 public boolean isWhiteSpace() { return sr.isWhiteSpace(); } 250 251 @Override /* Overridden from XMLStreamReader */ 252 public int next() throws XMLStreamException { 253 return sr.next(); 254 } 255 256 @Override /* Overridden from XMLStreamReader */ 257 public int nextTag() throws XMLStreamException { 258 return sr.nextTag(); 259 } 260 261 @Override /* Overridden from XMLStreamReader */ 262 public void require(int type, String namespaceURI, String localName) throws XMLStreamException { 263 sr.require(type, namespaceURI, localName); 264 } 265 266 @Override /* Overridden from XMLStreamReader */ 267 public boolean standaloneSet() { 268 return sr.standaloneSet(); 269 } 270}