Save This Page
Home » Xerces-J-src.2.9.1 » org.apache.xerces » parsers » [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.parsers;
   19   
   20   import java.io.CharConversionException;
   21   import java.io.IOException;
   22   
   23   import org.apache.xerces.dom.DOMMessageFormatter;
   24   import org.apache.xerces.impl.Constants;
   25   import org.apache.xerces.util.EntityResolverWrapper;
   26   import org.apache.xerces.util.EntityResolver2Wrapper;
   27   import org.apache.xerces.util.ErrorHandlerWrapper;
   28   import org.apache.xerces.util.SAXMessageFormatter;
   29   import org.apache.xerces.util.SymbolTable;
   30   import org.apache.xerces.xni.XNIException;
   31   import org.apache.xerces.xni.grammars.XMLGrammarPool;
   32   import org.apache.xerces.xni.parser.XMLConfigurationException;
   33   import org.apache.xerces.xni.parser.XMLEntityResolver;
   34   import org.apache.xerces.xni.parser.XMLErrorHandler;
   35   import org.apache.xerces.xni.parser.XMLInputSource;
   36   import org.apache.xerces.xni.parser.XMLParseException;
   37   import org.apache.xerces.xni.parser.XMLParserConfiguration;
   38   import org.w3c.dom.Node;
   39   import org.xml.sax.EntityResolver;
   40   import org.xml.sax.ErrorHandler;
   41   import org.xml.sax.InputSource;
   42   import org.xml.sax.SAXException;
   43   import org.xml.sax.SAXNotRecognizedException;
   44   import org.xml.sax.SAXNotSupportedException;
   45   import org.xml.sax.SAXParseException;
   46   import org.xml.sax.ext.EntityResolver2;
   47   import org.xml.sax.helpers.LocatorImpl;
   48   
   49   /**
   50    * This is the main Xerces DOM parser class. It uses the abstract DOM
   51    * parser with a document scanner, a dtd scanner, and a validator, as
   52    * well as a grammar pool.
   53    *
   54    * @author Arnaud  Le Hors, IBM
   55    * @author Andy Clark, IBM
   56    *
   57    * @version $Id: DOMParser.java 542046 2007-05-27 22:48:02Z mrglavas $
   58    */
   59   public class DOMParser
   60       extends AbstractDOMParser {
   61   
   62       //
   63       // Constants
   64       //
   65       
   66       // features
   67       
   68       /** Feature identifier: EntityResolver2. */
   69       protected static final String USE_ENTITY_RESOLVER2 =
   70           Constants.SAX_FEATURE_PREFIX + Constants.USE_ENTITY_RESOLVER2_FEATURE;
   71   
   72       // properties
   73   
   74       /** Property identifier: symbol table. */
   75       protected static final String SYMBOL_TABLE =
   76           Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
   77   
   78       /** Property identifier: XML grammar pool. */
   79       protected static final String XMLGRAMMAR_POOL =
   80           Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY;
   81   
   82       /** Recognized properties. */
   83       private static final String[] RECOGNIZED_PROPERTIES = {
   84           SYMBOL_TABLE,
   85           XMLGRAMMAR_POOL,
   86       };
   87       
   88       //
   89       // Data
   90       //
   91       
   92       // features
   93       
   94       /** Use EntityResolver2. */
   95       protected boolean fUseEntityResolver2 = true;
   96   
   97       //
   98       // Constructors
   99       //
  100   
  101       /**
  102        * Constructs a DOM parser using the specified parser configuration.
  103        */
  104       public DOMParser(XMLParserConfiguration config) {
  105           super(config);
  106       } // <init>(XMLParserConfiguration)
  107   
  108       /**
  109        * Constructs a DOM parser using the dtd/xml schema parser configuration.
  110        */
  111       public DOMParser() {
  112           this(null, null);
  113       } // <init>()
  114   
  115       /**
  116        * Constructs a DOM parser using the specified symbol table.
  117        */
  118       public DOMParser(SymbolTable symbolTable) {
  119           this(symbolTable, null);
  120       } // <init>(SymbolTable)
  121   
  122   
  123       /**
  124        * Constructs a DOM parser using the specified symbol table and
  125        * grammar pool.
  126        */
  127       public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
  128           super((XMLParserConfiguration)ObjectFactory.createObject(
  129               "org.apache.xerces.xni.parser.XMLParserConfiguration",
  130               "org.apache.xerces.parsers.XIncludeAwareParserConfiguration"
  131               ));
  132   
  133           // set properties
  134           fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
  135           if (symbolTable != null) {
  136               fConfiguration.setProperty(SYMBOL_TABLE, symbolTable);
  137           }
  138           if (grammarPool != null) {
  139               fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool);
  140           }
  141   
  142       } // <init>(SymbolTable,XMLGrammarPool)
  143   
  144       //
  145       // XMLReader methods
  146       //
  147   
  148       /**
  149        * Parses the input source specified by the given system identifier.
  150        * <p>
  151        * This method is equivalent to the following:
  152        * <pre>
  153        *     parse(new InputSource(systemId));
  154        * </pre>
  155        *
  156        * @param systemId The system identifier (URI).
  157        *
  158        * @exception org.xml.sax.SAXException Throws exception on SAX error.
  159        * @exception java.io.IOException Throws exception on i/o error.
  160        */
  161       public void parse(String systemId) throws SAXException, IOException {
  162   
  163           // parse document
  164           XMLInputSource source = new XMLInputSource(null, systemId, null);
  165           try {
  166               parse(source);
  167           }
  168   
  169           // wrap XNI exceptions as SAX exceptions
  170           catch (XMLParseException e) {
  171               Exception ex = e.getException();
  172               if (ex == null || ex instanceof CharConversionException) {
  173                   // must be a parser exception; mine it for locator info and throw
  174                   // a SAXParseException
  175                   LocatorImpl locatorImpl = new LocatorImpl();
  176                   locatorImpl.setPublicId(e.getPublicId());
  177                   locatorImpl.setSystemId(e.getExpandedSystemId());
  178                   locatorImpl.setLineNumber(e.getLineNumber());
  179                   locatorImpl.setColumnNumber(e.getColumnNumber());
  180                   throw (ex == null) ? 
  181                           new SAXParseException(e.getMessage(), locatorImpl) : 
  182                           new SAXParseException(e.getMessage(), locatorImpl, ex);
  183               }
  184               if (ex instanceof SAXException) {
  185                   // why did we create an XMLParseException?
  186                   throw (SAXException)ex;
  187               }
  188               if (ex instanceof IOException) {
  189                   throw (IOException)ex;
  190               }
  191               throw new SAXException(ex);
  192           }
  193           catch (XNIException e) {
  194               e.printStackTrace();
  195               Exception ex = e.getException();
  196               if (ex == null) {
  197                   throw new SAXException(e.getMessage());
  198               }
  199               if (ex instanceof SAXException) {
  200                   throw (SAXException)ex;
  201               }
  202               if (ex instanceof IOException) {
  203                   throw (IOException)ex;
  204               }
  205               throw new SAXException(ex);
  206           }
  207   
  208       } // parse(String)
  209   
  210       /**
  211        * parse
  212        *
  213        * @param inputSource
  214        *
  215        * @exception org.xml.sax.SAXException
  216        * @exception java.io.IOException
  217        */
  218       public void parse(InputSource inputSource)
  219           throws SAXException, IOException {
  220   
  221           // parse document
  222           try {
  223               XMLInputSource xmlInputSource =
  224                   new XMLInputSource(inputSource.getPublicId(),
  225                                      inputSource.getSystemId(),
  226                                      null);
  227               xmlInputSource.setByteStream(inputSource.getByteStream());
  228               xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
  229               xmlInputSource.setEncoding(inputSource.getEncoding());
  230               parse(xmlInputSource);
  231           }
  232   
  233           // wrap XNI exceptions as SAX exceptions
  234           catch (XMLParseException e) {
  235               Exception ex = e.getException();
  236               if (ex == null || ex instanceof CharConversionException) {
  237                   // must be a parser exception; mine it for locator info and throw
  238                   // a SAXParseException
  239                   LocatorImpl locatorImpl = new LocatorImpl();
  240                   locatorImpl.setPublicId(e.getPublicId());
  241                   locatorImpl.setSystemId(e.getExpandedSystemId());
  242                   locatorImpl.setLineNumber(e.getLineNumber());
  243                   locatorImpl.setColumnNumber(e.getColumnNumber());
  244                   throw (ex == null) ? 
  245                           new SAXParseException(e.getMessage(), locatorImpl) : 
  246                           new SAXParseException(e.getMessage(), locatorImpl, ex);
  247               }
  248               if (ex instanceof SAXException) {
  249                   // why did we create an XMLParseException?
  250                   throw (SAXException)ex;
  251               }
  252               if (ex instanceof IOException) {
  253                   throw (IOException)ex;
  254               }
  255               throw new SAXException(ex);
  256           }
  257           catch (XNIException e) {
  258               Exception ex = e.getException();
  259               if (ex == null) {
  260                   throw new SAXException(e.getMessage());
  261               }
  262               if (ex instanceof SAXException) {
  263                   throw (SAXException)ex;
  264               }
  265               if (ex instanceof IOException) {
  266                   throw (IOException)ex;
  267               }
  268               throw new SAXException(ex);
  269           }
  270   
  271       } // parse(InputSource)
  272   
  273       /**
  274        * Sets the resolver used to resolve external entities. The EntityResolver
  275        * interface supports resolution of public and system identifiers.
  276        *
  277        * @param resolver The new entity resolver. Passing a null value will
  278        *                 uninstall the currently installed resolver.
  279        */
  280       public void setEntityResolver(EntityResolver resolver) {
  281   
  282           try {
  283               XMLEntityResolver xer = (XMLEntityResolver) fConfiguration.getProperty(ENTITY_RESOLVER);
  284               if (fUseEntityResolver2 && resolver instanceof EntityResolver2) {
  285                   if (xer instanceof EntityResolver2Wrapper) {
  286                       EntityResolver2Wrapper er2w = (EntityResolver2Wrapper) xer;
  287                       er2w.setEntityResolver((EntityResolver2) resolver);
  288                   }
  289                   else {
  290                       fConfiguration.setProperty(ENTITY_RESOLVER,
  291                               new EntityResolver2Wrapper((EntityResolver2) resolver));
  292                   }
  293               }
  294               else {
  295                   if (xer instanceof EntityResolverWrapper) {
  296                       EntityResolverWrapper erw = (EntityResolverWrapper) xer;
  297                       erw.setEntityResolver(resolver);
  298                   }
  299                   else {
  300                       fConfiguration.setProperty(ENTITY_RESOLVER,
  301                               new EntityResolverWrapper(resolver));
  302                   }
  303               }
  304           }
  305           catch (XMLConfigurationException e) {
  306               // do nothing
  307           }
  308   
  309       } // setEntityResolver(EntityResolver)
  310   
  311       /**
  312        * Return the current entity resolver.
  313        *
  314        * @return The current entity resolver, or null if none
  315        *         has been registered.
  316        * @see #setEntityResolver
  317        */
  318       public EntityResolver getEntityResolver() {
  319   
  320           EntityResolver entityResolver = null;
  321           try {
  322               XMLEntityResolver xmlEntityResolver =
  323                   (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
  324               if (xmlEntityResolver != null) {
  325                   if (xmlEntityResolver instanceof EntityResolverWrapper) {
  326                       entityResolver =
  327                           ((EntityResolverWrapper) xmlEntityResolver).getEntityResolver();
  328                   }
  329                   else if (xmlEntityResolver instanceof EntityResolver2Wrapper) {
  330                       entityResolver = 
  331                           ((EntityResolver2Wrapper) xmlEntityResolver).getEntityResolver();
  332                   }
  333               }
  334           }
  335           catch (XMLConfigurationException e) {
  336               // do nothing
  337           }
  338           return entityResolver;
  339   
  340       } // getEntityResolver():EntityResolver
  341   
  342       /**
  343        * Allow an application to register an error event handler.
  344        *
  345        * <p>If the application does not register an error handler, all
  346        * error events reported by the SAX parser will be silently
  347        * ignored; however, normal processing may not continue.  It is
  348        * highly recommended that all SAX applications implement an
  349        * error handler to avoid unexpected bugs.</p>
  350        *
  351        * <p>Applications may register a new or different handler in the
  352        * middle of a parse, and the SAX parser must begin using the new
  353        * handler immediately.</p>
  354        *
  355        * @param errorHandler The error handler.
  356        * @exception java.lang.NullPointerException If the handler
  357        *            argument is null.
  358        * @see #getErrorHandler
  359        */
  360       public void setErrorHandler(ErrorHandler errorHandler) {
  361   
  362           try {
  363               XMLErrorHandler xeh = (XMLErrorHandler) fConfiguration.getProperty(ERROR_HANDLER);
  364               if (xeh instanceof ErrorHandlerWrapper) {
  365                   ErrorHandlerWrapper ehw = (ErrorHandlerWrapper) xeh;
  366                   ehw.setErrorHandler(errorHandler);
  367               }
  368               else {
  369                   fConfiguration.setProperty(ERROR_HANDLER,
  370                           new ErrorHandlerWrapper(errorHandler));
  371               }
  372           }
  373           catch (XMLConfigurationException e) {
  374               // do nothing
  375           }
  376   
  377       } // setErrorHandler(ErrorHandler)
  378   
  379       /**
  380        * Return the current error handler.
  381        *
  382        * @return The current error handler, or null if none
  383        *         has been registered.
  384        * @see #setErrorHandler
  385        */
  386       public ErrorHandler getErrorHandler() {
  387   
  388           ErrorHandler errorHandler = null;
  389           try {
  390               XMLErrorHandler xmlErrorHandler =
  391                   (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
  392               if (xmlErrorHandler != null &&
  393                   xmlErrorHandler instanceof ErrorHandlerWrapper) {
  394                   errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
  395               }
  396           }
  397           catch (XMLConfigurationException e) {
  398               // do nothing
  399           }
  400           return errorHandler;
  401   
  402       } // getErrorHandler():ErrorHandler
  403   
  404       /**
  405        * Set the state of any feature in a SAX2 parser.  The parser
  406        * might not recognize the feature, and if it does recognize
  407        * it, it might not be able to fulfill the request.
  408        *
  409        * @param featureId The unique identifier (URI) of the feature.
  410        * @param state The requested state of the feature (true or false).
  411        *
  412        * @exception SAXNotRecognizedException If the
  413        *            requested feature is not known.
  414        * @exception SAXNotSupportedException If the
  415        *            requested feature is known, but the requested
  416        *            state is not supported.
  417        */
  418       public void setFeature(String featureId, boolean state)
  419           throws SAXNotRecognizedException, SAXNotSupportedException {
  420   
  421           try {
  422               
  423               // http://xml.org/sax/features/use-entity-resolver2
  424               //   controls whether the methods of an object implementing
  425               //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
  426               //
  427               if (featureId.equals(USE_ENTITY_RESOLVER2)) {
  428                   if (state != fUseEntityResolver2) {
  429                       fUseEntityResolver2 = state;
  430                       // Refresh EntityResolver wrapper.
  431                       setEntityResolver(getEntityResolver());
  432                   }
  433                   return;
  434               }
  435               
  436               //
  437               // Default handling
  438               //
  439               
  440               fConfiguration.setFeature(featureId, state);
  441           }
  442           catch (XMLConfigurationException e) {
  443               String identifier = e.getIdentifier();
  444               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  445                   throw new SAXNotRecognizedException(
  446                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  447                       "feature-not-recognized", new Object [] {identifier}));
  448               }
  449               else {
  450                   throw new SAXNotSupportedException(
  451                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  452                       "feature-not-supported", new Object [] {identifier}));
  453               }
  454           }
  455   
  456       } // setFeature(String,boolean)
  457   
  458       /**
  459        * Query the state of a feature.
  460        *
  461        * Query the current state of any feature in a SAX2 parser.  The
  462        * parser might not recognize the feature.
  463        *
  464        * @param featureId The unique identifier (URI) of the feature
  465        *                  being set.
  466        * @return The current state of the feature.
  467        * @exception org.xml.sax.SAXNotRecognizedException If the
  468        *            requested feature is not known.
  469        * @exception SAXNotSupportedException If the
  470        *            requested feature is known but not supported.
  471        */
  472       public boolean getFeature(String featureId)
  473           throws SAXNotRecognizedException, SAXNotSupportedException {
  474   
  475           try {
  476   
  477               // http://xml.org/sax/features/use-entity-resolver2
  478               //   controls whether the methods of an object implementing
  479               //   org.xml.sax.ext.EntityResolver2 will be used by the parser.
  480               //
  481               if (featureId.equals(USE_ENTITY_RESOLVER2)) {
  482                   return fUseEntityResolver2;
  483               }
  484               
  485               //
  486               // Default handling
  487               //
  488               
  489               return fConfiguration.getFeature(featureId);
  490           }
  491           catch (XMLConfigurationException e) {
  492               String identifier = e.getIdentifier();
  493               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  494                   throw new SAXNotRecognizedException(
  495                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  496                       "feature-not-recognized", new Object [] {identifier}));
  497               }
  498               else {
  499                   throw new SAXNotSupportedException(
  500                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  501                       "feature-not-supported", new Object [] {identifier}));
  502               }
  503           }
  504   
  505       } // getFeature(String):boolean
  506   
  507       /**
  508        * Set the value of any property in a SAX2 parser.  The parser
  509        * might not recognize the property, and if it does recognize
  510        * it, it might not support the requested value.
  511        *
  512        * @param propertyId The unique identifier (URI) of the property
  513        *                   being set.
  514        * @param value The value to which the property is being set.
  515        *
  516        * @exception SAXNotRecognizedException If the
  517        *            requested property is not known.
  518        * @exception SAXNotSupportedException If the
  519        *            requested property is known, but the requested
  520        *            value is not supported.
  521        */
  522       public void setProperty(String propertyId, Object value)
  523           throws SAXNotRecognizedException, SAXNotSupportedException {
  524   
  525           try {
  526               fConfiguration.setProperty(propertyId, value);
  527           }
  528           catch (XMLConfigurationException e) {
  529               String identifier = e.getIdentifier();
  530               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  531                   throw new SAXNotRecognizedException(
  532                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  533                       "property-not-recognized", new Object [] {identifier}));
  534               }
  535               else {
  536                   throw new SAXNotSupportedException(
  537                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  538                       "property-not-supported", new Object [] {identifier}));
  539               }
  540           }
  541   
  542       } // setProperty(String,Object)
  543   
  544       /**
  545        * Query the value of a property.
  546        *
  547        * Return the current value of a property in a SAX2 parser.
  548        * The parser might not recognize the property.
  549        *
  550        * @param propertyId The unique identifier (URI) of the property
  551        *                   being set.
  552        * @return The current value of the property.
  553        * @exception org.xml.sax.SAXNotRecognizedException If the
  554        *            requested property is not known.
  555        * @exception SAXNotSupportedException If the
  556        *            requested property is known but not supported.
  557        */
  558       public Object getProperty(String propertyId)
  559           throws SAXNotRecognizedException, SAXNotSupportedException {
  560   
  561          if (propertyId.equals(CURRENT_ELEMENT_NODE)) {
  562              boolean deferred = false;
  563              try {
  564                  deferred = getFeature(DEFER_NODE_EXPANSION);
  565              }
  566              catch (XMLConfigurationException e){
  567                  // ignore
  568              }
  569              if (deferred) {
  570                  throw new SAXNotSupportedException(
  571                          DOMMessageFormatter.formatMessage(
  572                          DOMMessageFormatter.DOM_DOMAIN,
  573                          "CannotQueryDeferredNode", null));
  574              }
  575              return (fCurrentNode!=null &&
  576                      fCurrentNode.getNodeType() == Node.ELEMENT_NODE)? fCurrentNode:null;
  577          }
  578   
  579           try {
  580               return fConfiguration.getProperty(propertyId);
  581           }
  582           catch (XMLConfigurationException e) {
  583               String identifier = e.getIdentifier();
  584               if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  585                   throw new SAXNotRecognizedException(
  586                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  587                       "property-not-recognized", new Object [] {identifier}));
  588               }
  589               else {
  590                   throw new SAXNotSupportedException(
  591                       SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), 
  592                       "property-not-supported", new Object [] {identifier}));
  593               }
  594           }
  595   
  596       } // getProperty(String):Object
  597       
  598       /** 
  599        * Returns this parser's XMLParserConfiguration.
  600        */
  601       public XMLParserConfiguration getXMLParserConfiguration() {
  602           return fConfiguration;
  603       } // getXMLParserConfiguration():XMLParserConfiguration
  604   
  605   } // class DOMParser

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