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