View Javadoc
1   /*
2    * Copyright (c) 2000, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package javax.xml.parsers;
27  
28  import javax.xml.validation.Schema;
29  
30  /**
31   * Defines a factory API that enables applications to obtain a
32   * parser that produces DOM object trees from XML documents.
33   *
34   * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
35   * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a>
36   *
37   * @version $Revision: 1.9 $, $Date: 2010/05/25 16:19:44 $
38  
39   */
40  
41  public abstract class DocumentBuilderFactory {
42  
43      private boolean validating = false;
44      private boolean namespaceAware = false;
45      private boolean whitespace = false;
46      private boolean expandEntityRef = true;
47      private boolean ignoreComments = false;
48      private boolean coalescing = false;
49  
50      /**
51       * <p>Protected constructor to prevent instantiation.
52       * Use {@link #newInstance()}.</p>
53       */
54      protected DocumentBuilderFactory () {
55      }
56  
57      /**
58       * Obtain a new instance of a
59       * <code>DocumentBuilderFactory</code>. This static method creates
60       * a new factory instance.
61       * This method uses the following ordered lookup procedure to determine
62       * the <code>DocumentBuilderFactory</code> implementation class to
63       * load:
64       * <ul>
65       * <li>
66       * Use the <code>javax.xml.parsers.DocumentBuilderFactory</code> system
67       * property.
68       * </li>
69       * <li>
70       * Use the properties file "lib/jaxp.properties" in the JRE directory.
71       * This configuration file is in standard <code>java.util.Properties
72       * </code> format and contains the fully qualified name of the
73       * implementation class with the key being the system property defined
74       * above.
75       *
76       * The jaxp.properties file is read only once by the JAXP implementation
77       * and it's values are then cached for future use.  If the file does not exist
78       * when the first attempt is made to read from it, no further attempts are
79       * made to check for its existence.  It is not possible to change the value
80       * of any property in jaxp.properties after it has been read for the first time.
81       * </li>
82       * <li>
83       * Uses the service-provider loading facilities, defined by the
84       * {@link java.util.ServiceLoader} class, to attempt to locate and load an
85       * implementation of the service using the {@linkplain
86       * java.util.ServiceLoader#load(java.lang.Class) default loading mechanism}:
87       * the service-provider loading facility will use the {@linkplain
88       * java.lang.Thread#getContextClassLoader() current thread's context class loader}
89       * to attempt to load the service. If the context class
90       * loader is null, the {@linkplain
91       * ClassLoader#getSystemClassLoader() system class loader} will be used.
92       * </li>
93       * <li>
94       * Otherwise, the system-default implementation is returned.
95       * </li>
96       * </ul>
97       *
98       * Once an application has obtained a reference to a
99       * <code>DocumentBuilderFactory</code> it can use the factory to
100      * configure and obtain parser instances.
101      *
102      *
103      * <h2>Tip for Trouble-shooting</h2>
104      * <p>Setting the <code>jaxp.debug</code> system property will cause
105      * this method to print a lot of debug messages
106      * to <code>System.err</code> about what it is doing and where it is looking at.</p>
107      *
108      * <p> If you have problems loading {@link DocumentBuilder}s, try:</p>
109      * <pre>
110      * java -Djaxp.debug=1 YourProgram ....
111      * </pre>
112      *
113      * @return New instance of a <code>DocumentBuilderFactory</code>
114      *
115      * @throws FactoryConfigurationError in case of {@linkplain
116      * java.util.ServiceConfigurationError service configuration error} or if
117      * the implementation is not available or cannot be instantiated.
118      */
119     public static DocumentBuilderFactory newInstance() {
120         return FactoryFinder.find(
121                 /* The default property name according to the JAXP spec */
122                 DocumentBuilderFactory.class, // "javax.xml.parsers.DocumentBuilderFactory"
123                 /* The fallback implementation class name */
124                 "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
125     }
126 
127     /**
128      * <p>Obtain a new instance of a <code>DocumentBuilderFactory</code> from class name.
129      * This function is useful when there are multiple providers in the classpath.
130      * It gives more control to the application as it can specify which provider
131      * should be loaded.</p>
132      *
133      * <p>Once an application has obtained a reference to a <code>DocumentBuilderFactory</code>
134      * it can use the factory to configure and obtain parser instances.</p>
135      *
136      *
137      * <h2>Tip for Trouble-shooting</h2>
138      * <p>Setting the <code>jaxp.debug</code> system property will cause
139      * this method to print a lot of debug messages
140      * to <code>System.err</code> about what it is doing and where it is looking at.</p>
141      *
142      * <p> If you have problems try:</p>
143      * <pre>
144      * java -Djaxp.debug=1 YourProgram ....
145      * </pre>
146      *
147      * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.parsers.DocumentBuilderFactory</code>.
148      *
149      * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code>
150      *                     current <code>Thread</code>'s context classLoader is used to load the factory class.
151      *
152      * @return New instance of a <code>DocumentBuilderFactory</code>
153      *
154      * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or
155      *                                   the factory class cannot be loaded, instantiated.
156      *
157      * @see #newInstance()
158      *
159      * @since 1.6
160      */
161     public static DocumentBuilderFactory newInstance(String factoryClassName, ClassLoader classLoader){
162             //do not fallback if given classloader can't find the class, throw exception
163             return FactoryFinder.newInstance(DocumentBuilderFactory.class,
164                         factoryClassName, classLoader, false);
165     }
166 
167     /**
168      * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder}
169      * using the currently configured parameters.
170      *
171      * @return A new instance of a DocumentBuilder.
172      *
173      * @throws ParserConfigurationException if a DocumentBuilder
174      *   cannot be created which satisfies the configuration requested.
175      */
176 
177     public abstract DocumentBuilder newDocumentBuilder()
178         throws ParserConfigurationException;
179 
180 
181     /**
182      * Specifies that the parser produced by this code will
183      * provide support for XML namespaces. By default the value of this is set
184      * to <code>false</code>
185      *
186      * @param awareness true if the parser produced will provide support
187      *                  for XML namespaces; false otherwise.
188      */
189 
190     public void setNamespaceAware(boolean awareness) {
191         this.namespaceAware = awareness;
192     }
193 
194     /**
195      * Specifies that the parser produced by this code will
196      * validate documents as they are parsed. By default the value of this
197      * is set to <code>false</code>.
198      *
199      * <p>
200      * Note that "the validation" here means
201      * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating
202      * parser</a> as defined in the XML recommendation.
203      * In other words, it essentially just controls the DTD validation.
204      * (except the legacy two properties defined in JAXP 1.2.)
205      * </p>
206      *
207      * <p>
208      * To use modern schema languages such as W3C XML Schema or
209      * RELAX NG instead of DTD, you can configure your parser to be
210      * a non-validating parser by leaving the {@link #setValidating(boolean)}
211      * method <code>false</code>, then use the {@link #setSchema(Schema)}
212      * method to associate a schema to a parser.
213      * </p>
214      *
215      * @param validating true if the parser produced will validate documents
216      *                   as they are parsed; false otherwise.
217      */
218 
219     public void setValidating(boolean validating) {
220         this.validating = validating;
221     }
222 
223     /**
224      * Specifies that the parsers created by this  factory must eliminate
225      * whitespace in element content (sometimes known loosely as
226      * 'ignorable whitespace') when parsing XML documents (see XML Rec
227      * 2.10). Note that only whitespace which is directly contained within
228      * element content that has an element only content model (see XML
229      * Rec 3.2.1) will be eliminated. Due to reliance on the content model
230      * this setting requires the parser to be in validating mode. By default
231      * the value of this is set to <code>false</code>.
232      *
233      * @param whitespace true if the parser created must eliminate whitespace
234      *                   in the element content when parsing XML documents;
235      *                   false otherwise.
236      */
237 
238     public void setIgnoringElementContentWhitespace(boolean whitespace) {
239         this.whitespace = whitespace;
240     }
241 
242     /**
243      * Specifies that the parser produced by this code will
244      * expand entity reference nodes. By default the value of this is set to
245      * <code>true</code>
246      *
247      * @param expandEntityRef true if the parser produced will expand entity
248      *                        reference nodes; false otherwise.
249      */
250 
251     public void setExpandEntityReferences(boolean expandEntityRef) {
252         this.expandEntityRef = expandEntityRef;
253     }
254 
255     /**
256      * <p>Specifies that the parser produced by this code will
257      * ignore comments. By default the value of this is set to <code>false
258      * </code>.</p>
259      *
260      * @param ignoreComments <code>boolean</code> value to ignore comments during processing
261      */
262 
263     public void setIgnoringComments(boolean ignoreComments) {
264         this.ignoreComments = ignoreComments;
265     }
266 
267     /**
268      * Specifies that the parser produced by this code will
269      * convert CDATA nodes to Text nodes and append it to the
270      * adjacent (if any) text node. By default the value of this is set to
271      * <code>false</code>
272      *
273      * @param coalescing  true if the parser produced will convert CDATA nodes
274      *                    to Text nodes and append it to the adjacent (if any)
275      *                    text node; false otherwise.
276      */
277 
278     public void setCoalescing(boolean coalescing) {
279         this.coalescing = coalescing;
280     }
281 
282     /**
283      * Indicates whether or not the factory is configured to produce
284      * parsers which are namespace aware.
285      *
286      * @return  true if the factory is configured to produce parsers which
287      *          are namespace aware; false otherwise.
288      */
289 
290     public boolean isNamespaceAware() {
291         return namespaceAware;
292     }
293 
294     /**
295      * Indicates whether or not the factory is configured to produce
296      * parsers which validate the XML content during parse.
297      *
298      * @return  true if the factory is configured to produce parsers
299      *          which validate the XML content during parse; false otherwise.
300      */
301 
302     public boolean isValidating() {
303         return validating;
304     }
305 
306     /**
307      * Indicates whether or not the factory is configured to produce
308      * parsers which ignore ignorable whitespace in element content.
309      *
310      * @return  true if the factory is configured to produce parsers
311      *          which ignore ignorable whitespace in element content;
312      *          false otherwise.
313      */
314 
315     public boolean isIgnoringElementContentWhitespace() {
316         return whitespace;
317     }
318 
319     /**
320      * Indicates whether or not the factory is configured to produce
321      * parsers which expand entity reference nodes.
322      *
323      * @return  true if the factory is configured to produce parsers
324      *          which expand entity reference nodes; false otherwise.
325      */
326 
327     public boolean isExpandEntityReferences() {
328         return expandEntityRef;
329     }
330 
331     /**
332      * Indicates whether or not the factory is configured to produce
333      * parsers which ignores comments.
334      *
335      * @return  true if the factory is configured to produce parsers
336      *          which ignores comments; false otherwise.
337      */
338 
339     public boolean isIgnoringComments() {
340         return ignoreComments;
341     }
342 
343     /**
344      * Indicates whether or not the factory is configured to produce
345      * parsers which converts CDATA nodes to Text nodes and appends it to
346      * the adjacent (if any) Text node.
347      *
348      * @return  true if the factory is configured to produce parsers
349      *          which converts CDATA nodes to Text nodes and appends it to
350      *          the adjacent (if any) Text node; false otherwise.
351      */
352 
353     public boolean isCoalescing() {
354         return coalescing;
355     }
356 
357     /**
358      * Allows the user to set specific attributes on the underlying
359      * implementation.
360      * <p>
361      * All implementations that implement JAXP 1.5 or newer are required to
362      * support the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} and
363      * {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} properties.
364      * </p>
365      * <ul>
366      *   <li>
367      *      <p>
368      *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_DTD} property
369      *      restricts the access to external DTDs, external Entity References to the
370      *      protocols specified by the property.
371      *      If access is denied during parsing due to the restriction of this property,
372      *      {@link org.xml.sax.SAXException} will be thrown by the parse methods defined by
373      *      {@link javax.xml.parsers.DocumentBuilder}.
374      *      </p>
375      *      <p>
376      *      Setting the {@link javax.xml.XMLConstants#ACCESS_EXTERNAL_SCHEMA} property
377      *      restricts the access to external Schema set by the schemaLocation attribute to
378      *      the protocols specified by the property.  If access is denied during parsing
379      *      due to the restriction of this property, {@link org.xml.sax.SAXException}
380      *      will be thrown by the parse methods defined by
381      *      {@link javax.xml.parsers.DocumentBuilder}.
382      *      </p>
383      *   </li>
384      * </ul>
385      *
386      * @param name The name of the attribute.
387      * @param value The value of the attribute.
388      *
389      * @throws IllegalArgumentException thrown if the underlying
390      *   implementation doesn't recognize the attribute.
391      */
392     public abstract void setAttribute(String name, Object value)
393                 throws IllegalArgumentException;
394 
395     /**
396      * Allows the user to retrieve specific attributes on the underlying
397      * implementation.
398      *
399      * @param name The name of the attribute.
400      *
401      * @return value The value of the attribute.
402      *
403      * @throws IllegalArgumentException thrown if the underlying
404      *   implementation doesn't recognize the attribute.
405      */
406     public abstract Object getAttribute(String name)
407                 throws IllegalArgumentException;
408 
409     /**
410      * <p>Set a feature for this <code>DocumentBuilderFactory</code> and <code>DocumentBuilder</code>s created by this factory.</p>
411      *
412      * <p>
413      * Feature names are fully qualified {@link java.net.URI}s.
414      * Implementations may define their own features.
415      * A {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the
416      * <code>DocumentBuilder</code>s it creates cannot support the feature.
417      * It is possible for a <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state.
418      * </p>
419      *
420      * <p>
421      * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
422      * When the feature is:</p>
423      * <ul>
424      *   <li>
425      *     <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
426      *     Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources.
427      *     If XML processing is limited for security reasons, it will be reported via a call to the registered
428      *    {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}.
429      *     See {@link  DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}.
430      *   </li>
431      *   <li>
432      *     <code>false</code>: the implementation will processing XML according to the XML specifications without
433      *     regard to possible implementation limits.
434      *   </li>
435      * </ul>
436      *
437      * @param name Feature name.
438      * @param value Is feature state <code>true</code> or <code>false</code>.
439      *
440      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> or the <code>DocumentBuilder</code>s
441      *   it creates cannot support this feature.
442      * @throws NullPointerException If the <code>name</code> parameter is null.
443      */
444     public abstract void setFeature(String name, boolean value)
445             throws ParserConfigurationException;
446 
447     /**
448      * <p>Get the state of the named feature.</p>
449      *
450      * <p>
451      * Feature names are fully qualified {@link java.net.URI}s.
452      * Implementations may define their own features.
453      * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the
454      * <code>DocumentBuilder</code>s it creates cannot support the feature.
455      * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state.
456      * </p>
457      *
458      * @param name Feature name.
459      *
460      * @return State of the named feature.
461      *
462      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code>
463      *   or the <code>DocumentBuilder</code>s it creates cannot support this feature.
464      */
465     public abstract boolean getFeature(String name)
466             throws ParserConfigurationException;
467 
468 
469     /**
470      * Gets the {@link Schema} object specified through
471      * the {@link #setSchema(Schema schema)} method.
472      *
473      * @return
474      *      the {@link Schema} object that was last set through
475      *      the {@link #setSchema(Schema)} method, or null
476      *      if the method was not invoked since a {@link DocumentBuilderFactory}
477      *      is created.
478      *
479      * @throws UnsupportedOperationException When implementation does not
480      *   override this method.
481      *
482      * @since 1.5
483      */
484     public Schema getSchema() {
485         throw new UnsupportedOperationException(
486             "This parser does not support specification \""
487             + this.getClass().getPackage().getSpecificationTitle()
488             + "\" version \""
489             + this.getClass().getPackage().getSpecificationVersion()
490             + "\""
491             );
492 
493     }
494 
495     /**
496      * <p>Set the {@link Schema} to be used by parsers created
497      * from this factory.
498      *
499      * <p>
500      * When a {@link Schema} is non-null, a parser will use a validator
501      * created from it to validate documents before it passes information
502      * down to the application.
503      *
504      * <p>When errors are found by the validator, the parser is responsible
505      * to report them to the user-specified {@link org.xml.sax.ErrorHandler}
506      * (or if the error handler is not set, ignore them or throw them), just
507      * like any other errors found by the parser itself.
508      * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
509      * is set, it must receive those errors, and if not, they must be
510      * treated according to the implementation specific
511      * default error handling rules.
512      *
513      * <p>
514      * A validator may modify the outcome of a parse (for example by
515      * adding default values that were missing in documents), and a parser
516      * is responsible to make sure that the application will receive
517      * modified DOM trees.
518      *
519      * <p>
520      * Initialy, null is set as the {@link Schema}.
521      *
522      * <p>
523      * This processing will take effect even if
524      * the {@link #isValidating()} method returns <code>false</code>.
525      *
526      * <p>It is an error to use
527      * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code>;
528      * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code>;
529      * property in conjunction with a {@link Schema} object.
530      * Such configuration will cause a {@link ParserConfigurationException}
531      * exception when the {@link #newDocumentBuilder()} is invoked.</p>
532      *
533      *
534      * <h4>Note for implmentors</h4>
535      *
536      * <p>
537      * A parser must be able to work with any {@link Schema}
538      * implementation. However, parsers and schemas are allowed
539      * to use implementation-specific custom mechanisms
540      * as long as they yield the result described in the specification.
541      * </p>
542      *
543      * @param schema <code>Schema</code> to use or <code>null</code>
544      *   to remove a schema.
545      *
546      * @throws UnsupportedOperationException When implementation does not
547      *   override this method.
548      *
549      * @since 1.5
550      */
551     public void setSchema(Schema schema) {
552         throw new UnsupportedOperationException(
553             "This parser does not support specification \""
554             + this.getClass().getPackage().getSpecificationTitle()
555             + "\" version \""
556             + this.getClass().getPackage().getSpecificationVersion()
557             + "\""
558             );
559     }
560 
561 
562 
563     /**
564      * <p>Set state of XInclude processing.</p>
565      *
566      * <p>If XInclude markup is found in the document instance, should it be
567      * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
568      * XML Inclusions (XInclude) Version 1.0</a>.</p>
569      *
570      * <p>XInclude processing defaults to <code>false</code>.</p>
571      *
572      * @param state Set XInclude processing to <code>true</code> or
573      *   <code>false</code>
574      *
575      * @throws UnsupportedOperationException When implementation does not
576      *   override this method.
577      *
578      * @since 1.5
579      */
580     public void setXIncludeAware(final boolean state) {
581         if (state) {
582             throw new UnsupportedOperationException(" setXIncludeAware " +
583                 "is not supported on this JAXP" +
584                 " implementation or earlier: " + this.getClass());
585         }
586     }
587 
588     /**
589      * <p>Get state of XInclude processing.</p>
590      *
591      * @return current state of XInclude processing
592      *
593      * @throws UnsupportedOperationException When implementation does not
594      *   override this method.
595      *
596      * @since 1.5
597      */
598     public boolean isXIncludeAware() {
599         throw new UnsupportedOperationException(
600             "This parser does not support specification \""
601             + this.getClass().getPackage().getSpecificationTitle()
602             + "\" version \""
603             + this.getClass().getPackage().getSpecificationVersion()
604             + "\""
605             );
606     }
607 }