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.io.Writer; 048 import java.util.Properties; 049 import javax.xml.stream.util.XMLEventAllocator; 050 import javax.xml.transform.Source; 051 052 /** 053 * Factory for creating stream and event readers from various kinds of input 054 * source. 055 * <h3>Parameters</h3> 056 * <table> 057 * <tr> 058 * <th>Name</th> 059 * <th>Description</th> 060 * <th>Type</th> 061 * <th>Default</th> 062 * <th>Required</th> 063 * </tr> 064 * <tr> 065 * <td>javax.xml.stream.isValidating</td> 066 * <td>Controls DTD validation</td> 067 * <td>Boolean</td> 068 * <td>Boolean.FALSE</td> 069 * <td>no</td> 070 * </tr> 071 * <tr> 072 * <td>javax.xml.stream.isNamespaceAware</td> 073 * <td>Controls namespace processing for XML 1.0</td> 074 * <td>Boolean</td> 075 * <td>Boolean.TRUE</td> 076 * <td>true is required, false is optional</td> 077 * </tr> 078 * <tr> 079 * <td>javax.xml.stream.isCoalescing</td> 080 * <td>Controls coalescing (normalization of adjacent character data)</td> 081 * <td>Boolean</td> 082 * <td>Boolean.FALSE</td> 083 * <td>yes</td> 084 * </tr> 085 * <tr> 086 * <td>javax.xml.stream.isReplacingEntityReferences</td> 087 * <td>Controls replacement of entity references with their replacement 088 * text</td> 089 * <td>Boolean</td> 090 * <td>Boolean.TRUE</td> 091 * <td>yes</td> 092 * </tr> 093 * <tr> 094 * <td>javax.xml.stream.isSupportingExternalEntities</td> 095 * <td>Controls whether to resolve external entities</td> 096 * <td>Boolean</td> 097 * <td>not specified</td> 098 * <td>yes</td> 099 * </tr> 100 * <tr> 101 * <td>javax.xml.stream.supportDTD</td> 102 * <td>Controls whether to support DTDs</td> 103 * <td>Boolean</td> 104 * <td>Boolean.TRUE</td> 105 * <td>yes</td> 106 * </tr> 107 * <tr> 108 * <td>javax.xml.stream.reporter</td> 109 * <td></td> 110 * <td>javax.xml.stream.XMLReporter</td> 111 * <td></td> 112 * <td>yes</td> 113 * </tr> 114 * <tr> 115 * <td>javax.xml.stream.resolver</td> 116 * <td></td> 117 * <td>javax.xml.stream.XMLResolver</td> 118 * <td></td> 119 * <td>yes</td> 120 * </tr> 121 * <tr> 122 * <td>javax.xml.stream.allocator</td> 123 * <td></td> 124 * <td>javax.xml.stream.util.XMLEventAllocator</td> 125 * <td></td> 126 * <td>yes</td> 127 * </tr> 128 * </table> 129 */ 130 public abstract class XMLInputFactory 131 { 132 133 /** 134 * Property used to control namespace support. 135 */ 136 public static final String IS_NAMESPACE_AWARE = 137 "javax.xml.stream.isNamespaceAware"; 138 139 /** 140 * Property used to control DTD validation. 141 */ 142 public static final String IS_VALIDATING = "javax.xml.stream.isValidating"; 143 144 /** 145 * Property used to control whether to coalesce adjacent text events. 146 */ 147 public static final String IS_COALESCING = "javax.xml.stream.isCoalescing"; 148 149 /** 150 * Property used to control whether to replace entity references with 151 * their replacement text. 152 */ 153 public static final String IS_REPLACING_ENTITY_REFERENCES = 154 "javax.xml.stream.isReplacingEntityReferences"; 155 156 /** 157 * Property used to control whether to resolve external entities. 158 */ 159 public static final String IS_SUPPORTING_EXTERNAL_ENTITIES = 160 "javax.xml.stream.isSupportingExternalEntities"; 161 162 /** 163 * Property used to indicate whether to support DTDs. 164 */ 165 public static final String SUPPORT_DTD = "javax.xml.stream.supportDTD"; 166 167 /** 168 * Property used to control the error reporter implementation. 169 */ 170 public static final String REPORTER = "javax.xml.stream.reporter"; 171 172 /** 173 * Property used to control the entity resolver implementation. 174 */ 175 public static final String RESOLVER = "javax.xml.stream.resolver"; 176 177 /** 178 * Property used to control the event allocator implementation. 179 */ 180 public static final String ALLOCATOR = "javax.xml.stream.allocator"; 181 182 protected XMLInputFactory() 183 { 184 } 185 186 /** 187 * Creates a new factory instance. 188 * @see #newInstance(String,ClassLoader) 189 */ 190 public static XMLInputFactory newInstance() 191 throws FactoryConfigurationError 192 { 193 return newInstance(null, null); 194 } 195 196 /** 197 * Creates a new factory instance. 198 * The implementation class to load is the first found in the following 199 * locations: 200 * <ol> 201 * <li>the <code>javax.xml.stream.XMLInputFactory</code> system 202 * property</li> 203 * <li>the above named property value in the 204 * <code><i>$JAVA_HOME</i>/lib/stax.properties</code> file</li> 205 * <li>the class name specified in the 206 * <code>META-INF/services/javax.xml.stream.XMLInputFactory</code> 207 * system resource</li> 208 * <li>the default factory class</li> 209 * </ol> 210 */ 211 public static XMLInputFactory newInstance(String factoryId, 212 ClassLoader classLoader) 213 throws FactoryConfigurationError 214 { 215 ClassLoader loader = classLoader; 216 if (loader == null) 217 { 218 loader = Thread.currentThread().getContextClassLoader(); 219 } 220 if (loader == null) 221 { 222 loader = XMLInputFactory.class.getClassLoader(); 223 } 224 String className = null; 225 int count = 0; 226 do 227 { 228 className = getFactoryClassName(loader, count++); 229 if (className != null) 230 { 231 try 232 { 233 Class t = (loader != null) ? loader.loadClass(className) : 234 Class.forName(className); 235 return (XMLInputFactory) t.newInstance(); 236 } 237 catch (ClassNotFoundException e) 238 { 239 className = null; 240 } 241 catch (Exception e) 242 { 243 throw new FactoryConfigurationError(e, 244 "error instantiating class " + className); 245 } 246 } 247 } 248 while (className == null && count < 3); 249 return new gnu.xml.stream.XMLInputFactoryImpl(); 250 } 251 252 private static String getFactoryClassName(ClassLoader loader, int attempt) 253 { 254 final String propertyName = "javax.xml.stream.XMLInputFactory"; 255 switch (attempt) 256 { 257 case 0: 258 return System.getProperty(propertyName); 259 case 1: 260 try 261 { 262 File file = new File(System.getProperty("java.home")); 263 file = new File(file, "lib"); 264 file = new File(file, "stax.properties"); 265 InputStream in = new FileInputStream(file); 266 Properties props = new Properties(); 267 props.load(in); 268 in.close(); 269 return props.getProperty(propertyName); 270 } 271 catch (IOException e) 272 { 273 return null; 274 } 275 case 2: 276 try 277 { 278 String serviceKey = "/META-INF/services/" + propertyName; 279 InputStream in = (loader != null) ? 280 loader.getResourceAsStream(serviceKey) : 281 XMLInputFactory.class.getResourceAsStream(serviceKey); 282 if (in != null) 283 { 284 BufferedReader r = 285 new BufferedReader(new InputStreamReader(in)); 286 String ret = r.readLine(); 287 r.close(); 288 return ret; 289 } 290 } 291 catch (IOException e) 292 { 293 } 294 return null; 295 default: 296 return null; 297 } 298 } 299 300 /** 301 * Creates a new stream reader. 302 */ 303 public abstract XMLStreamReader createXMLStreamReader(Reader reader) 304 throws XMLStreamException; 305 306 /** 307 * Creates a new stream reader. 308 */ 309 public abstract XMLStreamReader createXMLStreamReader(Source source) 310 throws XMLStreamException; 311 312 /** 313 * Creates a new stream reader. 314 */ 315 public abstract XMLStreamReader createXMLStreamReader(InputStream stream) 316 throws XMLStreamException; 317 318 /** 319 * Creates a new stream reader. 320 */ 321 public abstract XMLStreamReader createXMLStreamReader(InputStream stream, 322 String encoding) 323 throws XMLStreamException; 324 325 /** 326 * Creates a new stream reader. 327 */ 328 public abstract XMLStreamReader createXMLStreamReader(String systemId, 329 InputStream stream) 330 throws XMLStreamException; 331 332 /** 333 * Creates a new stream reader. 334 */ 335 public abstract XMLStreamReader createXMLStreamReader(String systemId, 336 Reader reader) 337 throws XMLStreamException; 338 339 /** 340 * Creates a new event reader. 341 */ 342 public abstract XMLEventReader createXMLEventReader(Reader reader) 343 throws XMLStreamException; 344 345 /** 346 * Creates a new event reader. 347 */ 348 public abstract XMLEventReader createXMLEventReader(String systemId, 349 Reader reader) 350 throws XMLStreamException; 351 352 /** 353 * Creates a new event reader. 354 */ 355 public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) 356 throws XMLStreamException; 357 358 /** 359 * Creates a new event reader. 360 */ 361 public abstract XMLEventReader createXMLEventReader(Source source) 362 throws XMLStreamException; 363 364 /** 365 * Creates a new event reader. 366 */ 367 public abstract XMLEventReader createXMLEventReader(InputStream stream) 368 throws XMLStreamException; 369 370 /** 371 * Creates a new event reader. 372 */ 373 public abstract XMLEventReader createXMLEventReader(InputStream stream, 374 String encoding) 375 throws XMLStreamException; 376 377 /** 378 * Creates a new event reader. 379 */ 380 public abstract XMLEventReader createXMLEventReader(String systemId, 381 InputStream stream) 382 throws XMLStreamException; 383 384 /** 385 * Create a new filtered reader. 386 */ 387 public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, 388 StreamFilter filter) 389 throws XMLStreamException; 390 391 /** 392 * Create a new filtered reader. 393 */ 394 public abstract XMLEventReader createFilteredReader(XMLEventReader reader, 395 EventFilter filter) 396 throws XMLStreamException; 397 398 /** 399 * Returns the entity resolver. 400 */ 401 public abstract XMLResolver getXMLResolver(); 402 403 /** 404 * Sets the entity resolver. 405 */ 406 public abstract void setXMLResolver(XMLResolver resolver); 407 408 /** 409 * Returns the error reporter. 410 */ 411 public abstract XMLReporter getXMLReporter(); 412 413 /** 414 * Sets the error reporter. 415 */ 416 public abstract void setXMLReporter(XMLReporter reporter); 417 418 /** 419 * Sets the implementation-specific property of the given name. 420 * @exception IllegalArgumentException if the property is not supported 421 */ 422 public abstract void setProperty(String name, Object value) 423 throws IllegalArgumentException; 424 425 /** 426 * Returns the implementation-specific property of the given name. 427 * @exception IllegalArgumentException if the property is not supported 428 */ 429 public abstract Object getProperty(String name) 430 throws IllegalArgumentException; 431 432 /** 433 * Indicates whether the specified property is supported. 434 */ 435 public abstract boolean isPropertySupported(String name); 436 437 /** 438 * Sets the event allocator. 439 */ 440 public abstract void setEventAllocator(XMLEventAllocator allocator); 441 442 /** 443 * Returns the event allocator. 444 */ 445 public abstract XMLEventAllocator getEventAllocator(); 446 447 } 448