KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xerces > jaxp > DocumentBuilderImpl


1 /*
2  * Copyright 2000-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.xerces.jaxp;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.Hashtable JavaDoc;
22
23 import javax.xml.parsers.DocumentBuilder JavaDoc;
24 import javax.xml.validation.Schema JavaDoc;
25
26 import org.apache.xerces.dom.DOMImplementationImpl;
27 import org.apache.xerces.dom.DOMMessageFormatter;
28 import org.apache.xerces.impl.Constants;
29 import org.apache.xerces.impl.validation.ValidationManager;
30 import org.apache.xerces.impl.xs.XMLSchemaValidator;
31 import org.apache.xerces.jaxp.validation.XSGrammarPoolContainer;
32 import org.apache.xerces.parsers.DOMParser;
33 import org.apache.xerces.util.SecurityManager;
34 import org.apache.xerces.xni.XMLDocumentHandler;
35 import org.apache.xerces.xni.parser.XMLComponent;
36 import org.apache.xerces.xni.parser.XMLComponentManager;
37 import org.apache.xerces.xni.parser.XMLConfigurationException;
38 import org.apache.xerces.xni.parser.XMLDTDFilter;
39 import org.apache.xerces.xni.parser.XMLDocumentSource;
40 import org.apache.xerces.xni.parser.XMLParserConfiguration;
41 import org.w3c.dom.DOMImplementation JavaDoc;
42 import org.w3c.dom.Document JavaDoc;
43 import org.xml.sax.EntityResolver JavaDoc;
44 import org.xml.sax.ErrorHandler JavaDoc;
45 import org.xml.sax.InputSource JavaDoc;
46 import org.xml.sax.SAXException JavaDoc;
47 import org.xml.sax.SAXNotRecognizedException JavaDoc;
48 import org.xml.sax.SAXNotSupportedException JavaDoc;
49
50 /**
51  * @author Rajiv Mordani
52  * @author Edwin Goei
53  * @version $Id: DocumentBuilderImpl.java,v 1.33 2005/06/21 17:19:08 mrglavas Exp $
54  */

55 public class DocumentBuilderImpl extends DocumentBuilder JavaDoc
56         implements JAXPConstants
57 {
58     /** Feature identifier: namespaces. */
59     private static final String JavaDoc NAMESPACES_FEATURE =
60         Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
61     
62     /** Feature identifier: include ignorable white space. */
63     private static final String JavaDoc INCLUDE_IGNORABLE_WHITESPACE =
64         Constants.XERCES_FEATURE_PREFIX + Constants.INCLUDE_IGNORABLE_WHITESPACE;
65     
66     /** Feature identifier: create entiry ref nodes feature. */
67     private static final String JavaDoc CREATE_ENTITY_REF_NODES_FEATURE =
68         Constants.XERCES_FEATURE_PREFIX + Constants.CREATE_ENTITY_REF_NODES_FEATURE;
69     
70     /** Feature identifier: include comments feature. */
71     private static final String JavaDoc INCLUDE_COMMENTS_FEATURE =
72         Constants.XERCES_FEATURE_PREFIX + Constants.INCLUDE_COMMENTS_FEATURE;
73     
74     /** Feature identifier: create cdata nodes feature. */
75     private static final String JavaDoc CREATE_CDATA_NODES_FEATURE =
76         Constants.XERCES_FEATURE_PREFIX + Constants.CREATE_CDATA_NODES_FEATURE;
77     
78     /** Feature identifier: XInclude processing */
79     private static final String JavaDoc XINCLUDE_FEATURE =
80         Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
81
82     /** feature identifier: XML Schema validation */
83     private static final String JavaDoc XMLSCHEMA_VALIDATION_FEATURE =
84         Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
85     
86     /** Feature identifier: validation */
87     private static final String JavaDoc VALIDATION_FEATURE =
88         Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
89     
90     /** Property identifier: security manager. */
91     private static final String JavaDoc SECURITY_MANAGER =
92         Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
93     
94     private DOMParser domParser = null;
95     private final Schema JavaDoc grammar;
96     
97     private XMLComponent fSchemaValidator;
98     private XMLComponentManager fSchemaValidatorComponentManager;
99     private ValidationManager fSchemaValidationManager;
100     
101     /** Initial ErrorHandler */
102     private final ErrorHandler JavaDoc fInitErrorHandler;
103     
104     /** Initial EntityResolver */
105     private final EntityResolver JavaDoc fInitEntityResolver;
106     
107     DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable JavaDoc dbfAttrs, Hashtable JavaDoc features)
108         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc {
109         this(dbf, dbfAttrs, features, false);
110     }
111
112     DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable JavaDoc dbfAttrs, Hashtable JavaDoc features, boolean secureProcessing)
113         throws SAXNotRecognizedException JavaDoc, SAXNotSupportedException JavaDoc
114     {
115         domParser = new DOMParser();
116
117         // If validating, provide a default ErrorHandler that prints
118
// validation errors with a warning telling the user to set an
119
// ErrorHandler
120
if (dbf.isValidating()) {
121             fInitErrorHandler = new DefaultValidationErrorHandler();
122             setErrorHandler(fInitErrorHandler);
123         }
124         else {
125             fInitErrorHandler = domParser.getErrorHandler();
126         }
127
128         domParser.setFeature(VALIDATION_FEATURE, dbf.isValidating());
129
130         // "namespaceAware" == SAX Namespaces feature
131
domParser.setFeature(NAMESPACES_FEATURE, dbf.isNamespaceAware());
132
133         // Set various parameters obtained from DocumentBuilderFactory
134
domParser.setFeature(INCLUDE_IGNORABLE_WHITESPACE,
135                 !dbf.isIgnoringElementContentWhitespace());
136         domParser.setFeature(CREATE_ENTITY_REF_NODES_FEATURE,
137                 !dbf.isExpandEntityReferences());
138         domParser.setFeature(INCLUDE_COMMENTS_FEATURE,
139                 !dbf.isIgnoringComments());
140         domParser.setFeature(CREATE_CDATA_NODES_FEATURE,
141                 !dbf.isCoalescing());
142         
143         // Avoid setting the XInclude processing feature if the value is false.
144
// This will keep the configuration from throwing an exception if it
145
// does not support XInclude.
146
if (dbf.isXIncludeAware()) {
147             domParser.setFeature(XINCLUDE_FEATURE, true);
148         }
149         
150         // If the secure processing feature is on set a security manager.
151
if (secureProcessing) {
152             domParser.setProperty(SECURITY_MANAGER, new SecurityManager JavaDoc());
153         }
154         
155         this.grammar = dbf.getSchema();
156         if (grammar != null) {
157             XMLParserConfiguration config = domParser.getXMLParserConfiguration();
158             XMLComponent validatorComponent = null;
159             /** For Xerces grammars, use built-in schema validator. **/
160             if (grammar instanceof XSGrammarPoolContainer) {
161                 validatorComponent = new XMLSchemaValidator();
162                 fSchemaValidationManager = new ValidationManager();
163                 XMLDTDFilter entityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
164                 config.setDTDHandler(entityHandler);
165                 entityHandler.setDTDHandler(domParser);
166                 domParser.setDTDSource(entityHandler);
167                 fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config,
168                         (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
169             }
170             /** For third party grammars, use the JAXP validator component. **/
171             else {
172                 validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
173                 fSchemaValidatorComponentManager = config;
174             }
175             config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
176             config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
177             config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
178             ((XMLDocumentSource)validatorComponent).setDocumentHandler(domParser);
179             domParser.setDocumentSource((XMLDocumentSource) validatorComponent);
180             fSchemaValidator = validatorComponent;
181         }
182
183         // Set features
184
setFeatures(features);
185         
186         // Set attributes
187
setDocumentBuilderFactoryAttributes(dbfAttrs);
188         
189         // Initial EntityResolver
190
fInitEntityResolver = domParser.getEntityResolver();
191     }
192     
193     private void setFeatures(Hashtable JavaDoc features)
194         throws SAXNotSupportedException JavaDoc, SAXNotRecognizedException JavaDoc {
195         if (features != null) {
196             for (Enumeration JavaDoc e = features.keys(); e.hasMoreElements();) {
197                 String JavaDoc feature = (String JavaDoc)e.nextElement();
198                 boolean value = ((Boolean JavaDoc)features.get(feature)).booleanValue();
199                 domParser.setFeature(feature, value);
200             }
201         }
202     }
203
204     /**
205      * Set any DocumentBuilderFactory attributes of our underlying DOMParser
206      *
207      * Note: code does not handle possible conflicts between DOMParser
208      * attribute names and JAXP specific attribute names,
209      * eg. DocumentBuilderFactory.setValidating()
210      */

211     private void setDocumentBuilderFactoryAttributes(Hashtable JavaDoc dbfAttrs)
212         throws SAXNotSupportedException JavaDoc, SAXNotRecognizedException JavaDoc
213     {
214         if (dbfAttrs == null) {
215             // Nothing to do
216
return;
217         }
218
219         for (Enumeration JavaDoc e = dbfAttrs.keys(); e.hasMoreElements();) {
220             String JavaDoc name = (String JavaDoc)e.nextElement();
221             Object JavaDoc val = dbfAttrs.get(name);
222             if (val instanceof Boolean JavaDoc) {
223                 // Assume feature
224
domParser.setFeature(name, ((Boolean JavaDoc)val).booleanValue());
225             } else {
226                 // Assume property
227
if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
228                     // JAXP 1.2 support
229
//None of the properties will take effect till the setValidating(true) has been called
230
if ( W3C_XML_SCHEMA.equals(val) ) {
231                         if( isValidating() ) {
232                             domParser.setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
233                             // this should allow us not to emit DTD errors, as expected by the
234
// spec when schema validation is enabled
235
domParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
236                         }
237                     }
238                 } else if(JAXP_SCHEMA_SOURCE.equals(name)){
239                     if( isValidating() ) {
240                         String JavaDoc value=(String JavaDoc)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE);
241                         if(value !=null && W3C_XML_SCHEMA.equals(value)){
242                             domParser.setProperty(name, val);
243                         }else{
244                             throw new IllegalArgumentException JavaDoc(
245                                 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN,
246                                 "jaxp-order-not-supported",
247                                 new Object JavaDoc[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
248                         }
249                     }
250                 } else {
251                     // Let Xerces code handle the property
252
domParser.setProperty(name, val);
253                 }
254             }
255         }
256     }
257
258     /**
259      * Non-preferred: use the getDOMImplementation() method instead of this
260      * one to get a DOM Level 2 DOMImplementation object and then use DOM
261      * Level 2 methods to create a DOM Document object.
262      */

263     public Document JavaDoc newDocument() {
264         return new org.apache.xerces.dom.DocumentImpl();
265     }
266
267     public DOMImplementation JavaDoc getDOMImplementation() {
268         return DOMImplementationImpl.getDOMImplementation();
269     }
270
271     public Document JavaDoc parse(InputSource JavaDoc is) throws SAXException JavaDoc, IOException JavaDoc {
272         if (is == null) {
273             throw new IllegalArgumentException JavaDoc(
274                 DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN,
275                 "jaxp-null-input-source", null));
276         }
277         if (fSchemaValidator != null) {
278             if (fSchemaValidationManager != null) {
279                 fSchemaValidationManager.reset();
280             }
281             resetSchemaValidator();
282         }
283         domParser.parse(is);
284         return domParser.getDocument();
285     }
286
287     public boolean isNamespaceAware() {
288         try {
289             return domParser.getFeature(NAMESPACES_FEATURE);
290         }
291         catch (SAXException JavaDoc x) {
292             throw new IllegalStateException JavaDoc(x.getMessage());
293         }
294     }
295
296     public boolean isValidating() {
297         try {
298             return domParser.getFeature(VALIDATION_FEATURE);
299         }
300         catch (SAXException JavaDoc x) {
301             throw new IllegalStateException JavaDoc(x.getMessage());
302         }
303     }
304     
305     /**
306      * Gets the XInclude processing mode for this parser
307      * @return the state of XInclude processing mode
308      */

309     public boolean isXIncludeAware() {
310         try {
311             return domParser.getFeature(XINCLUDE_FEATURE);
312         }
313         catch (SAXException JavaDoc exc) {
314             return false;
315         }
316     }
317
318     public void setEntityResolver(EntityResolver JavaDoc er) {
319         domParser.setEntityResolver(er);
320     }
321
322     public void setErrorHandler(ErrorHandler JavaDoc eh) {
323         domParser.setErrorHandler(eh);
324     }
325     
326     public Schema JavaDoc getSchema() {
327         return grammar;
328     }
329     
330     public void reset() {
331         /** Restore the initial error handler. **/
332         if (domParser.getErrorHandler() != fInitErrorHandler) {
333             domParser.setErrorHandler(fInitErrorHandler);
334         }
335         /** Restore the initial entity resolver. **/
336         if (domParser.getEntityResolver() != fInitEntityResolver) {
337             domParser.setEntityResolver(fInitEntityResolver);
338         }
339     }
340
341     // package private
342
DOMParser getDOMParser() {
343         return domParser;
344     }
345     
346     private void resetSchemaValidator() throws SAXException JavaDoc {
347         try {
348             fSchemaValidator.reset(fSchemaValidatorComponentManager);
349         }
350         // This should never be thrown from the schema validator.
351
catch (XMLConfigurationException e) {
352             throw new SAXException JavaDoc(e);
353         }
354     }
355 }
356
Popular Tags