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