1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
  6. * 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 com.sun.org.apache.xerces.internal.impl.Constants;
  60. import com.sun.org.apache.xerces.internal.util.EntityResolverWrapper;
  61. import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper;
  62. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  63. import com.sun.org.apache.xerces.internal.xni.XNIException;
  64. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  65. import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  66. import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  67. import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  68. import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  69. import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException;
  70. import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
  71. import org.w3c.dom.Node;
  72. import org.xml.sax.EntityResolver;
  73. import org.xml.sax.ErrorHandler;
  74. import org.xml.sax.InputSource;
  75. import org.xml.sax.SAXException;
  76. import org.xml.sax.SAXNotRecognizedException;
  77. import org.xml.sax.SAXNotSupportedException;
  78. import org.xml.sax.SAXParseException;
  79. import org.xml.sax.helpers.LocatorImpl;
  80. import com.sun.org.apache.xerces.internal.util.EntityResolver2Wrapper;
  81. import org.xml.sax.ext.EntityResolver2;
  82. /**
  83. * This is the main Xerces DOM parser class. It uses the abstract DOM
  84. * parser with a document scanner, a dtd scanner, and a validator, as
  85. * well as a grammar pool.
  86. *
  87. * @author Arnaud Le Hors, IBM
  88. * @author Andy Clark, IBM
  89. *
  90. * @version $Id: DOMParser.java,v 1.69 2004/02/17 07:14:49 neeraj Exp $
  91. */
  92. public class DOMParser
  93. extends AbstractDOMParser {
  94. //
  95. // Constants
  96. //
  97. // properties
  98. /** Property identifier: symbol table. */
  99. protected static final String SYMBOL_TABLE =
  100. Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  101. /** Property identifier: XML grammar pool. */
  102. protected static final String XMLGRAMMAR_POOL =
  103. Constants.XERCES_PROPERTY_PREFIX+Constants.XMLGRAMMAR_POOL_PROPERTY;
  104. /** Recognized properties. */
  105. private static final String[] RECOGNIZED_PROPERTIES = {
  106. SYMBOL_TABLE,
  107. XMLGRAMMAR_POOL,
  108. };
  109. //
  110. // Constructors
  111. //
  112. /**
  113. * Constructs a DOM parser using the specified parser configuration.
  114. */
  115. public DOMParser(XMLParserConfiguration config) {
  116. super(config);
  117. } // <init>(XMLParserConfiguration)
  118. /**
  119. * Constructs a DOM parser using the dtd/xml schema parser configuration.
  120. */
  121. public DOMParser() {
  122. this(null, null);
  123. } // <init>()
  124. /**
  125. * Constructs a DOM parser using the specified symbol table.
  126. */
  127. public DOMParser(SymbolTable symbolTable) {
  128. this(symbolTable, null);
  129. } // <init>(SymbolTable)
  130. /**
  131. * Constructs a DOM parser using the specified symbol table and
  132. * grammar pool.
  133. */
  134. public DOMParser(SymbolTable symbolTable, XMLGrammarPool grammarPool) {
  135. super((XMLParserConfiguration)ObjectFactory.createObject(
  136. "com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration",
  137. "com.sun.org.apache.xerces.internal.parsers.XIncludeParserConfiguration"
  138. ));
  139. // set properties
  140. fConfiguration.addRecognizedProperties(RECOGNIZED_PROPERTIES);
  141. if (symbolTable != null) {
  142. fConfiguration.setProperty(SYMBOL_TABLE, symbolTable);
  143. }
  144. if (grammarPool != null) {
  145. fConfiguration.setProperty(XMLGRAMMAR_POOL, grammarPool);
  146. }
  147. } // <init>(SymbolTable,XMLGrammarPool)
  148. //
  149. // XMLReader methods
  150. //
  151. /**
  152. * Parses the input source specified by the given system identifier.
  153. * <p>
  154. * This method is equivalent to the following:
  155. * <pre>
  156. * parse(new InputSource(systemId));
  157. * </pre>
  158. *
  159. * @param source The input source.
  160. *
  161. * @exception org.xml.sax.SAXException Throws exception on SAX error.
  162. * @exception java.io.IOException Throws exception on i/o error.
  163. */
  164. public void parse(String systemId) throws SAXException, IOException {
  165. // parse document
  166. XMLInputSource source = new XMLInputSource(null, systemId, null);
  167. try {
  168. parse(source);
  169. }
  170. // wrap XNI exceptions as SAX exceptions
  171. catch (XMLParseException e) {
  172. Exception ex = e.getException();
  173. if (ex == null) {
  174. // must be a parser exception; mine it for locator info and throw
  175. // a SAXParseException
  176. LocatorImpl locatorImpl = new LocatorImpl();
  177. locatorImpl.setPublicId(e.getPublicId());
  178. locatorImpl.setSystemId(e.getExpandedSystemId());
  179. locatorImpl.setLineNumber(e.getLineNumber());
  180. locatorImpl.setColumnNumber(e.getColumnNumber());
  181. throw new SAXParseException(e.getMessage(), locatorImpl);
  182. }
  183. if (ex instanceof SAXException) {
  184. // why did we create an XMLParseException?
  185. throw (SAXException)ex;
  186. }
  187. if (ex instanceof IOException) {
  188. throw (IOException)ex;
  189. }
  190. throw new SAXException(ex);
  191. }
  192. catch (XNIException e) {
  193. e.printStackTrace();
  194. Exception ex = e.getException();
  195. if (ex == null) {
  196. throw new SAXException(e.getMessage());
  197. }
  198. if (ex instanceof SAXException) {
  199. throw (SAXException)ex;
  200. }
  201. if (ex instanceof IOException) {
  202. throw (IOException)ex;
  203. }
  204. throw new SAXException(ex);
  205. }
  206. } // parse(String)
  207. /**
  208. * parse
  209. *
  210. * @param inputSource
  211. *
  212. * @exception org.xml.sax.SAXException
  213. * @exception java.io.IOException
  214. */
  215. public void parse(InputSource inputSource)
  216. throws SAXException, IOException {
  217. // parse document
  218. try {
  219. XMLInputSource xmlInputSource =
  220. new XMLInputSource(inputSource.getPublicId(),
  221. inputSource.getSystemId(),
  222. null);
  223. xmlInputSource.setByteStream(inputSource.getByteStream());
  224. xmlInputSource.setCharacterStream(inputSource.getCharacterStream());
  225. xmlInputSource.setEncoding(inputSource.getEncoding());
  226. parse(xmlInputSource);
  227. }
  228. // wrap XNI exceptions as SAX exceptions
  229. catch (XMLParseException e) {
  230. Exception ex = e.getException();
  231. if (ex == null) {
  232. // must be a parser exception; mine it for locator info and throw
  233. // a SAXParseException
  234. LocatorImpl locatorImpl = new LocatorImpl();
  235. locatorImpl.setPublicId(e.getPublicId());
  236. locatorImpl.setSystemId(e.getExpandedSystemId());
  237. locatorImpl.setLineNumber(e.getLineNumber());
  238. locatorImpl.setColumnNumber(e.getColumnNumber());
  239. throw new SAXParseException(e.getMessage(), locatorImpl);
  240. }
  241. if (ex instanceof SAXException) {
  242. // why did we create an XMLParseException?
  243. throw (SAXException)ex;
  244. }
  245. if (ex instanceof IOException) {
  246. throw (IOException)ex;
  247. }
  248. throw new SAXException(ex);
  249. }
  250. catch (XNIException e) {
  251. Exception ex = e.getException();
  252. if (ex == null) {
  253. throw new SAXException(e.getMessage());
  254. }
  255. if (ex instanceof SAXException) {
  256. throw (SAXException)ex;
  257. }
  258. if (ex instanceof IOException) {
  259. throw (IOException)ex;
  260. }
  261. throw new SAXException(ex);
  262. }
  263. } // parse(InputSource)
  264. /**
  265. * Sets the resolver used to resolve external entities. The EntityResolver
  266. * interface supports resolution of public and system identifiers.
  267. *
  268. * @param resolver The new entity resolver. Passing a null value will
  269. * uninstall the currently installed resolver.
  270. */
  271. public void setEntityResolver(EntityResolver resolver) {
  272. try {
  273. if(resolver instanceof EntityResolver2){
  274. fConfiguration.setProperty(ENTITY_RESOLVER, new EntityResolver2Wrapper((EntityResolver2)resolver));
  275. }else{
  276. fConfiguration.setProperty(ENTITY_RESOLVER, new EntityResolverWrapper(resolver));
  277. }
  278. }
  279. catch (XMLConfigurationException e) {
  280. // do nothing
  281. }
  282. } // setEntityResolver(EntityResolver)
  283. /**
  284. * Return the current entity resolver.
  285. *
  286. * @return The current entity resolver, or null if none
  287. * has been registered.
  288. * @see #setEntityResolver
  289. */
  290. public EntityResolver getEntityResolver() {
  291. EntityResolver entityResolver = null;
  292. try {
  293. XMLEntityResolver xmlEntityResolver =
  294. (XMLEntityResolver)fConfiguration.getProperty(ENTITY_RESOLVER);
  295. if (xmlEntityResolver != null){
  296. if(xmlEntityResolver instanceof EntityResolverWrapper) {
  297. entityResolver = ((EntityResolverWrapper)xmlEntityResolver).getEntityResolver();
  298. }else if(xmlEntityResolver instanceof EntityResolver2Wrapper){
  299. entityResolver = ((EntityResolver2Wrapper)xmlEntityResolver).getEntityResolver();
  300. }
  301. }
  302. }catch (XMLConfigurationException e) {
  303. // do nothing
  304. }
  305. return entityResolver;
  306. } // getEntityResolver():EntityResolver
  307. /**
  308. * Allow an application to register an error event handler.
  309. *
  310. * <p>If the application does not register an error handler, all
  311. * error events reported by the SAX parser will be silently
  312. * ignored; however, normal processing may not continue. It is
  313. * highly recommended that all SAX applications implement an
  314. * error handler to avoid unexpected bugs.</p>
  315. *
  316. * <p>Applications may register a new or different handler in the
  317. * middle of a parse, and the SAX parser must begin using the new
  318. * handler immediately.</p>
  319. *
  320. * @param errorHandler The error handler.
  321. * @exception java.lang.NullPointerException If the handler
  322. * argument is null.
  323. * @see #getErrorHandler
  324. */
  325. public void setErrorHandler(ErrorHandler errorHandler) {
  326. try {
  327. fConfiguration.setProperty(ERROR_HANDLER,
  328. new ErrorHandlerWrapper(errorHandler));
  329. }
  330. catch (XMLConfigurationException e) {
  331. // do nothing
  332. }
  333. } // setErrorHandler(ErrorHandler)
  334. /**
  335. * Return the current error handler.
  336. *
  337. * @return The current error handler, or null if none
  338. * has been registered.
  339. * @see #setErrorHandler
  340. */
  341. public ErrorHandler getErrorHandler() {
  342. ErrorHandler errorHandler = null;
  343. try {
  344. XMLErrorHandler xmlErrorHandler =
  345. (XMLErrorHandler)fConfiguration.getProperty(ERROR_HANDLER);
  346. if (xmlErrorHandler != null &&
  347. xmlErrorHandler instanceof ErrorHandlerWrapper) {
  348. errorHandler = ((ErrorHandlerWrapper)xmlErrorHandler).getErrorHandler();
  349. }
  350. }
  351. catch (XMLConfigurationException e) {
  352. // do nothing
  353. }
  354. return errorHandler;
  355. } // getErrorHandler():ErrorHandler
  356. /**
  357. * Set the state of any feature in a SAX2 parser. The parser
  358. * might not recognize the feature, and if it does recognize
  359. * it, it might not be able to fulfill the request.
  360. *
  361. * @param featureId The unique identifier (URI) of the feature.
  362. * @param state The requested state of the feature (true or false).
  363. *
  364. * @exception SAXNotRecognizedException If the
  365. * requested feature is not known.
  366. * @exception SAXNotSupportedException If the
  367. * requested feature is known, but the requested
  368. * state is not supported.
  369. */
  370. public void setFeature(String featureId, boolean state)
  371. throws SAXNotRecognizedException, SAXNotSupportedException {
  372. try {
  373. fConfiguration.setFeature(featureId, state);
  374. }
  375. catch (XMLConfigurationException e) {
  376. String message = e.getMessage();
  377. if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  378. throw new SAXNotRecognizedException(message);
  379. }
  380. else {
  381. throw new SAXNotSupportedException(message);
  382. }
  383. }
  384. } // setFeature(String,boolean)
  385. /**
  386. * Query the state of a feature.
  387. *
  388. * Query the current state of any feature in a SAX2 parser. The
  389. * parser might not recognize the feature.
  390. *
  391. * @param featureId The unique identifier (URI) of the feature
  392. * being set.
  393. * @return The current state of the feature.
  394. * @exception org.xml.sax.SAXNotRecognizedException If the
  395. * requested feature is not known.
  396. * @exception SAXNotSupportedException If the
  397. * requested feature is known but not supported.
  398. */
  399. public boolean getFeature(String featureId)
  400. throws SAXNotRecognizedException, SAXNotSupportedException {
  401. try {
  402. return fConfiguration.getFeature(featureId);
  403. }
  404. catch (XMLConfigurationException e) {
  405. String message = e.getMessage();
  406. if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  407. throw new SAXNotRecognizedException(message);
  408. }
  409. else {
  410. throw new SAXNotSupportedException(message);
  411. }
  412. }
  413. } // getFeature(String):boolean
  414. /**
  415. * Set the value of any property in a SAX2 parser. The parser
  416. * might not recognize the property, and if it does recognize
  417. * it, it might not support the requested value.
  418. *
  419. * @param propertyId The unique identifier (URI) of the property
  420. * being set.
  421. * @param Object The value to which the property is being set.
  422. *
  423. * @exception SAXNotRecognizedException If the
  424. * requested property is not known.
  425. * @exception SAXNotSupportedException If the
  426. * requested property is known, but the requested
  427. * value is not supported.
  428. */
  429. public void setProperty(String propertyId, Object value)
  430. throws SAXNotRecognizedException, SAXNotSupportedException {
  431. try {
  432. fConfiguration.setProperty(propertyId, value);
  433. }
  434. catch (XMLConfigurationException e) {
  435. String message = e.getMessage();
  436. if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  437. throw new SAXNotRecognizedException(message);
  438. }
  439. else {
  440. throw new SAXNotSupportedException(message);
  441. }
  442. }
  443. } // setProperty(String,Object)
  444. /**
  445. * Query the value of a property.
  446. *
  447. * Return the current value of a property in a SAX2 parser.
  448. * The parser might not recognize the property.
  449. *
  450. * @param propertyId The unique identifier (URI) of the property
  451. * being set.
  452. * @return The current value of the property.
  453. * @exception org.xml.sax.SAXNotRecognizedException If the
  454. * requested property is not known.
  455. * @exception SAXNotSupportedException If the
  456. * requested property is known but not supported.
  457. */
  458. public Object getProperty(String propertyId)
  459. throws SAXNotRecognizedException, SAXNotSupportedException {
  460. if (propertyId.equals(CURRENT_ELEMENT_NODE)) {
  461. boolean deferred = false;
  462. try {
  463. deferred = getFeature(DEFER_NODE_EXPANSION);
  464. }
  465. catch (XMLConfigurationException e){
  466. // ignore
  467. }
  468. if (deferred) {
  469. throw new SAXNotSupportedException("Current element node cannot be queried when node expansion is deferred.");
  470. }
  471. return (fCurrentNode!=null &&
  472. fCurrentNode.getNodeType() == Node.ELEMENT_NODE)? fCurrentNode:null;
  473. }
  474. try {
  475. return fConfiguration.getProperty(propertyId);
  476. }
  477. catch (XMLConfigurationException e) {
  478. String message = e.getMessage();
  479. if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) {
  480. throw new SAXNotRecognizedException(message);
  481. }
  482. else {
  483. throw new SAXNotSupportedException(message);
  484. }
  485. }
  486. } // getProperty(String):Object
  487. } // class DOMParser