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: SAXParserFactory.java 884950 2009-11-27 18:46:18Z mrglavas $
19
20package javax.xml.parsers;
21
22import javax.xml.validation.Schema;
23import org.apache.harmony.xml.parsers.SAXParserFactoryImpl;
24import org.xml.sax.SAXException;
25import org.xml.sax.SAXNotRecognizedException;
26import org.xml.sax.SAXNotSupportedException;
27
28/**
29 * Defines a factory API that enables applications to configure and
30 * obtain a SAX based parser to parse XML documents.
31 *
32 * @author <a href="Jeff.Suttor@Sun.com">Jeff Suttor</a>
33 * @version $Revision: 884950 $, $Date: 2009-11-27 10:46:18 -0800 (Fri, 27 Nov 2009) $
34 */
35public abstract class SAXParserFactory {
36
37    /**
38     * <p>Should Parsers be validating?</p>
39     */
40    private boolean validating = false;
41
42    /**
43     * <p>Should Parsers be namespace aware?</p>
44     */
45    private boolean namespaceAware = false;
46
47    /**
48     * <p>Protected constructor to force use of {@link #newInstance()}.</p>
49     */
50    protected SAXParserFactory () {
51
52    }
53
54    /**
55     * Returns Android's implementation of {@code SAXParserFactory}. Unlike
56     * other Java implementations, this method does not consult system
57     * properties, property files, or the services API.
58     *
59     * @return a new SAXParserFactory.
60     *
61     * @exception FactoryConfigurationError never. Included for API
62     *     compatibility with other Java implementations.
63     */
64    public static SAXParserFactory newInstance() {
65        // instantiate the class directly rather than using reflection
66        return new SAXParserFactoryImpl();
67    }
68
69    /**
70     * Returns an instance of the named implementation of {@code SAXParserFactory}.
71     *
72     * @throws FactoryConfigurationError if {@code factoryClassName} is not available or cannot be
73     *     instantiated.
74     * @since 1.6
75     */
76    public static SAXParserFactory newInstance(String factoryClassName,
77            ClassLoader classLoader) {
78        if (factoryClassName == null) {
79            throw new FactoryConfigurationError("factoryClassName == null");
80        }
81        if (classLoader == null) {
82            classLoader = Thread.currentThread().getContextClassLoader();
83        }
84        try {
85            Class<?> type = classLoader != null
86                    ? classLoader.loadClass(factoryClassName)
87                    : Class.forName(factoryClassName);
88            return (SAXParserFactory) type.newInstance();
89        } catch (ClassNotFoundException e) {
90            throw new FactoryConfigurationError(e);
91        } catch (InstantiationException e) {
92            throw new FactoryConfigurationError(e);
93        } catch (IllegalAccessException e) {
94            throw new FactoryConfigurationError(e);
95        }
96    }
97
98    /**
99     * <p>Creates a new instance of a SAXParser using the currently
100     * configured factory parameters.</p>
101     *
102     * @return A new instance of a SAXParser.
103     *
104     * @exception ParserConfigurationException if a parser cannot
105     *   be created which satisfies the requested configuration.
106     * @exception SAXException for SAX errors.
107     */
108
109    public abstract SAXParser newSAXParser()
110        throws ParserConfigurationException, SAXException;
111
112
113    /**
114     * Specifies that the parser produced by this code will
115     * provide support for XML namespaces. By default the value of this is set
116     * to <code>false</code>.
117     *
118     * @param awareness true if the parser produced by this code will
119     *                  provide support for XML namespaces; false otherwise.
120     */
121
122    public void setNamespaceAware(boolean awareness) {
123        this.namespaceAware = awareness;
124    }
125
126    /**
127     * Specifies that the parser produced by this code will
128     * validate documents as they are parsed. By default the value of this is
129     * set to <code>false</code>.
130     *
131     * <p>
132     * Note that "the validation" here means
133     * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating
134     * parser</a> as defined in the XML recommendation.
135     * In other words, it essentially just controls the DTD validation.
136     * (except the legacy two properties defined in JAXP 1.2.
137     * See <a href="#validationCompatibility">here</a> for more details.)
138     * </p>
139     *
140     * <p>
141     * To use modern schema languages such as W3C XML Schema or
142     * RELAX NG instead of DTD, you can configure your parser to be
143     * a non-validating parser by leaving the {@link #setValidating(boolean)}
144     * method <tt>false</tt>, then use the {@link #setSchema(Schema)}
145     * method to associate a schema to a parser.
146     * </p>
147     *
148     * @param validating true if the parser produced by this code will
149     *                   validate documents as they are parsed; false otherwise.
150     */
151
152    public void setValidating(boolean validating) {
153        this.validating = validating;
154    }
155
156    /**
157     * Indicates whether or not the factory is configured to produce
158     * parsers which are namespace aware.
159     *
160     * @return true if the factory is configured to produce
161     *         parsers which are namespace aware; false otherwise.
162     */
163
164    public boolean isNamespaceAware() {
165        return namespaceAware;
166    }
167
168    /**
169     * Indicates whether or not the factory is configured to produce
170     * parsers which validate the XML content during parse.
171     *
172     * @return true if the factory is configured to produce parsers which validate
173     *         the XML content during parse; false otherwise.
174     */
175
176    public boolean isValidating() {
177        return validating;
178    }
179
180    /**
181     *
182     * <p>Sets the particular feature in the underlying implementation of
183     * org.xml.sax.XMLReader.
184     * A list of the core features and properties can be found at
185     * <a href="http://www.saxproject.org/">http://www.saxproject.org/</a></p>
186     *
187     * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature.
188     * When the feature is</p>
189     * <ul>
190     *   <li>
191     *     <code>true</code>: the implementation will limit XML processing to conform to implementation limits.
192     *     Examples include entity expansion limits and XML Schema constructs that would consume large amounts of resources.
193     *     If XML processing is limited for security reasons, it will be reported via a call to the registered
194     *     {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}.
195     *     See {@link SAXParser} <code>parse</code> methods for handler specification.
196     *   </li>
197     *   <li>
198     *     When the feature is <code>false</code>, the implementation will processing XML according to the XML specifications without
199     *     regard to possible implementation limits.
200     *   </li>
201     * </ul>
202     *
203     * @param name The name of the feature to be set.
204     * @param value The value of the feature to be set.
205     *
206     * @exception ParserConfigurationException if a parser cannot
207     *     be created which satisfies the requested configuration.
208     * @exception SAXNotRecognizedException When the underlying XMLReader does
209     *            not recognize the property name.
210     * @exception SAXNotSupportedException When the underlying XMLReader
211     *            recognizes the property name but doesn't support the
212     *            property.
213     * @throws NullPointerException If the <code>name</code> parameter is null.
214     *
215     * @see org.xml.sax.XMLReader#setFeature
216     */
217    public abstract void setFeature(String name, boolean value)
218        throws ParserConfigurationException, SAXNotRecognizedException,
219                SAXNotSupportedException;
220
221    /**
222     *
223     * <p>Returns the particular property requested for in the underlying
224     * implementation of org.xml.sax.XMLReader.</p>
225     *
226     * @param name The name of the property to be retrieved.
227     *
228     * @return Value of the requested property.
229     *
230     * @exception ParserConfigurationException if a parser cannot be created which satisfies the requested configuration.
231     * @exception SAXNotRecognizedException When the underlying XMLReader does not recognize the property name.
232     * @exception SAXNotSupportedException When the underlying XMLReader recognizes the property name but doesn't support the property.
233     *
234     * @see org.xml.sax.XMLReader#getProperty
235     */
236    public abstract boolean getFeature(String name)
237        throws ParserConfigurationException, SAXNotRecognizedException,
238                SAXNotSupportedException;
239
240    /**
241     * Gets the {@link Schema} object specified through
242     * the {@link #setSchema(Schema schema)} method.
243     *
244     *
245     * @throws UnsupportedOperationException
246     *      For backward compatibility, when implementations for
247     *      earlier versions of JAXP is used, this exception will be
248     *      thrown.
249     *
250     * @return
251     *      the {@link Schema} object that was last set through
252     *      the {@link #setSchema(Schema)} method, or null
253     *      if the method was not invoked since a {@link SAXParserFactory}
254     *      is created.
255     *
256     * @since 1.5
257     */
258    public Schema getSchema() {
259        throw new UnsupportedOperationException(
260            "This parser does not support specification \""
261            + this.getClass().getPackage().getSpecificationTitle()
262            + "\" version \""
263            + this.getClass().getPackage().getSpecificationVersion()
264            + "\""
265            );
266    }
267
268    /**
269     * <p>Set the {@link Schema} to be used by parsers created
270     * from this factory.</p>
271     *
272     * <p>When a {@link Schema} is non-null, a parser will use a validator
273     * created from it to validate documents before it passes information
274     * down to the application.</p>
275     *
276     * <p>When warnings/errors/fatal errors are found by the validator, the parser must
277     * handle them as if those errors were found by the parser itself.
278     * In other words, if the user-specified {@link org.xml.sax.ErrorHandler}
279     * is set, it must receive those errors, and if not, they must be
280     * treated according to the implementation specific
281     * default error handling rules.
282     *
283     * <p>A validator may modify the SAX event stream (for example by
284     * adding default values that were missing in documents), and a parser
285     * is responsible to make sure that the application will receive
286     * those modified event stream.</p>
287     *
288     * <p>Initially, <code>null</code> is set as the {@link Schema}.</p>
289     *
290     * <p>This processing will take effect even if
291     * the {@link #isValidating()} method returns <code>false</code>.
292     *
293     * <p>It is an error to use
294     * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code>
295     * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code>
296     * property in conjunction with a non-null {@link Schema} object.
297     * Such configuration will cause a {@link SAXException}
298     * exception when those properties are set on a {@link SAXParser}.</p>
299     *
300     * <h4>Note for implementors</h4>
301     * <p>
302     * A parser must be able to work with any {@link Schema}
303     * implementation. However, parsers and schemas are allowed
304     * to use implementation-specific custom mechanisms
305     * as long as they yield the result described in the specification.
306     * </p>
307     *
308     * @param schema <code>Schema</code> to use, <code>null</code> to remove a schema.
309     *
310     * @throws UnsupportedOperationException
311     *      For backward compatibility, when implementations for
312     *      earlier versions of JAXP is used, this exception will be
313     *      thrown.
314     *
315     * @since 1.5
316     */
317    public void setSchema(Schema schema) {
318        throw new UnsupportedOperationException(
319            "This parser does not support specification \""
320            + this.getClass().getPackage().getSpecificationTitle()
321            + "\" version \""
322            + this.getClass().getPackage().getSpecificationVersion()
323            + "\""
324            );
325    }
326
327    /**
328     * <p>Set state of XInclude processing.</p>
329     *
330     * <p>If XInclude markup is found in the document instance, should it be
331     * processed as specified in <a href="http://www.w3.org/TR/xinclude/">
332     * XML Inclusions (XInclude) Version 1.0</a>.</p>
333     *
334     * <p>XInclude processing defaults to <code>false</code>.</p>
335     *
336     * @param state Set XInclude processing to <code>true</code> or
337     *   <code>false</code>
338     *
339     * @throws UnsupportedOperationException
340     *      For backward compatibility, when implementations for
341     *      earlier versions of JAXP is used, this exception will be
342     *      thrown.
343     *
344     * @since 1.5
345     */
346    public void setXIncludeAware(final boolean state) {
347        throw new UnsupportedOperationException(
348            "This parser does not support specification \""
349            + this.getClass().getPackage().getSpecificationTitle()
350            + "\" version \""
351            + this.getClass().getPackage().getSpecificationVersion()
352            + "\""
353            );
354    }
355
356    /**
357     * <p>Get state of XInclude processing.</p>
358     *
359     * @return current state of XInclude processing
360     *
361     * @throws UnsupportedOperationException
362     *      For backward compatibility, when implementations for
363     *      earlier versions of JAXP is used, this exception will be
364     *      thrown.
365     *
366     * @since 1.5
367     */
368    public boolean isXIncludeAware() {
369        throw new UnsupportedOperationException(
370            "This parser does not support specification \""
371            + this.getClass().getPackage().getSpecificationTitle()
372            + "\" version \""
373            + this.getClass().getPackage().getSpecificationVersion()
374            + "\""
375            );
376    }
377}
378
379