Save This Page
Home » Xerces-J-src.2.9.1 » org.apache.xerces » jaxp » [javadoc | source]
    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   package org.apache.xerces.jaxp;
   19   
   20   import java.io.IOException;
   21   import java.util.Enumeration;
   22   import java.util.Hashtable;
   23   
   24   import javax.xml.parsers.DocumentBuilder;
   25   import javax.xml.validation.Schema;
   26   
   27   import org.apache.xerces.dom.DOMImplementationImpl;
   28   import org.apache.xerces.dom.DOMMessageFormatter;
   29   import org.apache.xerces.impl.Constants;
   30   import org.apache.xerces.impl.validation.ValidationManager;
   31   import org.apache.xerces.impl.xs.XMLSchemaValidator;
   32   import org.apache.xerces.jaxp.validation.XSGrammarPoolContainer;
   33   import org.apache.xerces.parsers.DOMParser;
   34   import org.apache.xerces.util.SecurityManager;
   35   import org.apache.xerces.xni.XMLDocumentHandler;
   36   import org.apache.xerces.xni.parser.XMLComponent;
   37   import org.apache.xerces.xni.parser.XMLComponentManager;
   38   import org.apache.xerces.xni.parser.XMLConfigurationException;
   39   import org.apache.xerces.xni.parser.XMLDocumentSource;
   40   import org.apache.xerces.xni.parser.XMLParserConfiguration;
   41   import org.w3c.dom.DOMImplementation;
   42   import org.w3c.dom.Document;
   43   import org.xml.sax.EntityResolver;
   44   import org.xml.sax.ErrorHandler;
   45   import org.xml.sax.InputSource;
   46   import org.xml.sax.SAXException;
   47   import org.xml.sax.SAXNotRecognizedException;
   48   import org.xml.sax.SAXNotSupportedException;
   49   
   50   /**
   51    * @author Rajiv Mordani
   52    * @author Edwin Goei
   53    * @version $Id: DocumentBuilderImpl.java 520058 2007-03-19 19:33:53Z mrglavas $
   54    */
   55   public class DocumentBuilderImpl extends DocumentBuilder
   56           implements JAXPConstants
   57   {
   58       /** Feature identifier: namespaces. */
   59       private static final String NAMESPACES_FEATURE =
   60           Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE;
   61       
   62       /** Feature identifier: include ignorable white space. */
   63       private static final String 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 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 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 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 XINCLUDE_FEATURE = 
   80           Constants.XERCES_FEATURE_PREFIX + Constants.XINCLUDE_FEATURE;
   81   
   82       /** feature identifier: XML Schema validation */
   83       private static final String XMLSCHEMA_VALIDATION_FEATURE =
   84           Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_VALIDATION_FEATURE;
   85       
   86       /** Feature identifier: validation */
   87       private static final String VALIDATION_FEATURE =
   88           Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE;
   89       
   90       /** Property identifier: security manager. */
   91       private static final String SECURITY_MANAGER =
   92           Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
   93       
   94       private DOMParser domParser = null;
   95       private final Schema grammar;
   96       
   97       private XMLComponent fSchemaValidator;
   98       private XMLComponentManager fSchemaValidatorComponentManager;
   99       private ValidationManager fSchemaValidationManager;
  100       private UnparsedEntityHandler fUnparsedEntityHandler;
  101       
  102       /** Initial ErrorHandler */
  103       private final ErrorHandler fInitErrorHandler;
  104       
  105       /** Initial EntityResolver */
  106       private final EntityResolver fInitEntityResolver;
  107       
  108       DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features)
  109           throws SAXNotRecognizedException, SAXNotSupportedException {
  110           this(dbf, dbfAttrs, features, false);
  111       }
  112   
  113       DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features, boolean secureProcessing)
  114           throws SAXNotRecognizedException, SAXNotSupportedException
  115       {
  116           domParser = new DOMParser();
  117   
  118           // If validating, provide a default ErrorHandler that prints
  119           // validation errors with a warning telling the user to set an
  120           // ErrorHandler
  121           if (dbf.isValidating()) {
  122               fInitErrorHandler = new DefaultValidationErrorHandler();
  123               setErrorHandler(fInitErrorHandler);
  124           }
  125           else {
  126               fInitErrorHandler = domParser.getErrorHandler();
  127           }
  128   
  129           domParser.setFeature(VALIDATION_FEATURE, dbf.isValidating());
  130   
  131           // "namespaceAware" == SAX Namespaces feature
  132           domParser.setFeature(NAMESPACES_FEATURE, dbf.isNamespaceAware());
  133   
  134           // Set various parameters obtained from DocumentBuilderFactory
  135           domParser.setFeature(INCLUDE_IGNORABLE_WHITESPACE, 
  136                   !dbf.isIgnoringElementContentWhitespace());
  137           domParser.setFeature(CREATE_ENTITY_REF_NODES_FEATURE,
  138                   !dbf.isExpandEntityReferences());
  139           domParser.setFeature(INCLUDE_COMMENTS_FEATURE,
  140                   !dbf.isIgnoringComments());
  141           domParser.setFeature(CREATE_CDATA_NODES_FEATURE,
  142                   !dbf.isCoalescing());
  143           
  144           // Avoid setting the XInclude processing feature if the value is false.
  145           // This will keep the configuration from throwing an exception if it
  146           // does not support XInclude.
  147           if (dbf.isXIncludeAware()) {
  148               domParser.setFeature(XINCLUDE_FEATURE, true);
  149           }
  150           
  151           // If the secure processing feature is on set a security manager.
  152           if (secureProcessing) {
  153               domParser.setProperty(SECURITY_MANAGER, new SecurityManager());
  154           }
  155           
  156           this.grammar = dbf.getSchema();
  157           if (grammar != null) {
  158               XMLParserConfiguration config = domParser.getXMLParserConfiguration();
  159               XMLComponent validatorComponent = null;
  160               /** For Xerces grammars, use built-in schema validator. **/
  161               if (grammar instanceof XSGrammarPoolContainer) {
  162                   validatorComponent = new XMLSchemaValidator();
  163                   fSchemaValidationManager = new ValidationManager();
  164                   fUnparsedEntityHandler = new UnparsedEntityHandler(fSchemaValidationManager);
  165                   config.setDTDHandler(fUnparsedEntityHandler);
  166                   fUnparsedEntityHandler.setDTDHandler(domParser);
  167                   domParser.setDTDSource(fUnparsedEntityHandler);
  168                   fSchemaValidatorComponentManager = new SchemaValidatorConfiguration(config, 
  169                           (XSGrammarPoolContainer) grammar, fSchemaValidationManager);
  170               }
  171               /** For third party grammars, use the JAXP validator component. **/
  172               else {
  173                   validatorComponent = new JAXPValidatorComponent(grammar.newValidatorHandler());
  174                   fSchemaValidatorComponentManager = config;
  175               }
  176               config.addRecognizedFeatures(validatorComponent.getRecognizedFeatures());
  177               config.addRecognizedProperties(validatorComponent.getRecognizedProperties());
  178               config.setDocumentHandler((XMLDocumentHandler) validatorComponent);
  179               ((XMLDocumentSource)validatorComponent).setDocumentHandler(domParser);
  180               domParser.setDocumentSource((XMLDocumentSource) validatorComponent);
  181               fSchemaValidator = validatorComponent;
  182           }
  183   
  184           // Set features
  185           setFeatures(features);
  186           
  187           // Set attributes
  188           setDocumentBuilderFactoryAttributes(dbfAttrs);
  189           
  190           // Initial EntityResolver
  191           fInitEntityResolver = domParser.getEntityResolver();
  192       }
  193       
  194       private void setFeatures(Hashtable features)
  195           throws SAXNotSupportedException, SAXNotRecognizedException {
  196           if (features != null) {
  197               for (Enumeration e = features.keys(); e.hasMoreElements();) {
  198                   String feature = (String)e.nextElement();
  199                   boolean value = ((Boolean)features.get(feature)).booleanValue();
  200                   domParser.setFeature(feature, value);
  201               }
  202           }
  203       }
  204   
  205       /**
  206        * Set any DocumentBuilderFactory attributes of our underlying DOMParser
  207        *
  208        * Note: code does not handle possible conflicts between DOMParser
  209        * attribute names and JAXP specific attribute names,
  210        * eg. DocumentBuilderFactory.setValidating()
  211        */
  212       private void setDocumentBuilderFactoryAttributes(Hashtable dbfAttrs)
  213           throws SAXNotSupportedException, SAXNotRecognizedException
  214       {
  215           if (dbfAttrs == null) {
  216               // Nothing to do
  217               return;
  218           }
  219   
  220           for (Enumeration e = dbfAttrs.keys(); e.hasMoreElements();) {
  221               String name = (String)e.nextElement();
  222               Object val = dbfAttrs.get(name);
  223               if (val instanceof Boolean) {
  224                   // Assume feature
  225                   domParser.setFeature(name, ((Boolean)val).booleanValue());
  226               } else {
  227                   // Assume property
  228                   if (JAXP_SCHEMA_LANGUAGE.equals(name)) {
  229                       // JAXP 1.2 support
  230                       //None of the properties will take effect till the setValidating(true) has been called                                        
  231                       if ( W3C_XML_SCHEMA.equals(val) ) {
  232                           if( isValidating() ) {
  233                               domParser.setFeature(XMLSCHEMA_VALIDATION_FEATURE, true);
  234                               // this should allow us not to emit DTD errors, as expected by the 
  235                               // spec when schema validation is enabled
  236                               domParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
  237                           }
  238                       }
  239           		} else if(JAXP_SCHEMA_SOURCE.equals(name)){
  240                  		if( isValidating() ) {
  241   						String value=(String)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE);
  242   						if(value !=null && W3C_XML_SCHEMA.equals(value)){
  243               				domParser.setProperty(name, val);
  244   						}else{
  245                               throw new IllegalArgumentException(
  246                                   DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, 
  247                                   "jaxp-order-not-supported",
  248                                   new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE}));
  249   						}
  250   					}
  251               	} else {
  252                       // Let Xerces code handle the property
  253                       domParser.setProperty(name, val);
  254   				}
  255   			}
  256   		}
  257   	}
  258   
  259       /**
  260        * Non-preferred: use the getDOMImplementation() method instead of this
  261        * one to get a DOM Level 2 DOMImplementation object and then use DOM
  262        * Level 2 methods to create a DOM Document object.
  263        */
  264       public Document newDocument() {
  265           return new org.apache.xerces.dom.DocumentImpl();
  266       }
  267   
  268       public DOMImplementation getDOMImplementation() {
  269           return DOMImplementationImpl.getDOMImplementation();
  270       }
  271   
  272       public Document parse(InputSource is) throws SAXException, IOException {
  273           if (is == null) {
  274               throw new IllegalArgumentException(
  275                   DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, 
  276                   "jaxp-null-input-source", null));
  277           }
  278           if (fSchemaValidator != null) {
  279               if (fSchemaValidationManager != null) {
  280                   fSchemaValidationManager.reset();
  281                   fUnparsedEntityHandler.reset();
  282               }
  283               resetSchemaValidator();
  284           }
  285           domParser.parse(is);
  286           Document doc = domParser.getDocument();
  287           domParser.dropDocumentReferences();
  288           return doc;
  289       }
  290   
  291       public boolean isNamespaceAware() {
  292           try {
  293               return domParser.getFeature(NAMESPACES_FEATURE);
  294           } 
  295           catch (SAXException x) {
  296               throw new IllegalStateException(x.getMessage());
  297           }
  298       }
  299   
  300       public boolean isValidating() {
  301           try {
  302               return domParser.getFeature(VALIDATION_FEATURE);
  303           } 
  304           catch (SAXException x) {
  305               throw new IllegalStateException(x.getMessage());
  306           }
  307       }
  308       
  309       /**
  310        * Gets the XInclude processing mode for this parser
  311        * @return the state of XInclude processing mode
  312        */
  313       public boolean isXIncludeAware() {
  314           try {
  315               return domParser.getFeature(XINCLUDE_FEATURE);
  316           }
  317           catch (SAXException exc) {
  318               return false;
  319           }
  320       }
  321   
  322       public void setEntityResolver(EntityResolver er) {
  323           domParser.setEntityResolver(er);
  324       }
  325   
  326       public void setErrorHandler(ErrorHandler eh) {
  327           domParser.setErrorHandler(eh);
  328       }
  329       
  330       public Schema getSchema() {
  331           return grammar;
  332       }
  333       
  334       public void reset() {
  335           /** Restore the initial error handler. **/
  336           if (domParser.getErrorHandler() != fInitErrorHandler) {
  337               domParser.setErrorHandler(fInitErrorHandler);
  338           }
  339           /** Restore the initial entity resolver. **/
  340           if (domParser.getEntityResolver() != fInitEntityResolver) {
  341               domParser.setEntityResolver(fInitEntityResolver);
  342           }
  343       }
  344   
  345       // package private
  346       DOMParser getDOMParser() {
  347           return domParser;
  348       }
  349       
  350       private void resetSchemaValidator() throws SAXException {
  351           try {
  352               fSchemaValidator.reset(fSchemaValidatorComponentManager);
  353           }
  354           // This should never be thrown from the schema validator.
  355           catch (XMLConfigurationException e) {
  356               throw new SAXException(e);
  357           }
  358       }
  359   }

Save This Page
Home » Xerces-J-src.2.9.1 » org.apache.xerces » jaxp » [javadoc | source]