001 /* XMLInputFactory.java -- 002 Copyright (C) 2005,2006 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 package javax.xml.stream; 039 040 import java.io.BufferedReader; 041 import java.io.File; 042 import java.io.FileInputStream; 043 import java.io.InputStream; 044 import java.io.InputStreamReader; 045 import java.io.IOException; 046 import java.io.Reader; 047 import java.util.Properties; 048 import javax.xml.stream.util.XMLEventAllocator; 049 import 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 */ 129 public 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 */ 210 public static XMLInputFactory newInstance(String factoryId, 211 ClassLoader classLoader) 212 throws FactoryConfigurationError 213 { 214 ClassLoader loader = classLoader; 215 if (loader == null) 216 { 217 loader = Thread.currentThread().getContextClassLoader(); 218 } 219 if (loader == null) 220 { 221 loader = XMLInputFactory.class.getClassLoader(); 222 } 223 String className = null; 224 int count = 0; 225 do 226 { 227 className = getFactoryClassName(loader, count++); 228 if (className != null) 229 { 230 try 231 { 232 Class<?> t = (loader != null) ? loader.loadClass(className) : 233 Class.forName(className); 234 return (XMLInputFactory) t.newInstance(); 235 } 236 catch (ClassNotFoundException e) 237 { 238 className = null; 239 } 240 catch (Exception e) 241 { 242 throw new FactoryConfigurationError(e, 243 "error instantiating class " + className); 244 } 245 } 246 } 247 while (className == null && count < 3); 248 return new gnu.xml.stream.XMLInputFactoryImpl(); 249 } 250 251 private static String getFactoryClassName(ClassLoader loader, int attempt) 252 { 253 final String propertyName = "javax.xml.stream.XMLInputFactory"; 254 switch (attempt) 255 { 256 case 0: 257 return System.getProperty(propertyName); 258 case 1: 259 try 260 { 261 File file = new File(System.getProperty("java.home")); 262 file = new File(file, "lib"); 263 file = new File(file, "stax.properties"); 264 InputStream in = new FileInputStream(file); 265 Properties props = new Properties(); 266 props.load(in); 267 in.close(); 268 return props.getProperty(propertyName); 269 } 270 catch (IOException e) 271 { 272 return null; 273 } 274 case 2: 275 try 276 { 277 String serviceKey = "/META-INF/services/" + propertyName; 278 InputStream in = (loader != null) ? 279 loader.getResourceAsStream(serviceKey) : 280 XMLInputFactory.class.getResourceAsStream(serviceKey); 281 if (in != null) 282 { 283 BufferedReader r = 284 new BufferedReader(new InputStreamReader(in)); 285 String ret = r.readLine(); 286 r.close(); 287 return ret; 288 } 289 } 290 catch (IOException e) 291 { 292 } 293 return null; 294 default: 295 return null; 296 } 297 } 298 299 /** 300 * Creates a new stream reader. 301 */ 302 public abstract XMLStreamReader createXMLStreamReader(Reader reader) 303 throws XMLStreamException; 304 305 /** 306 * Creates a new stream reader. 307 */ 308 public abstract XMLStreamReader createXMLStreamReader(Source source) 309 throws XMLStreamException; 310 311 /** 312 * Creates a new stream reader. 313 */ 314 public abstract XMLStreamReader createXMLStreamReader(InputStream stream) 315 throws XMLStreamException; 316 317 /** 318 * Creates a new stream reader. 319 */ 320 public abstract XMLStreamReader createXMLStreamReader(InputStream stream, 321 String encoding) 322 throws XMLStreamException; 323 324 /** 325 * Creates a new stream reader. 326 */ 327 public abstract XMLStreamReader createXMLStreamReader(String systemId, 328 InputStream stream) 329 throws XMLStreamException; 330 331 /** 332 * Creates a new stream reader. 333 */ 334 public abstract XMLStreamReader createXMLStreamReader(String systemId, 335 Reader reader) 336 throws XMLStreamException; 337 338 /** 339 * Creates a new event reader. 340 */ 341 public abstract XMLEventReader createXMLEventReader(Reader reader) 342 throws XMLStreamException; 343 344 /** 345 * Creates a new event reader. 346 */ 347 public abstract XMLEventReader createXMLEventReader(String systemId, 348 Reader reader) 349 throws XMLStreamException; 350 351 /** 352 * Creates a new event reader. 353 */ 354 public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) 355 throws XMLStreamException; 356 357 /** 358 * Creates a new event reader. 359 */ 360 public abstract XMLEventReader createXMLEventReader(Source source) 361 throws XMLStreamException; 362 363 /** 364 * Creates a new event reader. 365 */ 366 public abstract XMLEventReader createXMLEventReader(InputStream stream) 367 throws XMLStreamException; 368 369 /** 370 * Creates a new event reader. 371 */ 372 public abstract XMLEventReader createXMLEventReader(InputStream stream, 373 String encoding) 374 throws XMLStreamException; 375 376 /** 377 * Creates a new event reader. 378 */ 379 public abstract XMLEventReader createXMLEventReader(String systemId, 380 InputStream stream) 381 throws XMLStreamException; 382 383 /** 384 * Create a new filtered reader. 385 */ 386 public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, 387 StreamFilter filter) 388 throws XMLStreamException; 389 390 /** 391 * Create a new filtered reader. 392 */ 393 public abstract XMLEventReader createFilteredReader(XMLEventReader reader, 394 EventFilter filter) 395 throws XMLStreamException; 396 397 /** 398 * Returns the entity resolver. 399 */ 400 public abstract XMLResolver getXMLResolver(); 401 402 /** 403 * Sets the entity resolver. 404 */ 405 public abstract void setXMLResolver(XMLResolver resolver); 406 407 /** 408 * Returns the error reporter. 409 */ 410 public abstract XMLReporter getXMLReporter(); 411 412 /** 413 * Sets the error reporter. 414 */ 415 public abstract void setXMLReporter(XMLReporter reporter); 416 417 /** 418 * Sets the implementation-specific property of the given name. 419 * @exception IllegalArgumentException if the property is not supported 420 */ 421 public abstract void setProperty(String name, Object value) 422 throws IllegalArgumentException; 423 424 /** 425 * Returns the implementation-specific property of the given name. 426 * @exception IllegalArgumentException if the property is not supported 427 */ 428 public abstract Object getProperty(String name) 429 throws IllegalArgumentException; 430 431 /** 432 * Indicates whether the specified property is supported. 433 */ 434 public abstract boolean isPropertySupported(String name); 435 436 /** 437 * Sets the event allocator. 438 */ 439 public abstract void setEventAllocator(XMLEventAllocator allocator); 440 441 /** 442 * Returns the event allocator. 443 */ 444 public abstract XMLEventAllocator getEventAllocator(); 445 446 } 447