1/* 2 * Copyright (c) 2005, 2006, 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 26package com.sun.xml.internal.stream; 27 28import java.io.InputStream; 29import java.io.Reader; 30 31import javax.xml.stream.*; 32import javax.xml.stream.util.XMLEventAllocator ; 33import javax.xml.transform.Source; 34import javax.xml.transform.stream.StreamSource; 35import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 36import com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl; 37import com.sun.org.apache.xerces.internal.impl.PropertyManager; 38import com.sun.org.apache.xerces.internal.impl.XMLStreamFilterImpl; 39import com.sun.org.apache.xerces.internal.impl.Constants; 40 41/** Factory Implementation for XMLInputFactory. 42 * @author Neeraj Bajaj Sun Microsystems 43 * @author K.Venugopal Sun Microsystems 44 */ 45 46//xxx: Should we be reusing the XMLInputSource object 47public class XMLInputFactoryImpl extends javax.xml.stream.XMLInputFactory { 48 49 50 //List of supported properties and default values. 51 private PropertyManager fPropertyManager = new PropertyManager(PropertyManager.CONTEXT_READER) ; 52 private static final boolean DEBUG = false; 53 54 //Maintain a reference to last reader instantiated. 55 private XMLStreamReaderImpl fTempReader = null ; 56 57 boolean fPropertyChanged = false; 58 //no reader reuse by default 59 boolean fReuseInstance = false; 60 61 /** Creates a new instance of ZephryParserFactory */ 62 public XMLInputFactoryImpl() { 63 64 } 65 66 void initEventReader(){ 67 fPropertyChanged = true; 68 } 69 70 /** 71 * @param inputstream 72 * @throws XMLStreamException 73 * @return 74 */ 75 public XMLEventReader createXMLEventReader(InputStream inputstream) throws XMLStreamException { 76 initEventReader(); 77 //delegate everything to XMLStreamReader 78 return new XMLEventReaderImpl(createXMLStreamReader(inputstream)); 79 } 80 81 public XMLEventReader createXMLEventReader(Reader reader) throws XMLStreamException { 82 initEventReader(); 83 //delegate everything to XMLStreamReader 84 return new XMLEventReaderImpl(createXMLStreamReader(reader)); 85 } 86 87 public XMLEventReader createXMLEventReader(Source source) throws XMLStreamException { 88 initEventReader(); 89 //delegate everything to XMLStreamReader 90 return new XMLEventReaderImpl(createXMLStreamReader(source)); 91 } 92 93 public XMLEventReader createXMLEventReader(String systemId, InputStream inputstream) throws XMLStreamException { 94 initEventReader(); 95 //delegate everything to XMLStreamReader 96 return new XMLEventReaderImpl(createXMLStreamReader(systemId, inputstream)); 97 } 98 99 public XMLEventReader createXMLEventReader(java.io.InputStream stream, String encoding) throws XMLStreamException { 100 initEventReader(); 101 //delegate everything to XMLStreamReader 102 return new XMLEventReaderImpl(createXMLStreamReader(stream, encoding)); 103 } 104 105 public XMLEventReader createXMLEventReader(String systemId, Reader reader) throws XMLStreamException { 106 initEventReader(); 107 //delegate everything to XMLStreamReader 108 return new XMLEventReaderImpl(createXMLStreamReader(systemId, reader)); 109 } 110 111 /** Create a new XMLEventReader from an XMLStreamReader. After being used 112 * to construct the XMLEventReader instance returned from this method 113 * the XMLStreamReader must not be used. 114 * @param reader the XMLStreamReader to read from (may not be modified) 115 * @return a new XMLEventReader 116 * @throws XMLStreamException 117 */ 118 public XMLEventReader createXMLEventReader(XMLStreamReader reader) throws XMLStreamException { 119 120 //xxx: what do we do now -- instance is passed from the application 121 //probably we should check if the state is at the start document, 122 //eventreader call to next() should return START_DOCUMENT and 123 //then delegate every call to underlying streamReader 124 return new XMLEventReaderImpl(reader) ; 125 } 126 127 public XMLStreamReader createXMLStreamReader(InputStream inputstream) throws XMLStreamException { 128 XMLInputSource inputSource = new XMLInputSource(null, null, null, inputstream, null); 129 return getXMLStreamReaderImpl(inputSource); 130 } 131 132 public XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException { 133 XMLInputSource inputSource = new XMLInputSource(null, null, null, reader, null); 134 return getXMLStreamReaderImpl(inputSource); 135 } 136 137 public XMLStreamReader createXMLStreamReader(String systemId, Reader reader) throws XMLStreamException { 138 XMLInputSource inputSource = new XMLInputSource(null,systemId,null,reader,null); 139 return getXMLStreamReaderImpl(inputSource); 140 } 141 142 public XMLStreamReader createXMLStreamReader(Source source) throws XMLStreamException { 143 return new XMLStreamReaderImpl(jaxpSourcetoXMLInputSource(source), 144 new PropertyManager(fPropertyManager)); 145 } 146 147 public XMLStreamReader createXMLStreamReader(String systemId, InputStream inputstream) throws XMLStreamException { 148 XMLInputSource inputSource = new XMLInputSource(null,systemId,null,inputstream,null); 149 return getXMLStreamReaderImpl(inputSource); 150 } 151 152 153 public XMLStreamReader createXMLStreamReader(InputStream inputstream, String encoding) throws XMLStreamException { 154 XMLInputSource inputSource = new XMLInputSource(null,null,null,inputstream,encoding); 155 return getXMLStreamReaderImpl(inputSource); 156 } 157 158 public XMLEventAllocator getEventAllocator() { 159 return (XMLEventAllocator)getProperty(XMLInputFactory.ALLOCATOR); 160 } 161 162 public XMLReporter getXMLReporter() { 163 return (XMLReporter)fPropertyManager.getProperty(XMLInputFactory.REPORTER); 164 } 165 166 public XMLResolver getXMLResolver() { 167 Object object = fPropertyManager.getProperty(XMLInputFactory.RESOLVER); 168 return (XMLResolver)object; 169 //return (XMLResolver)fPropertyManager.getProperty(XMLInputFactory.RESOLVER); 170 } 171 172 public void setXMLReporter(XMLReporter xmlreporter) { 173 fPropertyManager.setProperty(XMLInputFactory.REPORTER, xmlreporter); 174 } 175 176 public void setXMLResolver(XMLResolver xmlresolver) { 177 fPropertyManager.setProperty(XMLInputFactory.RESOLVER, xmlresolver); 178 } 179 180 /** Create a filtered event reader that wraps the filter around the event reader 181 * @param reader the event reader to wrap 182 * @param filter the filter to apply to the event reader 183 * @throws XMLStreamException 184 */ 185 public XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter) throws XMLStreamException { 186 return new EventFilterSupport(reader, filter); 187 } 188 189 /** Create a filtered reader that wraps the filter around the reader 190 * @param reader the reader to filter 191 * @param filter the filter to apply to the reader 192 * @throws XMLStreamException 193 */ 194 public XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) throws XMLStreamException { 195 if( reader != null && filter != null ) 196 return new XMLStreamFilterImpl(reader,filter); 197 198 return null; 199 } 200 201 202 203 /** Get the value of a feature/property from the underlying implementation 204 * @param name The name of the property (may not be null) 205 * @return The value of the property 206 * @throws IllegalArgumentException if the property is not supported 207 */ 208 public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException { 209 if(name == null){ 210 throw new IllegalArgumentException("Property not supported"); 211 } 212 if(fPropertyManager.containsProperty(name)) 213 return fPropertyManager.getProperty(name); 214 throw new IllegalArgumentException("Property not supported"); 215 } 216 217 /** Query the set of fProperties that this factory supports. 218 * 219 * @param name The name of the property (may not be null) 220 * @return true if the property is supported and false otherwise 221 */ 222 public boolean isPropertySupported(String name) { 223 if(name == null) 224 return false ; 225 else 226 return fPropertyManager.containsProperty(name); 227 } 228 229 /** Set a user defined event allocator for events 230 * @param allocator the user defined allocator 231 */ 232 public void setEventAllocator(XMLEventAllocator allocator) { 233 fPropertyManager.setProperty(XMLInputFactory.ALLOCATOR, allocator); 234 } 235 236 /** Allows the user to set specific feature/property on the underlying implementation. The underlying implementation 237 * is not required to support every setting of every property in the specification and may use IllegalArgumentException 238 * to signal that an unsupported property may not be set with the specified value. 239 * @param name The name of the property (may not be null) 240 * @param value The value of the property 241 * @throws java.lang.IllegalArgumentException if the property is not supported 242 */ 243 public void setProperty(java.lang.String name, Object value) throws java.lang.IllegalArgumentException { 244 245 if(name == null || value == null || !fPropertyManager.containsProperty(name) ){ 246 throw new IllegalArgumentException("Property "+name+" is not supported"); 247 } 248 if(name == Constants.REUSE_INSTANCE || name.equals(Constants.REUSE_INSTANCE)){ 249 fReuseInstance = ((Boolean)value).booleanValue(); 250 if(DEBUG)System.out.println("fReuseInstance is set to " + fReuseInstance); 251 }else{//for any other property set the flag 252 //REVISIT: Even in this case instance can be reused, by passing PropertyManager 253 fPropertyChanged = true; 254 } 255 fPropertyManager.setProperty(name,value); 256 } 257 258 XMLStreamReader getXMLStreamReaderImpl(XMLInputSource inputSource) throws javax.xml.stream.XMLStreamException{ 259 //1. if the temp reader is null -- create the instance and return 260 if(fTempReader == null){ 261 fPropertyChanged = false; 262 return fTempReader = new XMLStreamReaderImpl(inputSource, 263 new PropertyManager(fPropertyManager)); 264 } 265 //if factory is configured to reuse the instance & this instance can be reused 266 //& the setProperty() hasn't been called 267 if(fReuseInstance && fTempReader.canReuse() && !fPropertyChanged){ 268 if(DEBUG)System.out.println("Reusing the instance"); 269 //we can make setInputSource() call reset() and this way there wont be two function calls 270 fTempReader.reset(); 271 fTempReader.setInputSource(inputSource); 272 fPropertyChanged = false; 273 return fTempReader; 274 }else{ 275 fPropertyChanged = false; 276 //just return the new instance.. note that we are not setting fTempReader to the newly created instance 277 return fTempReader = new XMLStreamReaderImpl(inputSource, 278 new PropertyManager(fPropertyManager)); 279 } 280 } 281 282 XMLInputSource jaxpSourcetoXMLInputSource(Source source){ 283 if(source instanceof StreamSource){ 284 StreamSource stSource = (StreamSource)source; 285 String systemId = stSource.getSystemId(); 286 String publicId = stSource.getPublicId(); 287 InputStream istream = stSource.getInputStream(); 288 Reader reader = stSource.getReader(); 289 290 if(istream != null){ 291 return new XMLInputSource(publicId, systemId, null, istream, null); 292 } 293 else if(reader != null){ 294 return new XMLInputSource(publicId, systemId,null, reader, null); 295 }else{ 296 return new XMLInputSource(publicId, systemId, null, false); 297 } 298 } 299 300 throw new UnsupportedOperationException("Cannot create " + 301 "XMLStreamReader or XMLEventReader from a " + 302 source.getClass().getName()); 303 } 304 305}//XMLInputFactoryImpl 306