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 com.sun.org.apache.xerces.internal.impl.Constants;
  60. import com.sun.org.apache.xerces.internal.impl.dtd.DTDGrammar;
  61. import com.sun.org.apache.xerces.internal.impl.dtd.XMLDTDLoader;
  62. import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar;
  63. import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader;
  64. import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter;
  65. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  66. import com.sun.org.apache.xerces.internal.util.SynchronizedSymbolTable;
  67. import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl;
  68. import com.sun.org.apache.xerces.internal.xni.XNIException;
  69. import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  70. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  71. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  72. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  73. import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  74. import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  75. import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  76. /**
  77. * <p> This configuration provides a generic way of using
  78. * Xerces's grammar caching facilities. It extends the
  79. * XML11Configuration and thus may validate documents
  80. * according to XML schemas or DTD's. It also allows the user to
  81. * preparse a grammar, and to lock the grammar pool
  82. * implementation such that no more grammars will be added.</p>
  83. * <p> Using the com.sun.org.apache.xerces.internal.xni.parser property, an
  84. * application may instantiate a Xerces SAX or DOM parser with
  85. * this configuration. When invoked in this manner, the default
  86. * behaviour will be elicited; to use this configuration's
  87. * specific facilities, the user will need to reference it
  88. * directly.</p>
  89. * <p>
  90. * In addition to the features and properties recognized by the base
  91. * parser configuration, this class recognizes these additional
  92. * features and properties:
  93. * <ul>
  94. * </ul>
  95. *
  96. * @author Neil Graham, IBM
  97. *
  98. * @version $Id: XMLGrammarCachingConfiguration.java,v 1.15 2004/02/18 22:18:31 mrglavas Exp $
  99. */
  100. public class XMLGrammarCachingConfiguration
  101. extends XML11Configuration {
  102. //
  103. // Constants
  104. //
  105. // a larg(ish) prime to use for a symbol table to be shared
  106. // among
  107. // potentially man parsers. Start one as close to 2K (20
  108. // times larger than normal) and see what happens...
  109. public static final int BIG_PRIME = 2039;
  110. // the static symbol table to be shared amongst parsers
  111. protected static final SynchronizedSymbolTable fStaticSymbolTable =
  112. new SynchronizedSymbolTable(BIG_PRIME);
  113. // the Grammar Pool to be shared similarly
  114. protected static final XMLGrammarPoolImpl fStaticGrammarPool =
  115. new XMLGrammarPoolImpl();
  116. // schema full checking constant
  117. protected static final String SCHEMA_FULL_CHECKING =
  118. Constants.XERCES_FEATURE_PREFIX+Constants.SCHEMA_FULL_CHECKING;
  119. // Data
  120. // variables needed for caching schema grammars.
  121. protected XMLSchemaLoader fSchemaLoader;
  122. // the DTD grammar loader
  123. protected XMLDTDLoader fDTDLoader;
  124. //
  125. // Constructors
  126. //
  127. /** Default constructor. */
  128. public XMLGrammarCachingConfiguration() {
  129. this(fStaticSymbolTable, fStaticGrammarPool, null);
  130. } // <init>()
  131. /**
  132. * Constructs a parser configuration using the specified symbol table.
  133. *
  134. * @param symbolTable The symbol table to use.
  135. */
  136. public XMLGrammarCachingConfiguration(SymbolTable symbolTable) {
  137. this(symbolTable, fStaticGrammarPool, null);
  138. } // <init>(SymbolTable)
  139. /**
  140. * Constructs a parser configuration using the specified symbol table and
  141. * grammar pool.
  142. * <p>
  143. * <strong>REVISIT:</strong>
  144. * Grammar pool will be updated when the new validation engine is
  145. * implemented.
  146. *
  147. * @param symbolTable The symbol table to use.
  148. * @param grammarPool The grammar pool to use.
  149. */
  150. public XMLGrammarCachingConfiguration(SymbolTable symbolTable,
  151. XMLGrammarPool grammarPool) {
  152. this(symbolTable, grammarPool, null);
  153. } // <init>(SymbolTable,XMLGrammarPool)
  154. /**
  155. * Constructs a parser configuration using the specified symbol table,
  156. * grammar pool, and parent settings.
  157. * <p>
  158. * <strong>REVISIT:</strong>
  159. * Grammar pool will be updated when the new validation engine is
  160. * implemented.
  161. *
  162. * @param symbolTable The symbol table to use.
  163. * @param grammarPool The grammar pool to use.
  164. * @param parentSettings The parent settings.
  165. */
  166. public XMLGrammarCachingConfiguration(SymbolTable symbolTable,
  167. XMLGrammarPool grammarPool,
  168. XMLComponentManager parentSettings) {
  169. super(symbolTable, grammarPool, parentSettings);
  170. // REVISIT: may need to add some features/properties
  171. // specific to this configuration at some point...
  172. // add default recognized features
  173. // set state for default features
  174. // add default recognized properties
  175. // create and register missing components
  176. fSchemaLoader = new XMLSchemaLoader(fSymbolTable);
  177. fSchemaLoader.setProperty(XMLGRAMMAR_POOL, fGrammarPool);
  178. // and set up the DTD loader too:
  179. fDTDLoader = new XMLDTDLoader(fSymbolTable, fGrammarPool);
  180. } // <init>(SymbolTable,XMLGrammarPool, XMLComponentManager)
  181. //
  182. // Public methods
  183. //
  184. /*
  185. * lock the XMLGrammarPoolImpl object so that it does not
  186. * accept any more grammars from the validators.
  187. */
  188. public void lockGrammarPool() {
  189. fGrammarPool.lockPool();
  190. } // lockGrammarPool()
  191. /*
  192. * clear the XMLGrammarPoolImpl object so that it does not
  193. * contain any more grammars.
  194. */
  195. public void clearGrammarPool() {
  196. fGrammarPool.clear();
  197. } // clearGrammarPool()
  198. /*
  199. * unlock the XMLGrammarPoolImpl object so that it
  200. * accepts more grammars from the validators.
  201. */
  202. public void unlockGrammarPool() {
  203. fGrammarPool.unlockPool();
  204. } // unlockGrammarPool()
  205. /**
  206. * Parse a grammar from a location identified by an URI.
  207. * This method also adds this grammar to the XMLGrammarPool
  208. *
  209. * @param type The type of the grammar to be constructed
  210. * @param uri The location of the grammar to be constructed.
  211. * <strong>The parser will not expand this URI or make it
  212. * available to the EntityResolver</strong>
  213. * @return The newly created <code>Grammar</code>.
  214. * @exception XNIException thrown on an error in grammar
  215. * construction
  216. * @exception IOException thrown if an error is encountered
  217. * in reading the file
  218. */
  219. public Grammar parseGrammar(String type, String uri)
  220. throws XNIException, IOException {
  221. XMLInputSource source = new XMLInputSource(null, uri, null);
  222. return parseGrammar(type, source);
  223. }
  224. /**
  225. * Parse a grammar from a location identified by an
  226. * XMLInputSource.
  227. * This method also adds this grammar to the XMLGrammarPool
  228. *
  229. * @param type The type of the grammar to be constructed
  230. * @param source The XMLInputSource containing this grammar's
  231. * information
  232. * <strong>If a URI is included in the systemId field, the parser will not expand this URI or make it
  233. * available to the EntityResolver</strong>
  234. * @return The newly created <code>Grammar</code>.
  235. * @exception XNIException thrown on an error in grammar
  236. * construction
  237. * @exception IOException thrown if an error is encountered
  238. * in reading the file
  239. */
  240. public Grammar parseGrammar(String type, XMLInputSource
  241. is) throws XNIException, IOException {
  242. if(type.equals(XMLGrammarDescription.XML_SCHEMA)) {
  243. // by default, make all XMLGrammarPoolImpl's schema grammars available to fSchemaHandler
  244. return parseXMLSchema(is);
  245. } else if(type.equals(XMLGrammarDescription.XML_DTD)) {
  246. return parseDTD(is);
  247. }
  248. // don't know this grammar...
  249. return null;
  250. } // parseGrammar(String, XMLInputSource): Grammar
  251. //
  252. // Protected methods
  253. //
  254. // features and properties
  255. /**
  256. * Check a feature. If feature is known and supported, this method simply
  257. * returns. Otherwise, the appropriate exception is thrown.
  258. *
  259. * @param featureId The unique identifier (URI) of the feature.
  260. *
  261. * @throws XMLConfigurationException Thrown for configuration error.
  262. * In general, components should
  263. * only throw this exception if
  264. * it is <strong>really</strong>
  265. * a critical error.
  266. */
  267. protected void checkFeature(String featureId)
  268. throws XMLConfigurationException {
  269. super.checkFeature(featureId);
  270. } // checkFeature(String)
  271. /**
  272. * Check a property. If the property is known and supported, this method
  273. * simply returns. Otherwise, the appropriate exception is thrown.
  274. *
  275. * @param propertyId The unique identifier (URI) of the property
  276. * being set.
  277. *
  278. * @throws XMLConfigurationException Thrown for configuration error.
  279. * In general, components should
  280. * only throw this exception if
  281. * it is <strong>really</strong>
  282. * a critical error.
  283. */
  284. protected void checkProperty(String propertyId)
  285. throws XMLConfigurationException {
  286. super.checkProperty(propertyId);
  287. } // checkProperty(String)
  288. // package-protected methods
  289. /* This method parses an XML Schema document.
  290. * It requires a GrammarBucket parameter so that DOMASBuilder can
  291. * extract the info it needs.
  292. * Therefore, bucket must not be null!
  293. */
  294. SchemaGrammar parseXMLSchema(XMLInputSource is)
  295. throws IOException {
  296. XMLEntityResolver resolver = getEntityResolver();
  297. if(resolver != null) {
  298. fSchemaLoader.setEntityResolver(resolver);
  299. }
  300. if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
  301. fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
  302. }
  303. fSchemaLoader.setProperty(ERROR_REPORTER, fErrorReporter);
  304. String propPrefix = Constants.XERCES_PROPERTY_PREFIX;
  305. String propName = propPrefix + Constants.SCHEMA_LOCATION;
  306. fSchemaLoader.setProperty(propName, getProperty(propName));
  307. propName = propPrefix + Constants.SCHEMA_NONS_LOCATION;
  308. fSchemaLoader.setProperty(propName, getProperty(propName));
  309. propName = Constants.JAXP_PROPERTY_PREFIX+Constants.SCHEMA_SOURCE;
  310. fSchemaLoader.setProperty(propName, getProperty(propName));
  311. fSchemaLoader.setFeature(SCHEMA_FULL_CHECKING, getFeature(SCHEMA_FULL_CHECKING));
  312. // Should check whether the grammar with this namespace is already in
  313. // the grammar resolver. But since we don't know the target namespace
  314. // of the document here, we leave such check to XSDHandler
  315. SchemaGrammar grammar = (SchemaGrammar)fSchemaLoader.loadGrammar(is);
  316. // by default, hand it off to the grammar pool
  317. if (grammar != null) {
  318. fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA,
  319. new Grammar[]{grammar});
  320. }
  321. return grammar;
  322. } // parseXMLSchema(XMLInputSource) : SchemaGrammar
  323. /* This method parses an external DTD entity.
  324. */
  325. DTDGrammar parseDTD(XMLInputSource is)
  326. throws IOException {
  327. XMLEntityResolver resolver = getEntityResolver();
  328. if(resolver != null) {
  329. fDTDLoader.setEntityResolver(resolver);
  330. }
  331. fDTDLoader.setProperty(ERROR_REPORTER, fErrorReporter);
  332. // Should check whether the grammar with this namespace is already in
  333. // the grammar resolver. But since we don't know the target namespace
  334. // of the document here, we leave such check to the application...
  335. DTDGrammar grammar = (DTDGrammar)fDTDLoader.loadGrammar(is);
  336. // by default, hand it off to the grammar pool
  337. if (grammar != null) {
  338. fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD,
  339. new Grammar[]{grammar});
  340. }
  341. return grammar;
  342. } // parseXMLDTD(XMLInputSource) : DTDGrammar
  343. } // class XMLGrammarCachingConfiguration