Home | History | Annotate | Download | only in parsers
      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 (at) 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 
     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      */
     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      */
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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