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      * Earlier versions of this documentation have mandated support for the
311      * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature, but this is not a
312      * supported feature on any version of Android.
313      * </p>
314      *
315      * @param name Feature name.
316      * @param value Is feature state <code>true</code> or <code>false</code>.
317      *
318      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> or the <code>DocumentBuilder</code>s
319      *   it creates cannot support this feature.
320      * @throws NullPointerException If the <code>name</code> parameter is null.
321      */
setFeature(String name, boolean value)322     public abstract void setFeature(String name, boolean value)
323         throws ParserConfigurationException;
324 
325     /**
326      * <p>Get the state of the named feature.</p>
327      *
328      * <p>
329      * Feature names are fully qualified {@link java.net.URI}s.
330      * Implementations may define their own features.
331      * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the
332      * <code>DocumentBuilder</code>s it creates cannot support the feature.
333      * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state.
334      * </p>
335      *
336      * @param name Feature name.
337      *
338      * @return State of the named feature.
339      *
340      * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code>
341      *   or the <code>DocumentBuilder</code>s it creates cannot support this feature.
342      */
getFeature(String name)343     public abstract boolean getFeature(String name)
344         throws ParserConfigurationException;
345 
346     /**
347      * Gets the {@link Schema} object specified through
348      * the {@link #setSchema(Schema schema)} method.
349      *
350      *
351      * @throws UnsupportedOperationException
352      *      For backward compatibility, when implementations for
353      *      earlier versions of JAXP is used, this exception will be
354      *      thrown.
355      *
356      * @return
357      *      the {@link Schema} object that was last set through
358      *      the {@link #setSchema(Schema)} method, or null
359      *      if the method was not invoked since a {@link DocumentBuilderFactory}
360      *      is created.
361      *
362      * @since 1.5
363      */
getSchema()364     public Schema getSchema() {
365         throw new UnsupportedOperationException(
366             "This parser does not support specification \""
367             + this.getClass().getPackage().getSpecificationTitle()
368             + "\" version \""
369             + this.getClass().getPackage().getSpecificationVersion()
370             + "\""
371             );
372 
373     }
374 
375     /**
376      * <p>Set the {@link Schema} to be used by parsers created
377      * from this factory.
378      *
379      * <p>
380      * When a {@link Schema} is non-null, a parser will use a validator
381      * created from it to validate documents before it passes information
382      * down to the application.
383      *
384      * <p>When errors are found by the validator, the parser is responsible
385      * to report them to the user-specified {@link org.xml.sax.ErrorHandler}
386      * (or if the error handler is not set, ignore them or throw them), just
387      * like any other errors found by the parser itself.
388      * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
389      * is set, it must receive those errors, and if not, they must be
390      * treated according to the implementation specific
391      * default error handling rules.
392      *
393      * <p>
394      * A validator may modify the outcome of a parse (for example by
395      * adding default values that were missing in documents), and a parser
396      * is responsible to make sure that the application will receive
397      * modified DOM trees.
398      *
399      * <p>
400      * Initially, null is set as the {@link Schema}.
401      *
402      * <p>
403      * This processing will take effect even if
404      * the {@link #isValidating()} method returns <tt>false</tt>.
405      *
406      * <p>It is an error to use
407      * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code>
408      * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code>
409      * property in conjunction with a {@link Schema} object.
410      * Such configuration will cause a {@link ParserConfigurationException}
411      * exception when the {@link #newDocumentBuilder()} is invoked.</p>
412      *
413      *
414      * <h4>Note for implementors</h4>
415      * <p>
416      * A parser must be able to work with any {@link Schema}
417      * implementation. However, parsers and schemas are allowed
418      * to use implementation-specific custom mechanisms
419      * as long as they yield the result described in the specification.
420      *
421      * @param schema <code>Schema</code> to use or <code>null</code> to remove a schema.
422      *
423      * @throws UnsupportedOperationException
424      *      For backward compatibility, when implementations for
425      *      earlier versions of JAXP is used, this exception will be
426      *      thrown.
427      *
428      * @since 1.5
429      */
setSchema(Schema schema)430     public void setSchema(Schema schema) {
431         throw new UnsupportedOperationException(
432             "This parser does not support specification \""
433             + this.getClass().getPackage().getSpecificationTitle()
434             + "\" version \""
435             + this.getClass().getPackage().getSpecificationVersion()
436             + "\""
437             );
438     }
439 
440     /**
441      * <p>Set state of XInclude processing.</p>
442      *
443      * <p>If XInclude markup is found in the document instance, should it be
444      * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
445      * XML Inclusions (XInclude) Version 1.0</a>.</p>
446      *
447      * <p>XInclude processing defaults to <code>false</code>.</p>
448      *
449      * @param state Set XInclude processing to <code>true</code> or
450      *   <code>false</code>
451      *
452      * @throws UnsupportedOperationException
453      *      For backward compatibility, when implementations for
454      *      earlier versions of JAXP is used, this exception will be
455      *      thrown.
456      *
457      * @since 1.5
458      */
setXIncludeAware(final boolean state)459     public void setXIncludeAware(final boolean state) {
460         throw new UnsupportedOperationException(
461             "This parser does not support specification \""
462             + this.getClass().getPackage().getSpecificationTitle()
463             + "\" version \""
464             + this.getClass().getPackage().getSpecificationVersion()
465             + "\""
466             );
467     }
468 
469     /**
470      * <p>Get state of XInclude processing.</p>
471      *
472      * @return current state of XInclude processing
473      *
474      * @throws UnsupportedOperationException
475      *      For backward compatibility, when implementations for
476      *      earlier versions of JAXP is used, this exception will be
477      *      thrown.
478      *
479      * @since 1.5
480      */
isXIncludeAware()481     public boolean isXIncludeAware() {
482         throw new UnsupportedOperationException(
483             "This parser does not support specification \""
484             + this.getClass().getPackage().getSpecificationTitle()
485             + "\" version \""
486             + this.getClass().getPackage().getSpecificationVersion()
487             + "\""
488             );
489     }
490 }
491