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: DocumentBuilder.java 584483 2007-10-14 02:54:48Z mrglavas $
19
20package javax.xml.parsers;
21
22import java.io.File;
23import java.io.IOException;
24import java.io.InputStream;
25import javax.xml.validation.Schema;
26import org.w3c.dom.DOMImplementation;
27import org.w3c.dom.Document;
28import org.xml.sax.EntityResolver;
29import org.xml.sax.ErrorHandler;
30import org.xml.sax.InputSource;
31import org.xml.sax.SAXException;
32
33/**
34 * Defines the API to obtain DOM Document instances from an XML
35 * document. Using this class, an application programmer can obtain a
36 * {@link Document} from XML.<p>
37 *
38 * An instance of this class can be obtained from the
39 * {@link DocumentBuilderFactory#newDocumentBuilder()} method. Once
40 * an instance of this class is obtained, XML can be parsed from a
41 * variety of input sources. These input sources are InputStreams,
42 * Files, URLs, and SAX InputSources.<p>
43 *
44 * Note that this class reuses several classes from the SAX API. This
45 * does not require that the implementor of the underlying DOM
46 * implementation use a SAX parser to parse XML document into a
47 * <code>Document</code>. It merely requires that the implementation
48 * communicate with the application using these existing APIs.
49 *
50 * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a>
51 * @version $Revision: 584483 $, $Date: 2007-10-13 19:54:48 -0700 (Sat, 13 Oct 2007) $
52 */
53
54public abstract class DocumentBuilder {
55
56    private static final boolean DEBUG = false;
57
58    /** Protected constructor */
59    protected DocumentBuilder () {
60    }
61
62    /**
63      * <p>Reset this <code>DocumentBuilder</code> to its original configuration.</p>
64      *
65      * <p><code>DocumentBuilder</code> is reset to the same state as when it was created with
66      * {@link DocumentBuilderFactory#newDocumentBuilder()}.
67      * <code>reset()</code> is designed to allow the reuse of existing <code>DocumentBuilder</code>s
68      * thus saving resources associated with the creation of new <code>DocumentBuilder</code>s.</p>
69      *
70      * <p>The reset <code>DocumentBuilder</code> is not guaranteed to have the same {@link EntityResolver} or {@link ErrorHandler}
71      * <code>Object</code>s, e.g. {@link Object#equals(Object obj)}.  It is guaranteed to have a functionally equal
72      * <code>EntityResolver</code> and <code>ErrorHandler</code>.</p>
73      *
74      * @since 1.5
75      */
76    public void reset() {
77
78        // implementors should override this method
79        throw new UnsupportedOperationException(
80            "This DocumentBuilder, \"" + this.getClass().getName() + "\", does not support the reset functionality."
81            + "  Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\""
82            + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\""
83            );
84    }
85
86    /**
87     * Parse the content of the given <code>InputStream</code> as an XML
88     * document and return a new DOM {@link Document} object.
89     * An <code>IllegalArgumentException</code> is thrown if the
90     * <code>InputStream</code> is null.
91     *
92     * @param is InputStream containing the content to be parsed.
93     * @return <code>Document</code> result of parsing the
94     *  <code>InputStream</code>
95     * @exception IOException If any IO errors occur.
96     * @exception SAXException If any parse errors occur.
97     * @see org.xml.sax.DocumentHandler
98     */
99
100    public Document parse(InputStream is)
101        throws SAXException, IOException {
102        if (is == null) {
103            throw new IllegalArgumentException("InputStream cannot be null");
104        }
105
106        InputSource in = new InputSource(is);
107        return parse(in);
108    }
109
110    /**
111     * Parse the content of the given <code>InputStream</code> as an
112     * XML document and return a new DOM {@link Document} object.
113     * An <code>IllegalArgumentException</code> is thrown if the
114     * <code>InputStream</code> is null.
115     *
116     * @param is InputStream containing the content to be parsed.
117     * @param systemId Provide a base for resolving relative URIs.
118     * @return A new DOM Document object.
119     * @exception IOException If any IO errors occur.
120     * @exception SAXException If any parse errors occur.
121     * @see org.xml.sax.DocumentHandler
122     */
123
124    public Document parse(InputStream is, String systemId)
125        throws SAXException, IOException {
126        if (is == null) {
127            throw new IllegalArgumentException("InputStream cannot be null");
128        }
129
130        InputSource in = new InputSource(is);
131        in.setSystemId(systemId);
132        return parse(in);
133    }
134
135    /**
136     * Parse the content of the given URI as an XML document
137     * and return a new DOM {@link Document} object.
138     * An <code>IllegalArgumentException</code> is thrown if the
139     * URI is <code>null</code> null.
140     *
141     * @param uri The location of the content to be parsed.
142     * @return A new DOM Document object.
143     * @exception IOException If any IO errors occur.
144     * @exception SAXException If any parse errors occur.
145     * @see org.xml.sax.DocumentHandler
146     */
147
148    public Document parse(String uri)
149        throws SAXException, IOException {
150        if (uri == null) {
151            throw new IllegalArgumentException("URI cannot be null");
152        }
153
154        InputSource in = new InputSource(uri);
155        return parse(in);
156    }
157
158    /**
159     * Parse the content of the given file as an XML document
160     * and return a new DOM {@link Document} object.
161     * An <code>IllegalArgumentException</code> is thrown if the
162     * <code>File</code> is <code>null</code> null.
163     *
164     * @param f The file containing the XML to parse.
165     * @exception IOException If any IO errors occur.
166     * @exception SAXException If any parse errors occur.
167     * @see org.xml.sax.DocumentHandler
168     * @return A new DOM Document object.
169     */
170
171    public Document parse(File f) throws SAXException, IOException {
172        if (f == null) {
173            throw new IllegalArgumentException("File cannot be null");
174        }
175
176        String escapedURI = FilePathToURI.filepath2URI(f.getAbsolutePath());
177
178        if (DEBUG) {
179            System.out.println("Escaped URI = " + escapedURI);
180        }
181
182        InputSource in = new InputSource(escapedURI);
183        return parse(in);
184    }
185
186    /**
187     * Parse the content of the given input source as an XML document
188     * and return a new DOM {@link Document} object.
189     * An <code>IllegalArgumentException</code> is thrown if the
190     * <code>InputSource</code> is <code>null</code> null.
191     *
192     * @param is InputSource containing the content to be parsed.
193     * @exception IOException If any IO errors occur.
194     * @exception SAXException If any parse errors occur.
195     * @see org.xml.sax.DocumentHandler
196     * @return A new DOM Document object.
197     */
198
199    public abstract Document parse(InputSource is)
200        throws  SAXException, IOException;
201
202
203    /**
204     * Indicates whether or not this parser is configured to
205     * understand namespaces.
206     *
207     * @return true if this parser is configured to understand
208     *         namespaces; false otherwise.
209     */
210
211    public abstract boolean isNamespaceAware();
212
213    /**
214     * Indicates whether or not this parser is configured to
215     * validate XML documents.
216     *
217     * @return true if this parser is configured to validate
218     *         XML documents; false otherwise.
219     */
220
221    public abstract boolean isValidating();
222
223    /**
224     * Specify the {@link EntityResolver} to be used to resolve
225     * entities present in the XML document to be parsed. Setting
226     * this to <code>null</code> will result in the underlying
227     * implementation using it's own default implementation and
228     * behavior.
229     *
230     * @param er The <code>EntityResolver</code> to be used to resolve entities
231     *           present in the XML document to be parsed.
232     */
233
234    public abstract void setEntityResolver(EntityResolver er);
235
236    /**
237     * Specify the {@link ErrorHandler} to be used by the parser.
238     * Setting this to <code>null</code> will result in the underlying
239     * implementation using it's own default implementation and
240     * behavior.
241     *
242     * @param eh The <code>ErrorHandler</code> to be used by the parser.
243     */
244
245    public abstract void setErrorHandler(ErrorHandler eh);
246
247    /**
248     * Obtain a new instance of a DOM {@link Document} object
249     * to build a DOM tree with.
250     *
251     * @return A new instance of a DOM Document object.
252     */
253
254    public abstract Document newDocument();
255
256    /**
257     * Obtain an instance of a {@link DOMImplementation} object.
258     *
259     * @return A new instance of a <code>DOMImplementation</code>.
260     */
261
262    public abstract DOMImplementation getDOMImplementation();
263
264    /** <p>Get a reference to the the {@link Schema} being used by
265     * the XML processor.</p>
266     *
267     * <p>If no schema is being used, <code>null</code> is returned.</p>
268     *
269     * @return {@link Schema} being used or <code>null</code>
270     *  if none in use
271     *
272     * @throws UnsupportedOperationException
273     *      For backward compatibility, when implementations for
274     *      earlier versions of JAXP is used, this exception will be
275     *      thrown.
276     *
277     * @since 1.5
278     */
279    public Schema getSchema() {
280        throw new UnsupportedOperationException(
281            "This parser does not support specification \""
282            + this.getClass().getPackage().getSpecificationTitle()
283            + "\" version \""
284            + this.getClass().getPackage().getSpecificationVersion()
285            + "\""
286            );
287    }
288
289
290    /**
291     * <p>Get the XInclude processing mode for this parser.</p>
292     *
293     * @return
294     *      the return value of
295     *      the {@link DocumentBuilderFactory#isXIncludeAware()}
296     *      when this parser was created from factory.
297     *
298     * @throws UnsupportedOperationException
299     *      For backward compatibility, when implementations for
300     *      earlier versions of JAXP is used, this exception will be
301     *      thrown.
302     *
303     * @since 1.5
304     *
305     * @see DocumentBuilderFactory#setXIncludeAware(boolean)
306     */
307    public boolean isXIncludeAware() {
308        throw new UnsupportedOperationException(
309            "This parser does not support specification \""
310            + this.getClass().getPackage().getSpecificationTitle()
311            + "\" version \""
312            + this.getClass().getPackage().getSpecificationVersion()
313            + "\""
314            );
315    }
316}
317