001/* XMLInputFactory.java -- 002 Copyright (C) 2005,2006,2009 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038package javax.xml.stream; 039 040import java.io.BufferedReader; 041import java.io.File; 042import java.io.FileInputStream; 043import java.io.InputStream; 044import java.io.InputStreamReader; 045import java.io.IOException; 046import java.io.Reader; 047import java.util.Properties; 048import javax.xml.stream.util.XMLEventAllocator; 049import javax.xml.transform.Source; 050 051/** 052 * Factory for creating stream and event readers from various kinds of input 053 * source. 054 * <h3>Parameters</h3> 055 * <table> 056 * <tr> 057 * <th>Name</th> 058 * <th>Description</th> 059 * <th>Type</th> 060 * <th>Default</th> 061 * <th>Required</th> 062 * </tr> 063 * <tr> 064 * <td>javax.xml.stream.isValidating</td> 065 * <td>Controls DTD validation</td> 066 * <td>Boolean</td> 067 * <td>Boolean.FALSE</td> 068 * <td>no</td> 069 * </tr> 070 * <tr> 071 * <td>javax.xml.stream.isNamespaceAware</td> 072 * <td>Controls namespace processing for XML 1.0</td> 073 * <td>Boolean</td> 074 * <td>Boolean.TRUE</td> 075 * <td>true is required, false is optional</td> 076 * </tr> 077 * <tr> 078 * <td>javax.xml.stream.isCoalescing</td> 079 * <td>Controls coalescing (normalization of adjacent character data)</td> 080 * <td>Boolean</td> 081 * <td>Boolean.FALSE</td> 082 * <td>yes</td> 083 * </tr> 084 * <tr> 085 * <td>javax.xml.stream.isReplacingEntityReferences</td> 086 * <td>Controls replacement of entity references with their replacement 087 * text</td> 088 * <td>Boolean</td> 089 * <td>Boolean.TRUE</td> 090 * <td>yes</td> 091 * </tr> 092 * <tr> 093 * <td>javax.xml.stream.isSupportingExternalEntities</td> 094 * <td>Controls whether to resolve external entities</td> 095 * <td>Boolean</td> 096 * <td>not specified</td> 097 * <td>yes</td> 098 * </tr> 099 * <tr> 100 * <td>javax.xml.stream.supportDTD</td> 101 * <td>Controls whether to support DTDs</td> 102 * <td>Boolean</td> 103 * <td>Boolean.TRUE</td> 104 * <td>yes</td> 105 * </tr> 106 * <tr> 107 * <td>javax.xml.stream.reporter</td> 108 * <td></td> 109 * <td>javax.xml.stream.XMLReporter</td> 110 * <td></td> 111 * <td>yes</td> 112 * </tr> 113 * <tr> 114 * <td>javax.xml.stream.resolver</td> 115 * <td></td> 116 * <td>javax.xml.stream.XMLResolver</td> 117 * <td></td> 118 * <td>yes</td> 119 * </tr> 120 * <tr> 121 * <td>javax.xml.stream.allocator</td> 122 * <td></td> 123 * <td>javax.xml.stream.util.XMLEventAllocator</td> 124 * <td></td> 125 * <td>yes</td> 126 * </tr> 127 * </table> 128 */ 129public abstract class XMLInputFactory 130{ 131 132 /** 133 * Property used to control namespace support. 134 */ 135 public static final String IS_NAMESPACE_AWARE = 136 "javax.xml.stream.isNamespaceAware"; 137 138 /** 139 * Property used to control DTD validation. 140 */ 141 public static final String IS_VALIDATING = "javax.xml.stream.isValidating"; 142 143 /** 144 * Property used to control whether to coalesce adjacent text events. 145 */ 146 public static final String IS_COALESCING = "javax.xml.stream.isCoalescing"; 147 148 /** 149 * Property used to control whether to replace entity references with 150 * their replacement text. 151 */ 152 public static final String IS_REPLACING_ENTITY_REFERENCES = 153 "javax.xml.stream.isReplacingEntityReferences"; 154 155 /** 156 * Property used to control whether to resolve external entities. 157 */ 158 public static final String IS_SUPPORTING_EXTERNAL_ENTITIES = 159 "javax.xml.stream.isSupportingExternalEntities"; 160 161 /** 162 * Property used to indicate whether to support DTDs. 163 */ 164 public static final String SUPPORT_DTD = "javax.xml.stream.supportDTD"; 165 166 /** 167 * Property used to control the error reporter implementation. 168 */ 169 public static final String REPORTER = "javax.xml.stream.reporter"; 170 171 /** 172 * Property used to control the entity resolver implementation. 173 */ 174 public static final String RESOLVER = "javax.xml.stream.resolver"; 175 176 /** 177 * Property used to control the event allocator implementation. 178 */ 179 public static final String ALLOCATOR = "javax.xml.stream.allocator"; 180 181 protected XMLInputFactory() 182 { 183 } 184 185 /** 186 * Creates a new factory instance. 187 * @see #newInstance(String,ClassLoader) 188 */ 189 public static XMLInputFactory newInstance() 190 throws FactoryConfigurationError 191 { 192 return newInstance(null, null); 193 } 194 195 /** 196 * Creates a new factory instance. 197 * The implementation class to load is the first found in the following 198 * locations: 199 * <ol> 200 * <li>the <code>javax.xml.stream.XMLInputFactory</code> system 201 * property</li> 202 * <li>the above named property value in the 203 * <code><i>$JAVA_HOME</i>/lib/stax.properties</code> file</li> 204 * <li>the class name specified in the 205 * <code>META-INF/services/javax.xml.stream.XMLInputFactory</code> 206 * system resource</li> 207 * <li>the default factory class</li> 208 * </ol> 209 * @param factoryId name of the factory, same as a property name 210 * @param classLoader the class loader to use 211 * @return the factory implementation 212 * @exception FactoryConfigurationError if an instance of this factory 213 * cannot be loaded 214 */ 215 public static XMLInputFactory newInstance(String factoryId, 216 ClassLoader classLoader) 217 throws FactoryConfigurationError 218 { 219 ClassLoader loader = classLoader; 220 if (loader == null) 221 { 222 loader = Thread.currentThread().getContextClassLoader(); 223 } 224 if (loader == null) 225 { 226 loader = XMLInputFactory.class.getClassLoader(); 227 } 228 String className = null; 229 int count = 0; 230 do 231 { 232 className = getFactoryClassName(loader, count++); 233 if (className != null) 234 { 235 try 236 { 237 Class<?> t = (loader != null) ? loader.loadClass(className) : 238 Class.forName(className); 239 return (XMLInputFactory) t.newInstance(); 240 } 241 catch (ClassNotFoundException e) 242 { 243 className = null; 244 } 245 catch (Exception e) 246 { 247 throw new FactoryConfigurationError(e, 248 "error instantiating class " + className); 249 } 250 } 251 } 252 while (className == null && count < 3); 253 return new gnu.xml.stream.XMLInputFactoryImpl(); 254 } 255 256 private static String getFactoryClassName(ClassLoader loader, int attempt) 257 { 258 final String propertyName = "javax.xml.stream.XMLInputFactory"; 259 switch (attempt) 260 { 261 case 0: 262 return System.getProperty(propertyName); 263 case 1: 264 try 265 { 266 File file = new File(System.getProperty("java.home")); 267 file = new File(file, "lib"); 268 file = new File(file, "stax.properties"); 269 InputStream in = new FileInputStream(file); 270 Properties props = new Properties(); 271 props.load(in); 272 in.close(); 273 return props.getProperty(propertyName); 274 } 275 catch (IOException e) 276 { 277 return null; 278 } 279 case 2: 280 try 281 { 282 String serviceKey = "/META-INF/services/" + propertyName; 283 InputStream in = (loader != null) ? 284 loader.getResourceAsStream(serviceKey) : 285 XMLInputFactory.class.getResourceAsStream(serviceKey); 286 if (in != null) 287 { 288 BufferedReader r = 289 new BufferedReader(new InputStreamReader(in)); 290 String ret = r.readLine(); 291 r.close(); 292 return ret; 293 } 294 } 295 catch (IOException e) 296 { 297 } 298 return null; 299 default: 300 return null; 301 } 302 } 303 304 /** 305 * Creates a new stream reader. 306 */ 307 public abstract XMLStreamReader createXMLStreamReader(Reader reader) 308 throws XMLStreamException; 309 310 /** 311 * Creates a new stream reader. 312 */ 313 public abstract XMLStreamReader createXMLStreamReader(Source source) 314 throws XMLStreamException; 315 316 /** 317 * Creates a new stream reader. 318 */ 319 public abstract XMLStreamReader createXMLStreamReader(InputStream stream) 320 throws XMLStreamException; 321 322 /** 323 * Creates a new stream reader. 324 */ 325 public abstract XMLStreamReader createXMLStreamReader(InputStream stream, 326 String encoding) 327 throws XMLStreamException; 328 329 /** 330 * Creates a new stream reader. 331 */ 332 public abstract XMLStreamReader createXMLStreamReader(String systemId, 333 InputStream stream) 334 throws XMLStreamException; 335 336 /** 337 * Creates a new stream reader. 338 */ 339 public abstract XMLStreamReader createXMLStreamReader(String systemId, 340 Reader reader) 341 throws XMLStreamException; 342 343 /** 344 * Creates a new event reader. 345 */ 346 public abstract XMLEventReader createXMLEventReader(Reader reader) 347 throws XMLStreamException; 348 349 /** 350 * Creates a new event reader. 351 */ 352 public abstract XMLEventReader createXMLEventReader(String systemId, 353 Reader reader) 354 throws XMLStreamException; 355 356 /** 357 * Creates a new event reader. 358 */ 359 public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) 360 throws XMLStreamException; 361 362 /** 363 * Creates a new event reader. 364 */ 365 public abstract XMLEventReader createXMLEventReader(Source source) 366 throws XMLStreamException; 367 368 /** 369 * Creates a new event reader. 370 */ 371 public abstract XMLEventReader createXMLEventReader(InputStream stream) 372 throws XMLStreamException; 373 374 /** 375 * Creates a new event reader. 376 */ 377 public abstract XMLEventReader createXMLEventReader(InputStream stream, 378 String encoding) 379 throws XMLStreamException; 380 381 /** 382 * Creates a new event reader. 383 */ 384 public abstract XMLEventReader createXMLEventReader(String systemId, 385 InputStream stream) 386 throws XMLStreamException; 387 388 /** 389 * Create a new filtered reader. 390 */ 391 public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, 392 StreamFilter filter) 393 throws XMLStreamException; 394 395 /** 396 * Create a new filtered reader. 397 */ 398 public abstract XMLEventReader createFilteredReader(XMLEventReader reader, 399 EventFilter filter) 400 throws XMLStreamException; 401 402 /** 403 * Returns the entity resolver. 404 */ 405 public abstract XMLResolver getXMLResolver(); 406 407 /** 408 * Sets the entity resolver. 409 */ 410 public abstract void setXMLResolver(XMLResolver resolver); 411 412 /** 413 * Returns the error reporter. 414 */ 415 public abstract XMLReporter getXMLReporter(); 416 417 /** 418 * Sets the error reporter. 419 */ 420 public abstract void setXMLReporter(XMLReporter reporter); 421 422 /** 423 * Sets the implementation-specific property of the given name. 424 * @exception IllegalArgumentException if the property is not supported 425 */ 426 public abstract void setProperty(String name, Object value) 427 throws IllegalArgumentException; 428 429 /** 430 * Returns the implementation-specific property of the given name. 431 * @exception IllegalArgumentException if the property is not supported 432 */ 433 public abstract Object getProperty(String name) 434 throws IllegalArgumentException; 435 436 /** 437 * Indicates whether the specified property is supported. 438 */ 439 public abstract boolean isPropertySupported(String name); 440 441 /** 442 * Sets the event allocator. 443 */ 444 public abstract void setEventAllocator(XMLEventAllocator allocator); 445 446 /** 447 * Returns the event allocator. 448 */ 449 public abstract XMLEventAllocator getEventAllocator(); 450 451}