1 /*
2 * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.xml.parsers;
27
28 import javax.xml.validation.Schema;
29
30 import org.xml.sax.SAXException;
31 import org.xml.sax.SAXNotRecognizedException;
32 import org.xml.sax.SAXNotSupportedException;
33
34 /**
35 * Defines a factory API that enables applications to configure and
36 * obtain a SAX based parser to parse XML documents.
37 *
38 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
39 * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a>
40 *
41 *
42 */
43 public abstract class SAXParserFactory {
44 /** The default property name according to the JAXP spec */
45 private static final String DEFAULT_PROPERTY_NAME = "javax.xml.parsers.SAXParserFactory";
46
47 /**
48 * <p>Should Parsers be validating?</p>
49 */
50 private boolean validating = false;
51
52 /**
53 * <p>Should Parsers be namespace aware?</p>
54 */
55 private boolean namespaceAware = false;
56
57 /**
58 * <p>Protected constructor to force use of {@link #newInstance()}.</p>
59 */
60 protected SAXParserFactory () {
61
62 }
63
64 /**
65 * Obtain a new instance of a <code>SAXParserFactory</code>. This
66 * static method creates a new factory instance
67 * This method uses the following ordered lookup procedure to determine
68 * the <code>SAXParserFactory</code> implementation class to
69 * load:
70 * <ul>
71 * <li>
72 * Use the <code>javax.xml.parsers.SAXParserFactory</code> system
73 * property.
74 * </li>
75 * <li>
76 * Use the properties file "lib/jaxp.properties" in the JRE directory.
77 * This configuration file is in standard <code>java.util.Properties
78 * </code> format and contains the fully qualified name of the
79 * implementation class with the key being the system property defined
80 * above.
81 *
82 * The jaxp.properties file is read only once by the JAXP implementation
83 * and it's values are then cached for future use. If the file does not exist
84 * when the first attempt is made to read from it, no further attempts are
85 * made to check for its existence. It is not possible to change the value
86 * of any property in jaxp.properties after it has been read for the first time.
87 * </li>
88 * <li>
89 * Use the Services API (as detailed in the JAR specification), if
90 * available, to determine the classname. The Services API will look
91 * for a classname in the file
92 * <code>META-INF/services/javax.xml.parsers.SAXParserFactory</code>
93 * in jars available to the runtime.
94 * </li>
95 * <li>
96 * Platform default <code>SAXParserFactory</code> instance.
97 * </li>
98 * </ul>
99 *
100 * Once an application has obtained a reference to a
101 * <code>SAXParserFactory</code> it can use the factory to
102 * configure and obtain parser instances.
103 *
104 *
105 *
106 * <h2>Tip for Trouble-shooting</h2>
107 * <p>Setting the <code>jaxp.debug</code> system property will cause
108 * this method to print a lot of debug messages
109 * to <code>System.err</code> about what it is doing and where it is looking at.</p>
110 *
111 * <p> If you have problems loading {@link DocumentBuilder}s, try:</p>
112 * <pre>
113 * java -Djaxp.debug=1 YourProgram ....
114 * </pre>
115 *
116 *
117 * @return A new instance of a SAXParserFactory.
118 *
119 * @throws FactoryConfigurationError if the implementation is
120 * not available or cannot be instantiated.
121 */
122
123 public static SAXParserFactory newInstance() {
124 try {
125 return (SAXParserFactory) FactoryFinder.find(
126 /* The default property name according to the JAXP spec */
127 "javax.xml.parsers.SAXParserFactory",
128 /* The fallback implementation class name */
129 "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl");
130 } catch (FactoryFinder.ConfigurationError e) {
131 throw new FactoryConfigurationError(e.getException(),
132 e.getMessage());
133 }
134 }
135
136 /**
137 * <p>Obtain a new instance of a <code>SAXParserFactory</code> from class name.
138 * This function is useful when there are multiple providers in the classpath.
139 * It gives more control to the application as it can specify which provider
140 * should be loaded.</p>
141 *
142 * <p>Once an application has obtained a reference to a <code>SAXParserFactory</code>
143 * it can use the factory to configure and obtain parser instances.</p>
144 *
145 *
146 * <h2>Tip for Trouble-shooting</h2>
147 * <p>Setting the <code>jaxp.debug</code> system property will cause
148 * this method to print a lot of debug messages
149 * to <code>System.err</code> about what it is doing and where it is looking at.</p>
150 *
151 * <p> If you have problems, try:</p>
152 * <pre>
153 * java -Djaxp.debug=1 YourProgram ....
154 * </pre>
155 *
156 * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.parsers.SAXParserFactory</code>.
157 *
158 * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code>
159 * current <code>Thread</code>'s context classLoader is used to load the factory class.
160 *
161 * @return New instance of a <code>SAXParserFactory</code>
162 *
163 * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or
164 * the factory class cannot be loaded, instantiated.
165 *
166 * @see #newInstance()
167 *
168 * @since 1.6
169 */
170 public static SAXParserFactory newInstance(String factoryClassName, ClassLoader classLoader){
171 try {
172 //do not fallback if given classloader can't find the class, throw exception
173 return (SAXParserFactory) FactoryFinder.newInstance(factoryClassName, classLoader, false);
174 } catch (FactoryFinder.ConfigurationError e) {
175 throw new FactoryConfigurationError(e.getException(),
176 e.getMessage());
177 }
178 }
179
180 /**
181 * <p>Creates a new instance of a SAXParser using the currently
182 * configured factory parameters.</p>
183 *
184 * @return A new instance of a SAXParser.
185 *
186 * @throws ParserConfigurationException if a parser cannot
187 * be created which satisfies the requested configuration.
188 * @throws SAXException for SAX errors.
189 */
190
191 public abstract SAXParser newSAXParser()
192 throws ParserConfigurationException, SAXException;
193
194
195 /**
196 * Specifies that the parser produced by this code will
197 * provide support for XML namespaces. By default the value of this is set
198 * to <code>false</code>.
199 *
200 * @param awareness true if the parser produced by this code will
201 * provide support for XML namespaces; false otherwise.
202 */
203
204 public void setNamespaceAware(boolean awareness) {
205 this.namespaceAware = awareness;
206 }
207
208 /**
209 * Specifies that the parser produced by this code will
210 * validate documents as they are parsed. By default the value of this is
211 * set to <code>false</code>.
212 *
213 * <p>
214 * Note that "the validation" here means
215 * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating
216 * parser</a> as defined in the XML recommendation.
217 * In other words, it essentially just controls the DTD validation.
218 * (except the legacy two properties defined in JAXP 1.2.)
219 * </p>
220 *
221 * <p>
222 * To use modern schema languages such as W3C XML Schema or
223 * RELAX NG instead of DTD, you can configure your parser to be
224 * a non-validating parser by leaving the {@link #setValidating(boolean)}
225 * method <code>false</code>, then use the {@link #setSchema(Schema)}
226 * method to associate a schema to a parser.
227 * </p>
228 *
229 * @param validating true if the parser produced by this code will
230 * validate documents as they are parsed; false otherwise.
231 */
232
233 public void setValidating(boolean validating) {
234 this.validating = validating;
235 }
236
237 /**
238 * Indicates whether or not the factory is configured to produce
239 * parsers which are namespace aware.
240 *
241 * @return true if the factory is configured to produce
242 * parsers which are namespace aware; false otherwise.
243 */
244
245 public boolean isNamespaceAware() {
246 return namespaceAware;
247 }
248
249 /**
250 * Indicates whether or not the factory is configured to produce
251 * parsers which validate the XML content during parse.
252 *
253 * @return true if the factory is configured to produce parsers which validate
254 * the XML content during parse; false otherwise.
255 */
256
257 public boolean isValidating() {
258 return validating;
259 }
260
261 /**
262 *
263 * <p>Sets the particular feature in the underlying implementation of
264 * org.xml.sax.XMLReader.
265 * A list of the core features and properties can be found at
266 * <a href="http://www.saxproject.org/">http://www.saxproject.org/</a></p>
267 *
268 * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
269 * When the feature is</p>
270 * <ul>
271 * <li>
272 * <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
273 * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources.
274 * If XML processing is limited for security reasons, it will be reported via a call to the registered
275 * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}.
276 * See {@link SAXParser} <code>parse</code> methods for handler specification.
277 * </li>
278 * <li>
279 * When the feature is <code>false</code>, the implementation will processing XML according to the XML specifications without
280 * regard to possible implementation limits.
281 * </li>
282 * </ul>
283 *
284 * @param name The name of the feature to be set.
285 * @param value The value of the feature to be set.
286 *
287 * @throws ParserConfigurationException if a parser cannot
288 * be created which satisfies the requested configuration.
289 * @throws SAXNotRecognizedException When the underlying XMLReader does
290 * not recognize the property name.
291 * @throws SAXNotSupportedException When the underlying XMLReader
292 * recognizes the property name but doesn't support the
293 * property.
294 * @throws NullPointerException If the <code>name</code> parameter is null.
295 *
296 * @see org.xml.sax.XMLReader#setFeature
297 */
298 public abstract void setFeature(String name, boolean value)
299 throws ParserConfigurationException, SAXNotRecognizedException,
300 SAXNotSupportedException;
301
302 /**
303 *
304 * <p>Returns the particular property requested for in the underlying
305 * implementation of org.xml.sax.XMLReader.</p>
306 *
307 * @param name The name of the property to be retrieved.
308 *
309 * @return Value of the requested property.
310 *
311 * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
312 * @throws SAXNotRecognizedException When the underlying XMLReader does not recognize the property name.
313 * @throws SAXNotSupportedException When the underlying XMLReader recognizes the property name but doesn't support the property.
314 *
315 * @see org.xml.sax.XMLReader#getProperty
316 */
317 public abstract boolean getFeature(String name)
318 throws ParserConfigurationException, SAXNotRecognizedException,
319 SAXNotSupportedException;
320
321
322
323 /* <p>Get current state of canonicalization.</p>
324 *
325 * @return current state canonicalization control
326 */
327 /*
328 public boolean getCanonicalization() {
329 return canonicalState;
330 }
331 */
332
333 /**
334 * Gets the {@link Schema} object specified through
335 * the {@link #setSchema(Schema schema)} method.
336 *
337 *
338 * @throws UnsupportedOperationException When implementation does not
339 * override this method
340 *
341 * @return
342 * the {@link Schema} object that was last set through
343 * the {@link #setSchema(Schema)} method, or null
344 * if the method was not invoked since a {@link SAXParserFactory}
345 * is created.
346 *
347 * @since 1.5
348 */
349 public Schema getSchema() {
350 throw new UnsupportedOperationException(
351 "This parser does not support specification \""
352 + this.getClass().getPackage().getSpecificationTitle()
353 + "\" version \""
354 + this.getClass().getPackage().getSpecificationVersion()
355 + "\""
356 );
357 }
358
359 /** <p>Set canonicalization control to <code>true</code> or
360 * </code>false</code>.</p>
361 *
362 * @param state of canonicalization
363 */
364 /*
365 public void setCanonicalization(boolean state) {
366 canonicalState = state;
367 }
368 */
369
370 /**
371 * <p>Set the {@link Schema} to be used by parsers created
372 * from this factory.</p>
373 *
374 * <p>When a {@link Schema} is non-null, a parser will use a validator
375 * created from it to validate documents before it passes information
376 * down to the application.</p>
377 *
378 * <p>When warnings/errors/fatal errors are found by the validator, the parser must
379 * handle them as if those errors were found by the parser itself.
380 * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
381 * is set, it must receive those errors, and if not, they must be
382 * treated according to the implementation specific
383 * default error handling rules.
384 *
385 * <p>A validator may modify the SAX event stream (for example by
386 * adding default values that were missing in documents), and a parser
387 * is responsible to make sure that the application will receive
388 * those modified event stream.</p>
389 *
390 * <p>Initialy, <code>null</code> is set as the {@link Schema}.</p>
391 *
392 * <p>This processing will take effect even if
393 * the {@link #isValidating()} method returns <code>false</code>.
394 *
395 * <p>It is an error to use
396 * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code>
397 * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code>
398 * property in conjunction with a non-null {@link Schema} object.
399 * Such configuration will cause a {@link SAXException}
400 * exception when those properties are set on a {@link SAXParser}.</p>
401 *
402 * <h4>Note for implmentors</h4>
403 * <p>
404 * A parser must be able to work with any {@link Schema}
405 * implementation. However, parsers and schemas are allowed
406 * to use implementation-specific custom mechanisms
407 * as long as they yield the result described in the specification.
408 * </p>
409 *
410 * @param schema <code>Schema</code> to use, <code>null</code> to remove a schema.
411 *
412 * @throws UnsupportedOperationException When implementation does not
413 * override this method
414 *
415 * @since 1.5
416 */
417 public void setSchema(Schema schema) {
418 throw new UnsupportedOperationException(
419 "This parser does not support specification \""
420 + this.getClass().getPackage().getSpecificationTitle()
421 + "\" version \""
422 + this.getClass().getPackage().getSpecificationVersion()
423 + "\""
424 );
425 }
426
427 /**
428 * <p>Set state of XInclude processing.</p>
429 *
430 * <p>If XInclude markup is found in the document instance, should it be
431 * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
432 * XML Inclusions (XInclude) Version 1.0</a>.</p>
433 *
434 * <p>XInclude processing defaults to <code>false</code>.</p>
435 *
436 * @param state Set XInclude processing to <code>true</code> or
437 * <code>false</code>
438 *
439 * @throws UnsupportedOperationException When implementation does not
440 * override this method
441 *
442 * @since 1.5
443 */
444 public void setXIncludeAware(final boolean state) {
445 throw new UnsupportedOperationException(
446 "This parser does not support specification \""
447 + this.getClass().getPackage().getSpecificationTitle()
448 + "\" version \""
449 + this.getClass().getPackage().getSpecificationVersion()
450 + "\""
451 );
452 }
453
454 /**
455 * <p>Get state of XInclude processing.</p>
456 *
457 * @return current state of XInclude processing
458 *
459 * @throws UnsupportedOperationException When implementation does not
460 * override this method
461 *
462 * @since 1.5
463 */
464 public boolean isXIncludeAware() {
465 throw new UnsupportedOperationException(
466 "This parser does not support specification \""
467 + this.getClass().getPackage().getSpecificationTitle()
468 + "\" version \""
469 + this.getClass().getPackage().getSpecificationVersion()
470 + "\""
471 );
472 }
473 }