1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2001-2004 The Apache Software Foundation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xerces" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, International
  53. * Business Machines, Inc., http://www.apache.org. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package com.sun.org.apache.xerces.internal.parsers;
  58. import java.io.IOException;
  59. import java.util.Locale;
  60. import com.sun.org.apache.xerces.internal.impl.Constants;
  61. import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl;
  62. import com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl;
  63. import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  64. import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  65. import com.sun.org.apache.xerces.internal.impl.XMLNamespaceBinder;
  66. import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDProcessor;
  67. import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDValidator;
  68. import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory;
  69. import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter;
  70. import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager;
  71. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  72. import com.sun.org.apache.xerces.internal.xni.XMLLocator;
  73. import com.sun.org.apache.xerces.internal.xni.XNIException;
  74. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  75. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  76. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  77. import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  78. import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDScanner;
  79. import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner;
  80. import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  81. import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration;
  82. /**
  83. * This is the DTD-only parser configuration. It extends the basic
  84. * configuration with a standard set of parser components appropriate
  85. * to DTD-centric validation. Since
  86. * the Xerces2 reference implementation document and DTD scanner
  87. * implementations are capable of acting as pull parsers, this
  88. * configuration implements the
  89. * <code>XMLPullParserConfiguration</code> interface.
  90. * <p>
  91. * In addition to the features and properties recognized by the base
  92. * parser configuration, this class recognizes these additional
  93. * features and properties:
  94. * <ul>
  95. * <li>Features
  96. * <ul>
  97. * <li>http://apache.org/xml/features/validation/warn-on-duplicate-attdef</li>
  98. * <li>http://apache.org/xml/features/validation/warn-on-undeclared-elemdef</li>
  99. * <li>http://apache.org/xml/features/allow-java-encodings</li>
  100. * <li>http://apache.org/xml/features/continue-after-fatal-error</li>
  101. * <li>http://apache.org/xml/features/load-external-dtd</li>
  102. * </ul>
  103. * <li>Properties
  104. * <ul>
  105. * <li>http://apache.org/xml/properties/internal/error-reporter</li>
  106. * <li>http://apache.org/xml/properties/internal/entity-manager</li>
  107. * <li>http://apache.org/xml/properties/internal/document-scanner</li>
  108. * <li>http://apache.org/xml/properties/internal/dtd-scanner</li>
  109. * <li>http://apache.org/xml/properties/internal/grammar-pool</li>
  110. * <li>http://apache.org/xml/properties/internal/validator/dtd</li>
  111. * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li>
  112. * </ul>
  113. * </ul>
  114. *
  115. * @author Arnaud Le Hors, IBM
  116. * @author Andy Clark, IBM
  117. * @author Neil Graham, IBM
  118. *
  119. * @version $Id: DTDConfiguration.java,v 1.17 2004/01/26 17:28:10 mrglavas Exp $
  120. */
  121. public class DTDConfiguration
  122. extends BasicParserConfiguration
  123. implements XMLPullParserConfiguration {
  124. //
  125. // Constants
  126. //
  127. // feature identifiers
  128. /** Feature identifier: warn on duplicate attribute definition. */
  129. protected static final String WARN_ON_DUPLICATE_ATTDEF =
  130. Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE;
  131. /** Feature identifier: warn on duplicate entity definition. */
  132. protected static final String WARN_ON_DUPLICATE_ENTITYDEF =
  133. Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE;
  134. /** Feature identifier: warn on undeclared element definition. */
  135. protected static final String WARN_ON_UNDECLARED_ELEMDEF =
  136. Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE;
  137. /** Feature identifier: allow Java encodings. */
  138. protected static final String ALLOW_JAVA_ENCODINGS =
  139. Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
  140. /** Feature identifier: continue after fatal error. */
  141. protected static final String CONTINUE_AFTER_FATAL_ERROR =
  142. Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
  143. /** Feature identifier: load external DTD. */
  144. protected static final String LOAD_EXTERNAL_DTD =
  145. Constants.XERCES_FEATURE_PREFIX + Constants.LOAD_EXTERNAL_DTD_FEATURE;
  146. /** Feature identifier: notify built-in refereces. */
  147. protected static final String NOTIFY_BUILTIN_REFS =
  148. Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE;
  149. /** Feature identifier: notify character refereces. */
  150. protected static final String NOTIFY_CHAR_REFS =
  151. Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE;
  152. // property identifiers
  153. /** Property identifier: error reporter. */
  154. protected static final String ERROR_REPORTER =
  155. Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  156. /** Property identifier: entity manager. */
  157. protected static final String ENTITY_MANAGER =
  158. Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
  159. /** Property identifier document scanner: */
  160. protected static final String DOCUMENT_SCANNER =
  161. Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY;
  162. /** Property identifier: DTD scanner. */
  163. protected static final String DTD_SCANNER =
  164. Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY;
  165. /** Property identifier: grammar pool. */
  166. protected static final String XMLGRAMMAR_POOL =
  167. Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  168. /** Property identifier: DTD loader. */
  169. protected static final String DTD_PROCESSOR =
  170. Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY;
  171. /** Property identifier: DTD validator. */
  172. protected static final String DTD_VALIDATOR =
  173. Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY;
  174. /** Property identifier: namespace binder. */
  175. protected static final String NAMESPACE_BINDER =
  176. Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY;
  177. /** Property identifier: datatype validator factory. */
  178. protected static final String DATATYPE_VALIDATOR_FACTORY =
  179. Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY;
  180. protected static final String VALIDATION_MANAGER =
  181. Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY;
  182. /** Property identifier: JAXP schema language / DOM schema-type. */
  183. protected static final String JAXP_SCHEMA_LANGUAGE =
  184. Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE;
  185. /** Property identifier: JAXP schema source/ DOM schema-location. */
  186. protected static final String JAXP_SCHEMA_SOURCE =
  187. Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
  188. // debugging
  189. /** Set to true and recompile to print exception stack trace. */
  190. protected static final boolean PRINT_EXCEPTION_STACK_TRACE = false;
  191. //
  192. // Data
  193. //
  194. // components (non-configurable)
  195. /** Grammar pool. */
  196. protected XMLGrammarPool fGrammarPool;
  197. /** Datatype validator factory. */
  198. protected DTDDVFactory fDatatypeValidatorFactory;
  199. // components (configurable)
  200. /** Error reporter. */
  201. protected XMLErrorReporter fErrorReporter;
  202. /** Entity manager. */
  203. protected XMLEntityManager fEntityManager;
  204. /** Document scanner. */
  205. protected XMLDocumentScanner fScanner;
  206. /** Input Source */
  207. protected XMLInputSource fInputSource;
  208. /** DTD scanner. */
  209. protected XMLDTDScanner fDTDScanner;
  210. /** DTD Processor . */
  211. protected XMLDTDProcessor fDTDProcessor;
  212. /** DTD Validator. */
  213. protected XMLDTDValidator fDTDValidator;
  214. /** Namespace binder. */
  215. protected XMLNamespaceBinder fNamespaceBinder;
  216. protected ValidationManager fValidationManager;
  217. // state
  218. /** Locator */
  219. protected XMLLocator fLocator;
  220. /**
  221. * True if a parse is in progress. This state is needed because
  222. * some features/properties cannot be set while parsing (e.g.
  223. * validation and namespaces).
  224. */
  225. protected boolean fParseInProgress = false;
  226. //
  227. // Constructors
  228. //
  229. /** Default constructor. */
  230. public DTDConfiguration() {
  231. this(null, null, null);
  232. } // <init>()
  233. /**
  234. * Constructs a parser configuration using the specified symbol table.
  235. *
  236. * @param symbolTable The symbol table to use.
  237. */
  238. public DTDConfiguration(SymbolTable symbolTable) {
  239. this(symbolTable, null, null);
  240. } // <init>(SymbolTable)
  241. /**
  242. * Constructs a parser configuration using the specified symbol table and
  243. * grammar pool.
  244. * <p>
  245. * <strong>REVISIT:</strong>
  246. * Grammar pool will be updated when the new validation engine is
  247. * implemented.
  248. *
  249. * @param symbolTable The symbol table to use.
  250. * @param grammarPool The grammar pool to use.
  251. */
  252. public DTDConfiguration(SymbolTable symbolTable,
  253. XMLGrammarPool grammarPool) {
  254. this(symbolTable, grammarPool, null);
  255. } // <init>(SymbolTable,XMLGrammarPool)
  256. /**
  257. * Constructs a parser configuration using the specified symbol table,
  258. * grammar pool, and parent settings.
  259. * <p>
  260. * <strong>REVISIT:</strong>
  261. * Grammar pool will be updated when the new validation engine is
  262. * implemented.
  263. *
  264. * @param symbolTable The symbol table to use.
  265. * @param grammarPool The grammar pool to use.
  266. * @param parentSettings The parent settings.
  267. */
  268. public DTDConfiguration(SymbolTable symbolTable,
  269. XMLGrammarPool grammarPool,
  270. XMLComponentManager parentSettings) {
  271. super(symbolTable, parentSettings);
  272. // add default recognized features
  273. final String[] recognizedFeatures = {
  274. //WARN_ON_DUPLICATE_ATTDEF, // from XMLDTDScannerImpl
  275. //WARN_ON_UNDECLARED_ELEMDEF, // from XMLDTDScannerImpl
  276. //ALLOW_JAVA_ENCODINGS, // from XMLEntityManager
  277. CONTINUE_AFTER_FATAL_ERROR,
  278. LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl
  279. //NOTIFY_BUILTIN_REFS, // from XMLDocumentFragmentScannerImpl
  280. //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl
  281. //WARN_ON_DUPLICATE_ENTITYDEF, // from XMLEntityManager
  282. };
  283. addRecognizedFeatures(recognizedFeatures);
  284. // set state for default features
  285. //setFeature(WARN_ON_DUPLICATE_ATTDEF, false); // from XMLDTDScannerImpl
  286. //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false); // from XMLDTDScannerImpl
  287. //setFeature(ALLOW_JAVA_ENCODINGS, false); // from XMLEntityManager
  288. setFeature(CONTINUE_AFTER_FATAL_ERROR, false);
  289. setFeature(LOAD_EXTERNAL_DTD, true); // from XMLDTDScannerImpl
  290. //setFeature(NOTIFY_BUILTIN_REFS, false); // from XMLDocumentFragmentScannerImpl
  291. //setFeature(NOTIFY_CHAR_REFS, false); // from XMLDocumentFragmentScannerImpl
  292. //setFeature(WARN_ON_DUPLICATE_ENTITYDEF, false); // from XMLEntityManager
  293. // add default recognized properties
  294. final String[] recognizedProperties = {
  295. ERROR_REPORTER,
  296. ENTITY_MANAGER,
  297. DOCUMENT_SCANNER,
  298. DTD_SCANNER,
  299. DTD_PROCESSOR,
  300. DTD_VALIDATOR,
  301. NAMESPACE_BINDER,
  302. XMLGRAMMAR_POOL,
  303. DATATYPE_VALIDATOR_FACTORY,
  304. VALIDATION_MANAGER,
  305. JAXP_SCHEMA_SOURCE,
  306. JAXP_SCHEMA_LANGUAGE
  307. };
  308. addRecognizedProperties(recognizedProperties);
  309. fGrammarPool = grammarPool;
  310. if(fGrammarPool != null){
  311. setProperty(XMLGRAMMAR_POOL, fGrammarPool);
  312. }
  313. fEntityManager = createEntityManager();
  314. setProperty(ENTITY_MANAGER, fEntityManager);
  315. addComponent(fEntityManager);
  316. fErrorReporter = createErrorReporter();
  317. fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner());
  318. setProperty(ERROR_REPORTER, fErrorReporter);
  319. addComponent(fErrorReporter);
  320. fScanner = createDocumentScanner();
  321. setProperty(DOCUMENT_SCANNER, fScanner);
  322. if (fScanner instanceof XMLComponent) {
  323. addComponent((XMLComponent)fScanner);
  324. }
  325. fDTDScanner = createDTDScanner();
  326. if (fDTDScanner != null) {
  327. setProperty(DTD_SCANNER, fDTDScanner);
  328. if (fDTDScanner instanceof XMLComponent) {
  329. addComponent((XMLComponent)fDTDScanner);
  330. }
  331. }
  332. fDTDProcessor = createDTDProcessor();
  333. if (fDTDProcessor != null) {
  334. setProperty(DTD_PROCESSOR, fDTDProcessor);
  335. if (fDTDProcessor instanceof XMLComponent) {
  336. addComponent((XMLComponent)fDTDProcessor);
  337. }
  338. }
  339. fDTDValidator = createDTDValidator();
  340. if (fDTDValidator != null) {
  341. setProperty(DTD_VALIDATOR, fDTDValidator);
  342. addComponent(fDTDValidator);
  343. }
  344. fNamespaceBinder = createNamespaceBinder();
  345. if (fNamespaceBinder != null) {
  346. setProperty(NAMESPACE_BINDER, fNamespaceBinder);
  347. addComponent(fNamespaceBinder);
  348. }
  349. fDatatypeValidatorFactory = createDatatypeValidatorFactory();
  350. if (fDatatypeValidatorFactory != null) {
  351. setProperty(DATATYPE_VALIDATOR_FACTORY,
  352. fDatatypeValidatorFactory);
  353. }
  354. fValidationManager = createValidationManager();
  355. if (fValidationManager != null) {
  356. setProperty (VALIDATION_MANAGER, fValidationManager);
  357. }
  358. // add message formatters
  359. if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
  360. XMLMessageFormatter xmft = new XMLMessageFormatter();
  361. fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft);
  362. fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft);
  363. }
  364. // set locale
  365. try {
  366. setLocale(Locale.getDefault());
  367. }
  368. catch (XNIException e) {
  369. // do nothing
  370. // REVISIT: What is the right thing to do? -Ac
  371. }
  372. } // <init>(SymbolTable,XMLGrammarPool)
  373. //
  374. // Public methods
  375. //
  376. /**
  377. * Set the locale to use for messages.
  378. *
  379. * @param locale The locale object to use for localization of messages.
  380. *
  381. * @exception XNIException Thrown if the parser does not support the
  382. * specified locale.
  383. */
  384. public void setLocale(Locale locale) throws XNIException {
  385. super.setLocale(locale);
  386. fErrorReporter.setLocale(locale);
  387. } // setLocale(Locale)
  388. //
  389. // XMLPullParserConfiguration methods
  390. //
  391. // parsing
  392. /**
  393. * Sets the input source for the document to parse.
  394. *
  395. * @param inputSource The document's input source.
  396. *
  397. * @exception XMLConfigurationException Thrown if there is a
  398. * configuration error when initializing the
  399. * parser.
  400. * @exception IOException Thrown on I/O error.
  401. *
  402. * @see #parse(boolean)
  403. */
  404. public void setInputSource(XMLInputSource inputSource)
  405. throws XMLConfigurationException, IOException {
  406. // REVISIT: this method used to reset all the components and
  407. // construct the pipeline. Now reset() is called
  408. // in parse (boolean) just before we parse the document
  409. // Should this method still throw exceptions..?
  410. fInputSource = inputSource;
  411. } // setInputSource(XMLInputSource)
  412. /**
  413. * Parses the document in a pull parsing fashion.
  414. *
  415. * @param complete True if the pull parser should parse the
  416. * remaining document completely.
  417. *
  418. * @return True if there is more document to parse.
  419. *
  420. * @exception XNIException Any XNI exception, possibly wrapping
  421. * another exception.
  422. * @exception IOException An IO exception from the parser, possibly
  423. * from a byte stream or character stream
  424. * supplied by the parser.
  425. *
  426. * @see #setInputSource
  427. */
  428. public boolean parse(boolean complete) throws XNIException, IOException {
  429. //
  430. // reset and configure pipeline and set InputSource.
  431. if (fInputSource !=null) {
  432. try {
  433. // resets and sets the pipeline.
  434. reset();
  435. fScanner.setInputSource(fInputSource);
  436. fInputSource = null;
  437. }
  438. catch (XNIException ex) {
  439. if (PRINT_EXCEPTION_STACK_TRACE)
  440. ex.printStackTrace();
  441. throw ex;
  442. }
  443. catch (IOException ex) {
  444. if (PRINT_EXCEPTION_STACK_TRACE)
  445. ex.printStackTrace();
  446. throw ex;
  447. }
  448. catch (RuntimeException ex) {
  449. if (PRINT_EXCEPTION_STACK_TRACE)
  450. ex.printStackTrace();
  451. throw ex;
  452. }
  453. catch (Exception ex) {
  454. if (PRINT_EXCEPTION_STACK_TRACE)
  455. ex.printStackTrace();
  456. throw new XNIException(ex);
  457. }
  458. }
  459. try {
  460. return fScanner.scanDocument(complete);
  461. }
  462. catch (XNIException ex) {
  463. if (PRINT_EXCEPTION_STACK_TRACE)
  464. ex.printStackTrace();
  465. throw ex;
  466. }
  467. catch (IOException ex) {
  468. if (PRINT_EXCEPTION_STACK_TRACE)
  469. ex.printStackTrace();
  470. throw ex;
  471. }
  472. catch (RuntimeException ex) {
  473. if (PRINT_EXCEPTION_STACK_TRACE)
  474. ex.printStackTrace();
  475. throw ex;
  476. }
  477. catch (Exception ex) {
  478. if (PRINT_EXCEPTION_STACK_TRACE)
  479. ex.printStackTrace();
  480. throw new XNIException(ex);
  481. }
  482. } // parse(boolean):boolean
  483. /**
  484. * If the application decides to terminate parsing before the xml document
  485. * is fully parsed, the application should call this method to free any
  486. * resource allocated during parsing. For example, close all opened streams.
  487. */
  488. public void cleanup() {
  489. fEntityManager.closeReaders();
  490. }
  491. //
  492. // XMLParserConfiguration methods
  493. //
  494. /**
  495. * Parses the specified input source.
  496. *
  497. * @param source The input source.
  498. *
  499. * @exception XNIException Throws exception on XNI error.
  500. * @exception java.io.IOException Throws exception on i/o error.
  501. */
  502. public void parse(XMLInputSource source) throws XNIException, IOException {
  503. if (fParseInProgress) {
  504. // REVISIT - need to add new error message
  505. throw new XNIException("FWK005 parse may not be called while parsing.");
  506. }
  507. fParseInProgress = true;
  508. try {
  509. setInputSource(source);
  510. parse(true);
  511. }
  512. catch (XNIException ex) {
  513. if (PRINT_EXCEPTION_STACK_TRACE)
  514. ex.printStackTrace();
  515. throw ex;
  516. }
  517. catch (IOException ex) {
  518. if (PRINT_EXCEPTION_STACK_TRACE)
  519. ex.printStackTrace();
  520. throw ex;
  521. }
  522. catch (RuntimeException ex) {
  523. if (PRINT_EXCEPTION_STACK_TRACE)
  524. ex.printStackTrace();
  525. throw ex;
  526. }
  527. catch (Exception ex) {
  528. if (PRINT_EXCEPTION_STACK_TRACE)
  529. ex.printStackTrace();
  530. throw new XNIException(ex);
  531. }
  532. finally {
  533. fParseInProgress = false;
  534. // close all streams opened by xerces
  535. this.cleanup();
  536. }
  537. } // parse(InputSource)
  538. //
  539. // Protected methods
  540. //
  541. /**
  542. * Reset all components before parsing.
  543. *
  544. * @throws XNIException Thrown if an error occurs during initialization.
  545. */
  546. protected void reset() throws XNIException {
  547. if (fValidationManager != null)
  548. fValidationManager.reset();
  549. // configure the pipeline and initialize the components
  550. configurePipeline();
  551. super.reset();
  552. } // reset()
  553. /** Configures the pipeline. */
  554. protected void configurePipeline() {
  555. // REVISIT: This should be better designed. In other words, we
  556. // need to figure out what is the best way for people to
  557. // re-use *most* of the standard configuration but do
  558. // things common things such as remove a component (e.g.
  559. // the validator), insert a new component (e.g. XInclude),
  560. // etc... -Ac
  561. // setup document pipeline
  562. if (fDTDValidator != null) {
  563. fScanner.setDocumentHandler(fDTDValidator);
  564. if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
  565. // filters
  566. fDTDValidator.setDocumentHandler(fNamespaceBinder);
  567. fDTDValidator.setDocumentSource(fScanner);
  568. fNamespaceBinder.setDocumentHandler(fDocumentHandler);
  569. fNamespaceBinder.setDocumentSource(fDTDValidator);
  570. fLastComponent = fNamespaceBinder;
  571. }
  572. else {
  573. fDTDValidator.setDocumentHandler(fDocumentHandler);
  574. fDTDValidator.setDocumentSource(fScanner);
  575. fLastComponent = fDTDValidator;
  576. }
  577. }
  578. else {
  579. if (fFeatures.get(NAMESPACES) == Boolean.TRUE) {
  580. fScanner.setDocumentHandler(fNamespaceBinder);
  581. fNamespaceBinder.setDocumentHandler(fDocumentHandler);
  582. fNamespaceBinder.setDocumentSource(fScanner);
  583. fLastComponent = fNamespaceBinder;
  584. }
  585. else {
  586. fScanner.setDocumentHandler(fDocumentHandler);
  587. fLastComponent = fScanner;
  588. }
  589. }
  590. configureDTDPipeline();
  591. } // configurePipeline()
  592. protected void configureDTDPipeline (){
  593. // setup dtd pipeline
  594. if (fDTDScanner != null) {
  595. fProperties.put(DTD_SCANNER, fDTDScanner);
  596. if (fDTDProcessor != null) {
  597. fProperties.put(DTD_PROCESSOR, fDTDProcessor);
  598. fDTDScanner.setDTDHandler(fDTDProcessor);
  599. fDTDProcessor.setDTDSource(fDTDScanner);
  600. fDTDProcessor.setDTDHandler(fDTDHandler);
  601. if (fDTDHandler != null) {
  602. fDTDHandler.setDTDSource(fDTDProcessor);
  603. }
  604. fDTDScanner.setDTDContentModelHandler(fDTDProcessor);
  605. fDTDProcessor.setDTDContentModelSource(fDTDScanner);
  606. fDTDProcessor.setDTDContentModelHandler(fDTDContentModelHandler);
  607. if (fDTDContentModelHandler != null) {
  608. fDTDContentModelHandler.setDTDContentModelSource(fDTDProcessor);
  609. }
  610. }
  611. else {
  612. fDTDScanner.setDTDHandler(fDTDHandler);
  613. if (fDTDHandler != null) {
  614. fDTDHandler.setDTDSource(fDTDScanner);
  615. }
  616. fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler);
  617. if (fDTDContentModelHandler != null) {
  618. fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner);
  619. }
  620. }
  621. }
  622. }
  623. // features and properties
  624. /**
  625. * Check a feature. If feature is know and supported, this method simply
  626. * returns. Otherwise, the appropriate exception is thrown.
  627. *
  628. * @param featureId The unique identifier (URI) of the feature.
  629. *
  630. * @throws XMLConfigurationException Thrown for configuration error.
  631. * In general, components should
  632. * only throw this exception if
  633. * it is <strong>really</strong>
  634. * a critical error.
  635. */
  636. protected void checkFeature(String featureId)
  637. throws XMLConfigurationException {
  638. //
  639. // Xerces Features
  640. //
  641. if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) {
  642. final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length();
  643. //
  644. // http://apache.org/xml/features/validation/dynamic
  645. // Allows the parser to validate a document only when it
  646. // contains a grammar. Validation is turned on/off based
  647. // on each document instance, automatically.
  648. //
  649. if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() &&
  650. featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) {
  651. return;
  652. }
  653. //
  654. // http://apache.org/xml/features/validation/default-attribute-values
  655. //
  656. if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() &&
  657. featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) {
  658. // REVISIT
  659. short type = XMLConfigurationException.NOT_SUPPORTED;
  660. throw new XMLConfigurationException(type, featureId);
  661. }
  662. //
  663. // http://apache.org/xml/features/validation/default-attribute-values
  664. //
  665. if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() &&
  666. featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) {
  667. // REVISIT
  668. short type = XMLConfigurationException.NOT_SUPPORTED;
  669. throw new XMLConfigurationException(type, featureId);
  670. }
  671. //
  672. // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar
  673. //
  674. if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() &&
  675. featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) {
  676. return;
  677. }
  678. //
  679. // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd
  680. //
  681. if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() &&
  682. featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) {
  683. return;
  684. }
  685. //
  686. // http://apache.org/xml/features/validation/default-attribute-values
  687. //
  688. if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() &&
  689. featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) {
  690. short type = XMLConfigurationException.NOT_SUPPORTED;
  691. throw new XMLConfigurationException(type, featureId);
  692. }
  693. }
  694. //
  695. // Not recognized
  696. //
  697. super.checkFeature(featureId);
  698. } // checkFeature(String)
  699. /**
  700. * Check a property. If the property is know and supported, this method
  701. * simply returns. Otherwise, the appropriate exception is thrown.
  702. *
  703. * @param propertyId The unique identifier (URI) of the property
  704. * being set.
  705. *
  706. * @throws XMLConfigurationException Thrown for configuration error.
  707. * In general, components should
  708. * only throw this exception if
  709. * it is <strong>really</strong>
  710. * a critical error.
  711. */
  712. protected void checkProperty(String propertyId)
  713. throws XMLConfigurationException {
  714. //
  715. // Xerces Properties
  716. //
  717. if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) {
  718. final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length();
  719. if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() &&
  720. propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) {
  721. return;
  722. }
  723. }
  724. //
  725. // Not recognized
  726. //
  727. super.checkProperty(propertyId);
  728. } // checkProperty(String)
  729. // factory methods
  730. /** Creates an entity manager. */
  731. protected XMLEntityManager createEntityManager() {
  732. return new XMLEntityManager();
  733. } // createEntityManager():XMLEntityManager
  734. /** Creates an error reporter. */
  735. protected XMLErrorReporter createErrorReporter() {
  736. return new XMLErrorReporter();
  737. } // createErrorReporter():XMLErrorReporter
  738. /** Create a document scanner. */
  739. protected XMLDocumentScanner createDocumentScanner() {
  740. return new XMLDocumentScannerImpl();
  741. } // createDocumentScanner():XMLDocumentScanner
  742. /** Create a DTD scanner. */
  743. protected XMLDTDScanner createDTDScanner() {
  744. return new XMLDTDScannerImpl();
  745. } // createDTDScanner():XMLDTDScanner
  746. /** Create a DTD loader . */
  747. protected XMLDTDProcessor createDTDProcessor() {
  748. return new XMLDTDProcessor();
  749. } // createDTDProcessor():XMLDTDProcessor
  750. /** Create a DTD validator. */
  751. protected XMLDTDValidator createDTDValidator() {
  752. return new XMLDTDValidator();
  753. } // createDTDValidator():XMLDTDValidator
  754. /** Create a namespace binder. */
  755. protected XMLNamespaceBinder createNamespaceBinder() {
  756. return new XMLNamespaceBinder();
  757. } // createNamespaceBinder():XMLNamespaceBinder
  758. /** Create a datatype validator factory. */
  759. protected DTDDVFactory createDatatypeValidatorFactory() {
  760. return DTDDVFactory.getInstance();
  761. } // createDatatypeValidatorFactory():DatatypeValidatorFactory
  762. protected ValidationManager createValidationManager(){
  763. return new ValidationManager();
  764. }
  765. } // class DTDConfiguration