1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * The Apache Software License, Version 1.1
   7  *
   8  *
   9  * Copyright (c) 1999-2003 The Apache Software Foundation.
  10  * All rights reserved.
  11  *
  12  * Redistribution and use in source and binary forms, with or without
  13  * modification, are permitted provided that the following conditions
  14  * are met:
  15  *
  16  * 1. Redistributions of source code must retain the above copyright
  17  *    notice, this list of conditions and the following disclaimer.
  18  *
  19  * 2. Redistributions in binary form must reproduce the above copyright
  20  *    notice, this list of conditions and the following disclaimer in
  21  *    the documentation and/or other materials provided with the
  22  *    distribution.
  23  *
  24  * 3. The end-user documentation included with the redistribution,
  25  *    if any, must include the following acknowledgment:
  26  *       "This product includes software developed by the
  27  *        Apache Software Foundation (http://www.apache.org/)."
  28  *    Alternately, this acknowledgment may appear in the software itself,
  29  *    if and wherever such third-party acknowledgments normally appear.
  30  *
  31  * 4. The names "Xerces" and "Apache Software Foundation" must
  32  *    not be used to endorse or promote products derived from this
  33  *    software without prior written permission. For written
  34  *    permission, please contact apache@apache.org.
  35  *
  36  * 5. Products derived from this software may not be called "Apache",
  37  *    nor may "Apache" appear in their name, without prior written
  38  *    permission of the Apache Software Foundation.
  39  *
  40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  44  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  51  * SUCH DAMAGE.
  52  * ====================================================================
  53  *
  54  * This software consists of voluntary contributions made by many
  55  * individuals on behalf of the Apache Software Foundation and was
  56  * originally based on software copyright (c) 1999, International
  57  * Business Machines, Inc., http://www.apache.org.  For more
  58  * information on the Apache Software Foundation, please see
  59  * <http://www.apache.org/>.
  60  */
  61 
  62 package com.sun.org.apache.xerces.internal.impl.dtd;
  63 
  64 import java.io.EOFException;
  65 import java.io.IOException;
  66 import java.io.StringReader;
  67 import java.util.Locale;
  68 
  69 import com.sun.org.apache.xerces.internal.impl.Constants;
  70 import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
  71 import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  72 import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  73 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  74 
  75 import com.sun.org.apache.xerces.internal.util.Status;
  76 import com.sun.org.apache.xerces.internal.util.SymbolTable;
  77 import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
  78 
  79 import com.sun.org.apache.xerces.internal.xni.XNIException;
  80 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  81 import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarLoader;
  82 import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  83 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  84 import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  85 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  86 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  87 
  88 
  89 /**
  90  * The DTD loader. The loader knows how to build grammars from XMLInputSources.
  91  * It extends the DTD processor in order to do this; it's
  92  * a separate class because DTD processors don't need to know how
  93  * to talk to the outside world in their role as instance-document
  94  * helpers.
  95  * <p>
  96  * This component requires the following features and properties.  It
  97  * know ho to set them if no one else does:from the
  98  * <ul>
  99  *  <li>http://xml.org/sax/features/namespaces</li>
 100  *  <li>http://apache.org/xml/properties/internal/symbol-table</li>
 101  *  <li>http://apache.org/xml/properties/internal/error-reporter</li>
 102  *  <li>http://apache.org/xml/properties/internal/grammar-pool</li>
 103  *  <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
 104  * </ul>
 105  *
 106  * @xerces.internal
 107  *
 108  * @author Neil Graham, IBM
 109  * @author Michael Glavassevich, IBM
 110  *
 111  */
 112 public class XMLDTDLoader
 113         extends XMLDTDProcessor
 114         implements XMLGrammarLoader {
 115 
 116     //
 117     // Constants
 118     //
 119 
 120     // feature identifiers
 121 
 122     /** Feature identifier: standard uri conformant feature. */
 123     protected static final String STANDARD_URI_CONFORMANT_FEATURE =
 124         Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
 125 
 126     /** Feature identifier: balance syntax trees. */
 127     protected static final String BALANCE_SYNTAX_TREES =
 128         Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES;
 129 
 130     // recognized features:
 131     private static final String[] LOADER_RECOGNIZED_FEATURES = {
 132         VALIDATION,
 133         WARN_ON_DUPLICATE_ATTDEF,
 134         WARN_ON_UNDECLARED_ELEMDEF,
 135         NOTIFY_CHAR_REFS,
 136         STANDARD_URI_CONFORMANT_FEATURE,
 137         BALANCE_SYNTAX_TREES
 138     };
 139 
 140     // property identifiers
 141 
 142     /** Property identifier: error handler. */
 143     protected static final String ERROR_HANDLER =
 144         Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
 145 
 146     /** Property identifier: entity resolver. */
 147     public static final String ENTITY_RESOLVER =
 148         Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
 149 
 150     /** Property identifier: locale. */
 151     public static final String LOCALE =
 152         Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY;
 153 
 154     /** Recognized properties. */
 155     private static final String[] LOADER_RECOGNIZED_PROPERTIES = {
 156         SYMBOL_TABLE,
 157         ERROR_REPORTER,
 158         ERROR_HANDLER,
 159         ENTITY_RESOLVER,
 160         GRAMMAR_POOL,
 161         DTD_VALIDATOR,
 162         LOCALE
 163     };
 164 
 165     // enforcing strict uri?
 166     private boolean fStrictURI = false;
 167 
 168     /** Controls whether the DTD grammar produces balanced syntax trees. */
 169     private boolean fBalanceSyntaxTrees = false;
 170 
 171     /** Entity resolver . */
 172     protected XMLEntityResolver fEntityResolver;
 173 
 174     // the scanner we use to actually read the DTD
 175     protected XMLDTDScannerImpl fDTDScanner;
 176 
 177     // the entity manager the scanner needs.
 178     protected XMLEntityManager fEntityManager;
 179 
 180     // what's our Locale?
 181     protected Locale fLocale;
 182 
 183     //
 184     // Constructors
 185     //
 186 
 187     /** Deny default construction; we need a SymtolTable! */
 188     public XMLDTDLoader() {
 189         this(new SymbolTable());
 190     } // <init>()
 191 
 192     public XMLDTDLoader(SymbolTable symbolTable) {
 193         this(symbolTable, null);
 194     } // init(SymbolTable)
 195 
 196     public XMLDTDLoader(SymbolTable symbolTable,
 197                 XMLGrammarPool grammarPool) {
 198         this(symbolTable, grammarPool, null, new XMLEntityManager());
 199     } // init(SymbolTable, XMLGrammarPool)
 200 
 201     XMLDTDLoader(SymbolTable symbolTable,
 202                 XMLGrammarPool grammarPool, XMLErrorReporter errorReporter,
 203                 XMLEntityResolver entityResolver) {
 204         fSymbolTable = symbolTable;
 205         fGrammarPool = grammarPool;
 206         if(errorReporter == null) {
 207             errorReporter = new XMLErrorReporter();
 208             errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler());
 209         }
 210         fErrorReporter = errorReporter;
 211         // Add XML message formatter if there isn't one.
 212         if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
 213             XMLMessageFormatter xmft = new XMLMessageFormatter();
 214             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
 215             fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
 216         }
 217         fEntityResolver = entityResolver;
 218         if(fEntityResolver instanceof XMLEntityManager) {
 219             fEntityManager = (XMLEntityManager)fEntityResolver;
 220         } else {
 221             fEntityManager = new XMLEntityManager();
 222         }
 223         fEntityManager.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY, errorReporter);
 224         fDTDScanner = createDTDScanner(fSymbolTable, fErrorReporter, fEntityManager);
 225         fDTDScanner.setDTDHandler(this);
 226         fDTDScanner.setDTDContentModelHandler(this);
 227         reset();
 228     } // init(SymbolTable, XMLGrammarPool, XMLErrorReporter, XMLEntityResolver)
 229 
 230     // XMLGrammarLoader methods
 231 
 232     /**
 233      * Returns a list of feature identifiers that are recognized by
 234      * this component. This method may return null if no features
 235      * are recognized by this component.
 236      */
 237     public String[] getRecognizedFeatures() {
 238         return (String[])(LOADER_RECOGNIZED_FEATURES.clone());
 239     } // getRecognizedFeatures():String[]
 240 
 241     /**
 242      * Sets the state of a feature. This method is called by the component
 243      * manager any time after reset when a feature changes state.
 244      * <p>
 245      * <strong>Note:</strong> Components should silently ignore features
 246      * that do not affect the operation of the component.
 247      *
 248      * @param featureId The feature identifier.
 249      * @param state     The state of the feature.
 250      *
 251      * @throws SAXNotRecognizedException The component should not throw
 252      *                                   this exception.
 253      * @throws SAXNotSupportedException The component should not throw
 254      *                                  this exception.
 255      */
 256     public void setFeature(String featureId, boolean state)
 257             throws XMLConfigurationException {
 258         if (featureId.equals(VALIDATION)) {
 259             fValidation = state;
 260         }
 261         else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
 262             fWarnDuplicateAttdef = state;
 263         }
 264         else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
 265             fWarnOnUndeclaredElemdef = state;
 266         }
 267         else if (featureId.equals(NOTIFY_CHAR_REFS)) {
 268             fDTDScanner.setFeature(featureId, state);
 269         }
 270         else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) {
 271             fStrictURI = state;
 272         }
 273         else if (featureId.equals(BALANCE_SYNTAX_TREES)) {
 274             fBalanceSyntaxTrees = state;
 275         }
 276         else {
 277             throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId);
 278         }
 279     } // setFeature(String,boolean)
 280 
 281     /**
 282      * Returns a list of property identifiers that are recognized by
 283      * this component. This method may return null if no properties
 284      * are recognized by this component.
 285      */
 286     public String[] getRecognizedProperties() {
 287         return (String[])(LOADER_RECOGNIZED_PROPERTIES.clone());
 288     } // getRecognizedProperties():String[]
 289 
 290     /**
 291      * Returns the state of a property.
 292      *
 293      * @param propertyId The property identifier.
 294      *
 295      * @throws XMLConfigurationException Thrown on configuration error.
 296      */
 297     public Object getProperty(String propertyId)
 298             throws XMLConfigurationException {
 299         if (propertyId.equals(SYMBOL_TABLE)) {
 300             return fSymbolTable;
 301         }
 302         else if (propertyId.equals(ERROR_REPORTER)) {
 303             return fErrorReporter;
 304         }
 305         else if (propertyId.equals(ERROR_HANDLER)) {
 306             return fErrorReporter.getErrorHandler();
 307         }
 308         else if (propertyId.equals(ENTITY_RESOLVER)) {
 309             return fEntityResolver;
 310         }
 311         else if (propertyId.equals(LOCALE)) {
 312             return getLocale();
 313         }
 314         else if (propertyId.equals(GRAMMAR_POOL)) {
 315             return fGrammarPool;
 316         }
 317         else if (propertyId.equals(DTD_VALIDATOR)) {
 318             return fValidator;
 319         }
 320         throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId);
 321     } // getProperty(String):  Object
 322 
 323     /**
 324      * Sets the value of a property. This method is called by the component
 325      * manager any time after reset when a property changes value.
 326      * <p>
 327      * <strong>Note:</strong> Components should silently ignore properties
 328      * that do not affect the operation of the component.
 329      *
 330      * @param propertyId The property identifier.
 331      * @param value      The value of the property.
 332      *
 333      * @throws SAXNotRecognizedException The component should not throw
 334      *                                   this exception.
 335      * @throws SAXNotSupportedException The component should not throw
 336      *                                  this exception.
 337      */
 338     public void setProperty(String propertyId, Object value)
 339             throws XMLConfigurationException {
 340         if (propertyId.equals(SYMBOL_TABLE)) {
 341             fSymbolTable = (SymbolTable)value;
 342             fDTDScanner.setProperty(propertyId, value);
 343             fEntityManager.setProperty(propertyId, value);
 344         }
 345         else if(propertyId.equals(ERROR_REPORTER)) {
 346             fErrorReporter = (XMLErrorReporter)value;
 347             // Add XML message formatter if there isn't one.
 348             if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
 349                 XMLMessageFormatter xmft = new XMLMessageFormatter();
 350                 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
 351                 fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
 352             }
 353             fDTDScanner.setProperty(propertyId, value);
 354             fEntityManager.setProperty(propertyId, value);
 355         }
 356         else if (propertyId.equals(ERROR_HANDLER)) {
 357             fErrorReporter.setProperty(propertyId, value);
 358         }
 359         else if (propertyId.equals(ENTITY_RESOLVER)) {
 360             fEntityResolver = (XMLEntityResolver)value;
 361             fEntityManager.setProperty(propertyId, value);
 362         }
 363         else if (propertyId.equals(LOCALE)) {
 364             setLocale((Locale) value);
 365         }
 366         else if(propertyId.equals(GRAMMAR_POOL)) {
 367             fGrammarPool = (XMLGrammarPool)value;
 368         }
 369         else {
 370             throw new XMLConfigurationException(Status.NOT_RECOGNIZED, propertyId);
 371         }
 372     } // setProperty(String,Object)
 373 
 374     /**
 375      * Returns the state of a feature.
 376      *
 377      * @param featureId The feature identifier.
 378      *
 379      * @throws XMLConfigurationException Thrown on configuration error.
 380      */
 381     public boolean getFeature(String featureId)
 382             throws XMLConfigurationException {
 383         if (featureId.equals(VALIDATION)) {
 384             return fValidation;
 385         }
 386         else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) {
 387             return fWarnDuplicateAttdef;
 388         }
 389         else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) {
 390             return fWarnOnUndeclaredElemdef;
 391         }
 392         else if (featureId.equals(NOTIFY_CHAR_REFS)) {
 393             return fDTDScanner.getFeature(featureId);
 394         }
 395         else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) {
 396             return fStrictURI;
 397         }
 398         else if (featureId.equals(BALANCE_SYNTAX_TREES)) {
 399             return fBalanceSyntaxTrees;
 400         }
 401         throw new XMLConfigurationException(Status.NOT_RECOGNIZED, featureId);
 402     } //getFeature(String):  boolean
 403 
 404     /**
 405      * Set the locale to use for messages.
 406      *
 407      * @param locale The locale object to use for localization of messages.
 408      *
 409      * @exception XNIException Thrown if the parser does not support the
 410      *                         specified locale.
 411      */
 412     public void setLocale(Locale locale) {
 413         fLocale = locale;
 414         fErrorReporter.setLocale(locale);
 415     } // setLocale(Locale)
 416 
 417     /** Return the Locale the XMLGrammarLoader is using. */
 418     public Locale getLocale() {
 419         return fLocale;
 420     } // getLocale():  Locale
 421 
 422 
 423     /**
 424      * Sets the error handler.
 425      *
 426      * @param errorHandler The error handler.
 427      */
 428     public void setErrorHandler(XMLErrorHandler errorHandler) {
 429         fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
 430     } // setErrorHandler(XMLErrorHandler)
 431 
 432     /** Returns the registered error handler.  */
 433     public XMLErrorHandler getErrorHandler() {
 434         return fErrorReporter.getErrorHandler();
 435     } // getErrorHandler():  XMLErrorHandler
 436 
 437     /**
 438      * Sets the entity resolver.
 439      *
 440      * @param entityResolver The new entity resolver.
 441      */
 442     public void setEntityResolver(XMLEntityResolver entityResolver) {
 443         fEntityResolver = entityResolver;
 444         fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver);
 445     } // setEntityResolver(XMLEntityResolver)
 446 
 447     /** Returns the registered entity resolver.  */
 448     public XMLEntityResolver getEntityResolver() {
 449         return fEntityResolver;
 450     } // getEntityResolver():  XMLEntityResolver
 451 
 452     /**
 453      * Returns a Grammar object by parsing the contents of the
 454      * entity pointed to by source.
 455      *
 456      * @param source        the location of the entity which forms
 457      *                          the starting point of the grammar to be constructed.
 458      * @throws IOException      When a problem is encountered reading the entity
 459      *          XNIException    When a condition arises (such as a FatalError) that requires parsing
 460      *                              of the entity be terminated.
 461      */
 462     public Grammar loadGrammar(XMLInputSource source)
 463             throws IOException, XNIException {
 464         reset();
 465         // First chance checking strict URI
 466         String eid = XMLEntityManager.expandSystemId(source.getSystemId(), source.getBaseSystemId(), fStrictURI);
 467         XMLDTDDescription desc = new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null);
 468         if (!fBalanceSyntaxTrees) {
 469             fDTDGrammar = new DTDGrammar(fSymbolTable, desc);
 470         }
 471         else {
 472             fDTDGrammar = new BalancedDTDGrammar(fSymbolTable, desc);
 473         }
 474         fGrammarBucket = new DTDGrammarBucket();
 475         fGrammarBucket.setStandalone(false);
 476         fGrammarBucket.setActiveGrammar(fDTDGrammar);
 477         // no reason to use grammar bucket's "put" method--we
 478         // know which grammar it is, and we don't know the root name anyway...
 479 
 480         // actually start the parsing!
 481         try {
 482             fDTDScanner.setInputSource(source);
 483             fDTDScanner.scanDTDExternalSubset(true);
 484         } catch (EOFException e) {
 485             // expected behaviour...
 486         }
 487         finally {
 488             // Close all streams opened by the parser.
 489             fEntityManager.closeReaders();
 490         }
 491         if(fDTDGrammar != null && fGrammarPool != null) {
 492             fGrammarPool.cacheGrammars(XMLDTDDescription.XML_DTD, new Grammar[] {fDTDGrammar});
 493         }
 494         return fDTDGrammar;
 495     } // loadGrammar(XMLInputSource):  Grammar
 496 
 497     /**
 498      * Parse a DTD internal and/or external subset and insert the content
 499      * into the existing DTD grammar owned by the given DTDValidator.
 500      */
 501     public void loadGrammarWithContext(XMLDTDValidator validator, String rootName,
 502             String publicId, String systemId, String baseSystemId, String internalSubset)
 503         throws IOException, XNIException {
 504         final DTDGrammarBucket grammarBucket = validator.getGrammarBucket();
 505         final DTDGrammar activeGrammar = grammarBucket.getActiveGrammar();
 506         if (activeGrammar != null && !activeGrammar.isImmutable()) {
 507             fGrammarBucket = grammarBucket;
 508             fEntityManager.setScannerVersion(getScannerVersion());
 509             reset();
 510             try {
 511                 // process internal subset
 512                 if (internalSubset != null) {
 513                     // To get the DTD scanner to end at the right place we have to fool
 514                     // it into thinking that it reached the end of the internal subset
 515                     // in a real document.
 516                     StringBuffer buffer = new StringBuffer(internalSubset.length() + 2);
 517                     buffer.append(internalSubset).append("]>");
 518                     XMLInputSource is = new XMLInputSource(null, baseSystemId,
 519                             null, new StringReader(buffer.toString()), null);
 520                     fEntityManager.startDocumentEntity(is);
 521                     fDTDScanner.scanDTDInternalSubset(true, false, systemId != null);
 522                 }
 523                 // process external subset
 524                 if (systemId != null) {
 525                     XMLDTDDescription desc = new XMLDTDDescription(publicId, systemId, baseSystemId, null, rootName);
 526                     XMLInputSource source = fEntityManager.resolveEntity(desc);
 527                     fDTDScanner.setInputSource(source);
 528                     fDTDScanner.scanDTDExternalSubset(true);
 529                 }
 530             }
 531             catch (EOFException e) {
 532                 // expected behaviour...
 533             }
 534             finally {
 535                 // Close all streams opened by the parser.
 536                 fEntityManager.closeReaders();
 537             }
 538         }
 539     } // loadGrammarWithContext(XMLDTDValidator, String, String, String, String, String)
 540 
 541     // reset all the components that we rely upon
 542     protected void reset() {
 543         super.reset();
 544         fDTDScanner.reset();
 545         fEntityManager.reset();
 546         fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
 547     }
 548 
 549     protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable,
 550             XMLErrorReporter errorReporter, XMLEntityManager entityManager) {
 551         return new XMLDTDScannerImpl(symbolTable, errorReporter, entityManager);
 552     } // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl
 553 
 554     protected short getScannerVersion() {
 555         return Constants.XML_VERSION_1_0;
 556     } // getScannerVersion() : short
 557 
 558 } // class XMLDTDLoader