1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 // $Id: DocumentBuilderFactory.java 884950 2009-11-27 18:46:18Z mrglavas $
19 
20 package javax.xml.parsers;
21 
22 import javax.xml.validation.Schema;
23 import org.apache.harmony.xml.parsers.DocumentBuilderFactoryImpl;
24 
25 /**
26  * Defines a factory API that enables applications to obtain a
27  * parser that produces DOM object trees from XML documents.
28  *
29  * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
30  * @version $Revision: 884950 $, $Date: 2009-11-27 10:46:18 -0800 (Fri, 27 Nov 2009) $
31  */
32 
33 public abstract class DocumentBuilderFactory {
34 
35     private boolean validating = false;
36     private boolean namespaceAware = false;
37     private boolean whitespace = false;
38     private boolean expandEntityRef = true;
39     private boolean ignoreComments = false;
40     private boolean coalescing = false;
41 
DocumentBuilderFactory()42     protected DocumentBuilderFactory () {
43     }
44 
45     /**
46      * Returns Android's implementation of {@code DocumentBuilderFactory}.
47      * Unlike other Java implementations, this method does not consult system
48      * properties, property files, or the services API.
49      *
50      * @return a new DocumentBuilderFactory.
51      */
newInstance()52     public static DocumentBuilderFactory newInstance() {
53         // instantiate the class directly rather than using reflection
54         return new DocumentBuilderFactoryImpl();
55     }
56 
57     /**
58      * Returns an instance of the named implementation of {@code DocumentBuilderFactory}.
59      *
60      * @throws FactoryConfigurationError if {@code factoryClassName} is not available or cannot be
61      *     instantiated.
62      * @since 1.6
63      */
newInstance(String factoryClassName, ClassLoader classLoader)64     public static DocumentBuilderFactory newInstance(String factoryClassName,
65             ClassLoader classLoader) {
66         if (factoryClassName == null) {
67             throw new FactoryConfigurationError("factoryClassName == null");
68         }
69         if (classLoader == null) {
70             classLoader = Thread.currentThread().getContextClassLoader();
71         }
72         try {
73             Class<?> type = classLoader != null
74                     ? classLoader.loadClass(factoryClassName)
75                     : Class.forName(factoryClassName);
76             return (DocumentBuilderFactory) type.newInstance();
77         } catch (ClassNotFoundException e) {
78             throw new FactoryConfigurationError(e);
79         } catch (InstantiationException e) {
80             throw new FactoryConfigurationError(e);
81         } catch (IllegalAccessException e) {
82             throw new FactoryConfigurationError(e);
83         }
84     }
85 
86     /**
87      * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder}
88      * using the currently configured parameters.
89      *
90      * @exception ParserConfigurationException if a DocumentBuilder
91      * cannot be created which satisfies the configuration requested.
92      * @return A new instance of a DocumentBuilder.
93      */
94 
newDocumentBuilder()95     public abstract DocumentBuilder newDocumentBuilder()
96         throws ParserConfigurationException;
97 
98 
99     /**
100      * Specifies that the parser produced by this code will
101      * provide support for XML namespaces. By default the value of this is set
102      * to <code>false</code>
103      *
104      * @param awareness true if the parser produced will provide support
105      *                  for XML namespaces; false otherwise.
106      */
107 
setNamespaceAware(boolean awareness)108     public void setNamespaceAware(boolean awareness) {
109         this.namespaceAware = awareness;
110     }
111 
112     /**
113      * Specifies that the parser produced by this code will
114      * validate documents as they are parsed. By default the value of this
115      * is set to <code>false</code>.
116      *
117      * <p>
118      * Note that "the validation" here means
119      * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating
120      * parser</a> as defined in the XML recommendation.
121      * In other words, it essentially just controls the DTD validation.
122      * (except the legacy two properties defined in JAXP 1.2.
123      * See <a href="#validationCompatibility">here</a> for more details.)
124      * </p>
125      *
126      * <p>
127      * To use modern schema languages such as W3C XML Schema or
128      * RELAX NG instead of DTD, you can configure your parser to be
129      * a non-validating parser by leaving the {@link #setValidating(boolean)}
130      * method <tt>false</tt>, then use the {@link #setSchema(Schema)}
131      * method to associate a schema to a parser.
132      * </p>
133      *
134      * @param validating true if the parser produced will validate documents
135      *                   as they are parsed; false otherwise.
136      */
137 
setValidating(boolean validating)138     public void setValidating(boolean validating) {
139         this.validating = validating;
140     }
141 
142     /**
143      * Specifies that the parsers created by this  factory must eliminate
144      * whitespace in element content (sometimes known loosely as
145      * 'ignorable whitespace') when parsing XML documents (see XML Rec
146      * 2.10). Note that only whitespace which is directly contained within
147      * element content that has an element only content model (see XML
148      * Rec 3.2.1) will be eliminated. Due to reliance on the content model
149      * this setting requires the parser to be in validating mode. By default
150      * the value of this is set to <code>false</code>.
151      *
152      * @param whitespace true if the parser created must eliminate whitespace
153      *                   in the element content when parsing XML documents;
154      *                   false otherwise.
155      */
156 
setIgnoringElementContentWhitespace(boolean whitespace)157     public void setIgnoringElementContentWhitespace(boolean whitespace) {
158         this.whitespace = whitespace;
159     }
160 
161     /**
162      * Specifies that the parser produced by this code will
163      * expand entity reference nodes. By default the value of this is set to
164      * <code>true</code>
165      *
166      * @param expandEntityRef true if the parser produced will expand entity
167      *                        reference nodes; false otherwise.
168      */
169 
setExpandEntityReferences(boolean expandEntityRef)170     public void setExpandEntityReferences(boolean expandEntityRef) {
171         this.expandEntityRef = expandEntityRef;
172     }
173 
174     /**
175      * <p>Specifies that the parser produced by this code will
176      * ignore comments. By default the value of this is set to <code>false
177      * </code>.</p>
178      *
179      * @param ignoreComments <code>boolean</code> value to ignore comments during processing
180      */
181 
setIgnoringComments(boolean ignoreComments)182     public void setIgnoringComments(boolean ignoreComments) {
183         this.ignoreComments = ignoreComments;
184     }
185 
186     /**
187      * Specifies that the parser produced by this code will
188      * convert CDATA nodes to Text nodes and append it to the
189      * adjacent (if any) text node. By default the value of this is set to
190      * <code>false</code>
191      *
192      * @param coalescing  true if the parser produced will convert CDATA nodes
193      *                    to Text nodes and append it to the adjacent (if any)
194      *                    text node; false otherwise.
195      */
196 
setCoalescing(boolean coalescing)197     public void setCoalescing(boolean coalescing) {
198         this.coalescing = coalescing;
199     }
200 
201     /**
202      * Indicates whether or not the factory is configured to produce
203      * parsers which are namespace aware.
204      *
205      * @return  true if the factory is configured to produce parsers which
206      *          are namespace aware; false otherwise.
207      */
208 
isNamespaceAware()209     public boolean isNamespaceAware() {
210         return namespaceAware;
211     }
212 
213     /**
214      * Indicates whether or not the factory is configured to produce
215      * parsers which validate the XML content during parse.
216      *
217      * @return  true if the factory is configured to produce parsers
218      *          which validate the XML content during parse; false otherwise.
219      */
220 
isValidating()221     public boolean isValidating() {
222         return validating;
223     }
224 
225     /**
226      * Indicates whether or not the factory is configured to produce
227      * parsers which ignore ignorable whitespace in element content.
228      *
229      * @return  true if the factory is configured to produce parsers
230      *          which ignore ignorable whitespace in element content;
231      *          false otherwise.
232      */
233 
isIgnoringElementContentWhitespace()234     public boolean isIgnoringElementContentWhitespace() {
235         return whitespace;
236     }
237 
238     /**
239      * Indicates whether or not the factory is configured to produce
240      * parsers which expand entity reference nodes.
241      *
242      * @return  true if the factory is configured to produce parsers
243      *          which expand entity reference nodes; false otherwise.
244      */
245 
isExpandEntityReferences()246     public boolean isExpandEntityReferences() {
247         return expandEntityRef;
248     }
249 
250     /**
251      * Indicates whether or not the factory is configured to produce
252      * parsers which ignores comments.
253      *
254      * @return  true if the factory is configured to produce parsers
255      *          which ignores comments; false otherwise.
256      */
257 
isIgnoringComments()258     public boolean isIgnoringComments() {
259         return ignoreComments;
260     }
261 
262     /**
263      * Indicates whether or not the factory is configured to produce
264      * parsers which converts CDATA nodes to Text nodes and appends it to
265      * the adjacent (if any) Text node.
266      *
267      * @return  true if the factory is configured to produce parsers
268      *          which converts CDATA nodes to Text nodes and appends it to
269      *          the adjacent (if any) Text node; false otherwise.
270      */
271 
isCoalescing()272     public boolean isCoalescing() {
273         return coalescing;
274     }
275 
276     /**
277      * Allows the user to set specific attributes on the underlying
278      * implementation.
279      * @param name The name of the attribute.
280      * @param value The value of the attribute.
281      * @exception IllegalArgumentException thrown if the underlying
282      * implementation doesn't recognize the attribute.
283      */
setAttribute(String name, Object value)284     public abstract void setAttribute(String name, Object value)
285                 throws IllegalArgumentException;
286 
287     /**
288      * Allows the user to retrieve specific attributes on the underlying
289      * implementation.
290      * @param name The name of the attribute.
291      * @return value The value of the attribute.
292      * @exception IllegalArgumentException thrown if the underlying
293      * implementation doesn't recognize the attribute.
294      */
getAttribute(String name)295     public abstract Object getAttribute(String name)
296                 throws IllegalArgumentException;
297 
298     /**
299      * <p>Set a feature for this <code>DocumentBuilderFactory</code> and <code>DocumentBuilder</code>s created by this factory.</p>
300      *
301      * <p>
302      * Feature names are fully qualified {@link java.net.URI}s.
303      * Implementations may define their own features.
304      * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the
305      * <code>DocumentBuilder</code>s it creates cannot support the feature.
306      * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state.
307      * </p>
308      *
309      * <p>
310      * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
311      * When the feature is:</p>
312      * <ul>
313      *   <li>
314      *     <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
315      *     Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources.
316      *     If XML processing is limited for security reasons, it will be reported via a call to the registered
317      *    {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}.
318      *     See {@link  DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}.
319      *   </li>
320      *   <li>
321      *     <code>false</code>: the implementation will processing XML according to the XML specifications without
322      *     regard to possible implementation limits.
323      *   </li>
324      * </ul>
325      *
326      * @param name Feature name.
327      * @param value Is feature state <code>true</code> or <code>false</code>.
328      *
329      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> or the <code>DocumentBuilder</code>s
330      *   it creates cannot support this feature.
331      * @throws NullPointerException If the <code>name</code> parameter is null.
332      */
setFeature(String name, boolean value)333     public abstract void setFeature(String name, boolean value)
334         throws ParserConfigurationException;
335 
336     /**
337      * <p>Get the state of the named feature.</p>
338      *
339      * <p>
340      * Feature names are fully qualified {@link java.net.URI}s.
341      * Implementations may define their own features.
342      * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the
343      * <code>DocumentBuilder</code>s it creates cannot support the feature.
344      * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state.
345      * </p>
346      *
347      * @param name Feature name.
348      *
349      * @return State of the named feature.
350      *
351      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code>
352      *   or the <code>DocumentBuilder</code>s it creates cannot support this feature.
353      */
getFeature(String name)354     public abstract boolean getFeature(String name)
355         throws ParserConfigurationException;
356 
357     /**
358      * Gets the {@link Schema} object specified through
359      * the {@link #setSchema(Schema schema)} method.
360      *
361      *
362      * @throws UnsupportedOperationException
363      *      For backward compatibility, when implementations for
364      *      earlier versions of JAXP is used, this exception will be
365      *      thrown.
366      *
367      * @return
368      *      the {@link Schema} object that was last set through
369      *      the {@link #setSchema(Schema)} method, or null
370      *      if the method was not invoked since a {@link DocumentBuilderFactory}
371      *      is created.
372      *
373      * @since 1.5
374      */
getSchema()375     public Schema getSchema() {
376         throw new UnsupportedOperationException(
377             "This parser does not support specification \""
378             + this.getClass().getPackage().getSpecificationTitle()
379             + "\" version \""
380             + this.getClass().getPackage().getSpecificationVersion()
381             + "\""
382             );
383 
384     }
385 
386     /**
387      * <p>Set the {@link Schema} to be used by parsers created
388      * from this factory.
389      *
390      * <p>
391      * When a {@link Schema} is non-null, a parser will use a validator
392      * created from it to validate documents before it passes information
393      * down to the application.
394      *
395      * <p>When errors are found by the validator, the parser is responsible
396      * to report them to the user-specified {@link org.xml.sax.ErrorHandler}
397      * (or if the error handler is not set, ignore them or throw them), just
398      * like any other errors found by the parser itself.
399      * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
400      * is set, it must receive those errors, and if not, they must be
401      * treated according to the implementation specific
402      * default error handling rules.
403      *
404      * <p>
405      * A validator may modify the outcome of a parse (for example by
406      * adding default values that were missing in documents), and a parser
407      * is responsible to make sure that the application will receive
408      * modified DOM trees.
409      *
410      * <p>
411      * Initially, null is set as the {@link Schema}.
412      *
413      * <p>
414      * This processing will take effect even if
415      * the {@link #isValidating()} method returns <tt>false</tt>.
416      *
417      * <p>It is an error to use
418      * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code>
419      * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code>
420      * property in conjunction with a {@link Schema} object.
421      * Such configuration will cause a {@link ParserConfigurationException}
422      * exception when the {@link #newDocumentBuilder()} is invoked.</p>
423      *
424      *
425      * <h4>Note for implementors</h4>
426      * <p>
427      * A parser must be able to work with any {@link Schema}
428      * implementation. However, parsers and schemas are allowed
429      * to use implementation-specific custom mechanisms
430      * as long as they yield the result described in the specification.
431      *
432      * @param schema <code>Schema</code> to use or <code>null</code> to remove a schema.
433      *
434      * @throws UnsupportedOperationException
435      *      For backward compatibility, when implementations for
436      *      earlier versions of JAXP is used, this exception will be
437      *      thrown.
438      *
439      * @since 1.5
440      */
setSchema(Schema schema)441     public void setSchema(Schema schema) {
442         throw new UnsupportedOperationException(
443             "This parser does not support specification \""
444             + this.getClass().getPackage().getSpecificationTitle()
445             + "\" version \""
446             + this.getClass().getPackage().getSpecificationVersion()
447             + "\""
448             );
449     }
450 
451     /**
452      * <p>Set state of XInclude processing.</p>
453      *
454      * <p>If XInclude markup is found in the document instance, should it be
455      * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
456      * XML Inclusions (XInclude) Version 1.0</a>.</p>
457      *
458      * <p>XInclude processing defaults to <code>false</code>.</p>
459      *
460      * @param state Set XInclude processing to <code>true</code> or
461      *   <code>false</code>
462      *
463      * @throws UnsupportedOperationException
464      *      For backward compatibility, when implementations for
465      *      earlier versions of JAXP is used, this exception will be
466      *      thrown.
467      *
468      * @since 1.5
469      */
setXIncludeAware(final boolean state)470     public void setXIncludeAware(final boolean state) {
471         throw new UnsupportedOperationException(
472             "This parser does not support specification \""
473             + this.getClass().getPackage().getSpecificationTitle()
474             + "\" version \""
475             + this.getClass().getPackage().getSpecificationVersion()
476             + "\""
477             );
478     }
479 
480     /**
481      * <p>Get state of XInclude processing.</p>
482      *
483      * @return current state of XInclude processing
484      *
485      * @throws UnsupportedOperationException
486      *      For backward compatibility, when implementations for
487      *      earlier versions of JAXP is used, this exception will be
488      *      thrown.
489      *
490      * @since 1.5
491      */
isXIncludeAware()492     public boolean isXIncludeAware() {
493         throw new UnsupportedOperationException(
494             "This parser does not support specification \""
495             + this.getClass().getPackage().getSpecificationTitle()
496             + "\" version \""
497             + this.getClass().getPackage().getSpecificationVersion()
498             + "\""
499             );
500     }
501 }
502