1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 2000-2003 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.impl.xs;
  58. import java.io.BufferedInputStream;
  59. import java.io.File;
  60. import java.io.FileInputStream;
  61. import java.io.FileNotFoundException;
  62. import java.io.IOException;
  63. import java.io.InputStream;
  64. import java.io.Reader;
  65. import java.io.StringReader;
  66. import java.util.Hashtable;
  67. import java.util.Locale;
  68. import java.util.StringTokenizer;
  69. import java.util.Vector;
  70. import javax.xml.transform.Source;
  71. import com.sun.org.apache.xerces.internal.dom.DOMErrorImpl;
  72. import com.sun.org.apache.xerces.internal.dom.DOMMessageFormatter;
  73. import com.sun.org.apache.xerces.internal.dom.DOMStringListImpl;
  74. import com.sun.org.apache.xerces.internal.impl.Constants;
  75. import com.sun.org.apache.xerces.internal.impl.XMLEntityManager;
  76. import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter;
  77. import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
  78. import com.sun.org.apache.xerces.internal.impl.xs.models.CMBuilder;
  79. import com.sun.org.apache.xerces.internal.impl.xs.models.CMNodeFactory;
  80. import com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler;
  81. import com.sun.org.apache.xerces.internal.util.DOMErrorHandlerWrapper;
  82. import com.sun.org.apache.xerces.internal.util.DefaultErrorHandler;
  83. import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings;
  84. import com.sun.org.apache.xerces.internal.util.SymbolTable;
  85. import com.sun.org.apache.xerces.internal.util.XMLSymbols;
  86. import com.sun.org.apache.xerces.internal.xni.XNIException;
  87. import com.sun.org.apache.xerces.internal.xni.grammars.Grammar;
  88. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription;
  89. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarLoader;
  90. import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool;
  91. import com.sun.org.apache.xerces.internal.xni.grammars.XSGrammar;
  92. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
  93. import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
  94. import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
  95. import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
  96. import com.sun.org.apache.xerces.internal.xni.parser.XMLErrorHandler;
  97. import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
  98. import com.sun.org.apache.xerces.internal.xs.LSInputList;
  99. import com.sun.org.apache.xerces.internal.xs.StringList;
  100. import com.sun.org.apache.xerces.internal.xs.XSLoader;
  101. import com.sun.org.apache.xerces.internal.xs.XSModel;
  102. import org.w3c.dom.DOMConfiguration;
  103. import org.w3c.dom.DOMError;
  104. import org.w3c.dom.DOMErrorHandler;
  105. import org.w3c.dom.DOMException;
  106. import org.w3c.dom.DOMStringList;
  107. import org.w3c.dom.ls.LSInput;
  108. import org.xml.sax.InputSource;
  109. /**
  110. * This class implements xni.grammars.XMLGrammarLoader.
  111. * It also serves as implementation of xs.XSLoader interface and DOMConfiguration interface.
  112. *
  113. * This class is designed to interact either with a proxy for a user application
  114. * which wants to preparse schemas, or with our own Schema validator.
  115. * It is hoped that none of these "external" classes will therefore need to communicate directly
  116. * with XSDHandler in future.
  117. * <p>This class only knows how to make XSDHandler do its thing.
  118. * The caller must ensure that all its properties (schemaLocation, JAXPSchemaSource
  119. * etc.) have been properly set.
  120. *
  121. * @author Neil Graham, IBM
  122. * @version $Id: XMLSchemaLoader.java,v 1.26 2004/01/29 22:26:00 mrglavas Exp $
  123. */
  124. public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent,
  125. // XML Component API
  126. XSLoader, DOMConfiguration {
  127. // Feature identifiers:
  128. /** Feature identifier: schema full checking*/
  129. protected static final String SCHEMA_FULL_CHECKING =
  130. Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING;
  131. /** Feature identifier: continue after fatal error. */
  132. protected static final String CONTINUE_AFTER_FATAL_ERROR =
  133. Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE;
  134. /** Feature identifier: allow java encodings to be recognized when parsing schema docs. */
  135. protected static final String ALLOW_JAVA_ENCODINGS =
  136. Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE;
  137. /** Feature identifier: standard uri conformant feature. */
  138. protected static final String STANDARD_URI_CONFORMANT_FEATURE =
  139. Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE;
  140. /** Feature: disallow doctype*/
  141. protected static final String DISALLOW_DOCTYPE =
  142. Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE;
  143. protected static final String AUGMENT_PSVI =
  144. Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI;
  145. protected static final String PARSER_SETTINGS =
  146. Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS;
  147. // recognized features:
  148. private static final String[] RECOGNIZED_FEATURES = {
  149. SCHEMA_FULL_CHECKING,
  150. AUGMENT_PSVI,
  151. CONTINUE_AFTER_FATAL_ERROR,
  152. ALLOW_JAVA_ENCODINGS,
  153. STANDARD_URI_CONFORMANT_FEATURE,
  154. DISALLOW_DOCTYPE
  155. };
  156. // property identifiers
  157. /** Property identifier: symbol table. */
  158. public static final String SYMBOL_TABLE =
  159. Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY;
  160. /** Property identifier: error reporter. */
  161. public static final String ERROR_REPORTER =
  162. Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY;
  163. /** Property identifier: error handler. */
  164. protected static final String ERROR_HANDLER =
  165. Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY;
  166. /** Property identifier: entity resolver. */
  167. public static final String ENTITY_RESOLVER =
  168. Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY;
  169. /** Property identifier: grammar pool. */
  170. public static final String XMLGRAMMAR_POOL =
  171. Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY;
  172. /** Property identifier: schema location. */
  173. protected static final String SCHEMA_LOCATION =
  174. Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION;
  175. /** Property identifier: no namespace schema location. */
  176. protected static final String SCHEMA_NONS_LOCATION =
  177. Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION;
  178. /** Property identifier: JAXP schema source. */
  179. protected static final String JAXP_SCHEMA_SOURCE =
  180. Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE;
  181. protected static final String SECURITY_MANAGER =
  182. Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY;
  183. protected static final String ENTITY_MANAGER =
  184. Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY;
  185. // recognized properties
  186. private static final String [] RECOGNIZED_PROPERTIES = {
  187. ENTITY_MANAGER,
  188. SYMBOL_TABLE,
  189. ERROR_REPORTER,
  190. ERROR_HANDLER,
  191. ENTITY_RESOLVER,
  192. XMLGRAMMAR_POOL,
  193. SCHEMA_LOCATION,
  194. SCHEMA_NONS_LOCATION,
  195. JAXP_SCHEMA_SOURCE,
  196. SECURITY_MANAGER
  197. };
  198. // Data
  199. // features and properties
  200. private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings();
  201. private SymbolTable fSymbolTable = null;
  202. private XMLErrorReporter fErrorReporter = new XMLErrorReporter ();
  203. private XMLEntityManager fEntityManager = null;
  204. private XMLEntityResolver fUserEntityResolver = null;
  205. private XMLGrammarPool fGrammarPool = null;
  206. private String fExternalSchemas = null;
  207. private String fExternalNoNSSchema = null;
  208. // JAXP property: schema source
  209. private Object fJAXPSource = null;
  210. // is Schema Full Checking enabled
  211. private boolean fIsCheckedFully = false;
  212. // boolean that tells whether we've tested the JAXP property.
  213. private boolean fJAXPProcessed = false;
  214. // if features/properties has not been changed, the value of this attribute is "false"
  215. private boolean fSettingsChanged = true;
  216. // xml schema parsing
  217. private XSDHandler fSchemaHandler;
  218. private XSGrammarBucket fGrammarBucket;
  219. private XSDeclarationPool fDeclPool = null;
  220. private SubstitutionGroupHandler fSubGroupHandler;
  221. private CMBuilder fCMBuilder;
  222. private XSDDescription fXSDDescription = new XSDDescription();
  223. private Hashtable fJAXPCache;
  224. private Locale fLocale = Locale.getDefault();
  225. // XSLoader attributes
  226. private DOMStringList fRecognizedParameters = null;
  227. /** DOM L3 error handler */
  228. private DOMErrorHandlerWrapper fErrorHandler = null;
  229. // default constructor. Create objects we absolutely need:
  230. public XMLSchemaLoader() {
  231. this( new SymbolTable(), null, new XMLEntityManager(), null, null, null);
  232. }
  233. public XMLSchemaLoader(SymbolTable symbolTable) {
  234. this( symbolTable, null, new XMLEntityManager(), null, null, null);
  235. }
  236. /**
  237. * This constractor is used by the XMLSchemaValidator. Additional properties, i.e. XMLEntityManager,
  238. * will be passed during reset(XMLComponentManager).
  239. * @param errorReporter
  240. * @param grammarBucket
  241. * @param sHandler
  242. * @param builder
  243. */
  244. XMLSchemaLoader(XMLErrorReporter errorReporter,
  245. XSGrammarBucket grammarBucket,
  246. SubstitutionGroupHandler sHandler, CMBuilder builder) {
  247. this(null, errorReporter, new XMLEntityManager(), grammarBucket, sHandler, builder);
  248. }
  249. XMLSchemaLoader(SymbolTable symbolTable,
  250. XMLErrorReporter errorReporter,
  251. XMLEntityManager entityResolver,
  252. XSGrammarBucket grammarBucket,
  253. SubstitutionGroupHandler sHandler,
  254. CMBuilder builder) {
  255. // store properties and features in configuration
  256. fLoaderConfig.addRecognizedFeatures(RECOGNIZED_FEATURES);
  257. fLoaderConfig.addRecognizedProperties(RECOGNIZED_PROPERTIES);
  258. if (symbolTable != null){
  259. fLoaderConfig.setProperty(SYMBOL_TABLE, symbolTable);
  260. }
  261. if(errorReporter == null) {
  262. errorReporter = new XMLErrorReporter ();
  263. errorReporter.setLocale(fLocale);
  264. errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler());
  265. }
  266. fErrorReporter = errorReporter;
  267. // make sure error reporter knows about schemas...
  268. if(fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
  269. fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
  270. }
  271. fLoaderConfig.setProperty(ERROR_REPORTER, fErrorReporter);
  272. fEntityManager = entityResolver;
  273. // entity manager is null if XMLSchemaValidator creates the loader
  274. if (fEntityManager != null){
  275. fLoaderConfig.setProperty(ENTITY_MANAGER, fEntityManager);
  276. }
  277. // by default augment PSVI (i.e. don't use declaration pool)
  278. fLoaderConfig.setFeature(AUGMENT_PSVI, true);
  279. if(grammarBucket == null ) {
  280. grammarBucket = new XSGrammarBucket();
  281. }
  282. fGrammarBucket = grammarBucket;
  283. if(sHandler == null) {
  284. sHandler = new SubstitutionGroupHandler(fGrammarBucket);
  285. }
  286. fSubGroupHandler = sHandler;
  287. //get an instance of the CMNodeFactory */
  288. CMNodeFactory nodeFactory = new CMNodeFactory() ;
  289. if(builder == null) {
  290. builder = new CMBuilder(nodeFactory);
  291. }
  292. fCMBuilder = builder;
  293. fSchemaHandler = new XSDHandler(fGrammarBucket);
  294. fDeclPool = new XSDeclarationPool();
  295. fJAXPCache = new Hashtable();
  296. fSettingsChanged = true;
  297. }
  298. /**
  299. * Returns a list of feature identifiers that are recognized by
  300. * this XMLGrammarLoader. This method may return null if no features
  301. * are recognized.
  302. */
  303. public String[] getRecognizedFeatures() {
  304. return (String[])(RECOGNIZED_FEATURES.clone());
  305. } // getRecognizedFeatures(): String[]
  306. /**
  307. * Returns the state of a feature.
  308. *
  309. * @param featureId The feature identifier.
  310. *
  311. * @throws XMLConfigurationException Thrown on configuration error.
  312. */
  313. public boolean getFeature(String featureId)
  314. throws XMLConfigurationException {
  315. return fLoaderConfig.getFeature(featureId);
  316. } // getFeature (String): boolean
  317. /**
  318. * Sets the state of a feature.
  319. *
  320. * @param featureId The feature identifier.
  321. * @param state The state of the feature.
  322. *
  323. * @throws XMLConfigurationException Thrown when a feature is not
  324. * recognized or cannot be set.
  325. */
  326. public void setFeature(String featureId,
  327. boolean state) throws XMLConfigurationException {
  328. fSettingsChanged = true;
  329. if(featureId.equals(CONTINUE_AFTER_FATAL_ERROR)) {
  330. fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, state);
  331. }
  332. fLoaderConfig.setFeature(featureId, state);
  333. } // setFeature(String, boolean)
  334. /**
  335. * Returns a list of property identifiers that are recognized by
  336. * this XMLGrammarLoader. This method may return null if no properties
  337. * are recognized.
  338. */
  339. public String[] getRecognizedProperties() {
  340. return (String[])(RECOGNIZED_PROPERTIES.clone());
  341. } // getRecognizedProperties(): String[]
  342. /**
  343. * Returns the state of a property.
  344. *
  345. * @param propertyId The property identifier.
  346. *
  347. * @throws XMLConfigurationException Thrown on configuration error.
  348. */
  349. public Object getProperty(String propertyId)
  350. throws XMLConfigurationException {
  351. return fLoaderConfig.getProperty(propertyId);
  352. } // getProperty(String): Object
  353. /**
  354. * Sets the state of a property.
  355. *
  356. * @param propertyId The property identifier.
  357. * @param state The state of the property.
  358. *
  359. * @throws XMLConfigurationException Thrown when a property is not
  360. * recognized or cannot be set.
  361. */
  362. public void setProperty(String propertyId,
  363. Object state) throws XMLConfigurationException {
  364. fSettingsChanged = true;
  365. fLoaderConfig.setProperty(propertyId, state);
  366. if(propertyId.equals( JAXP_SCHEMA_SOURCE)) {
  367. fJAXPSource = state;
  368. fJAXPProcessed = false;
  369. }
  370. else if(propertyId.equals( XMLGRAMMAR_POOL)) {
  371. fGrammarPool = (XMLGrammarPool)state;
  372. }
  373. else if (propertyId.equals(SCHEMA_LOCATION)){
  374. fExternalSchemas = (String)state;
  375. }
  376. else if (propertyId.equals(SCHEMA_NONS_LOCATION)){
  377. fExternalNoNSSchema = (String) state;
  378. }
  379. else if (propertyId.equals(ENTITY_RESOLVER)){
  380. fEntityManager.setProperty(ENTITY_RESOLVER, state);
  381. }
  382. else if (propertyId.equals(ERROR_REPORTER)){
  383. fErrorReporter = (XMLErrorReporter)state;
  384. if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) {
  385. fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter());
  386. }
  387. }
  388. } // setProperty(String, Object)
  389. /**
  390. * Set the locale to use for messages.
  391. *
  392. * @param locale The locale object to use for localization of messages.
  393. *
  394. * @exception XNIException Thrown if the parser does not support the
  395. * specified locale.
  396. */
  397. public void setLocale(Locale locale) {
  398. fLocale = locale;
  399. fErrorReporter.setLocale(locale);
  400. } // setLocale(Locale)
  401. /** Return the Locale the XMLGrammarLoader is using. */
  402. public Locale getLocale() {
  403. return fLocale;
  404. } // getLocale(): Locale
  405. /**
  406. * Sets the error handler.
  407. *
  408. * @param errorHandler The error handler.
  409. */
  410. public void setErrorHandler(XMLErrorHandler errorHandler) {
  411. fErrorReporter.setProperty(ERROR_HANDLER, errorHandler);
  412. } // setErrorHandler(XMLErrorHandler)
  413. /** Returns the registered error handler. */
  414. public XMLErrorHandler getErrorHandler() {
  415. return fErrorReporter.getErrorHandler();
  416. } // getErrorHandler(): XMLErrorHandler
  417. /**
  418. * Sets the entity resolver.
  419. *
  420. * @param entityResolver The new entity resolver.
  421. */
  422. public void setEntityResolver(XMLEntityResolver entityResolver) {
  423. fUserEntityResolver = entityResolver;
  424. fLoaderConfig.setProperty(ENTITY_RESOLVER, entityResolver);
  425. fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver);
  426. } // setEntityResolver(XMLEntityResolver)
  427. /** Returns the registered entity resolver. */
  428. public XMLEntityResolver getEntityResolver() {
  429. return fUserEntityResolver;
  430. } // getEntityResolver(): XMLEntityResolver
  431. /**
  432. * Returns a Grammar object by parsing the contents of the
  433. * entity pointed to by source.
  434. *
  435. * @param source the location of the entity which forms
  436. * the starting point of the grammar to be constructed.
  437. * @throws IOException When a problem is encountered reading the entity
  438. * XNIException When a condition arises (such as a FatalError) that requires parsing
  439. * of the entity be terminated.
  440. */
  441. public Grammar loadGrammar(XMLInputSource source) throws IOException, XNIException {
  442. return loadGrammar( source.toSource() );
  443. }
  444. public Grammar loadGrammar(Source source)
  445. throws IOException, XNIException {
  446. // REVISIT: this method should have a namespace parameter specified by
  447. // user. In this case we can easily detect if a schema asked to be loaded
  448. // is already in the local cache.
  449. reset(fLoaderConfig);
  450. fSettingsChanged = false;
  451. XSDDescription desc = new XSDDescription();
  452. desc.fContextType = XSDDescription.CONTEXT_PREPARSE;
  453. desc.setLiteralSystemId( source.getSystemId());
  454. // none of the other fields make sense for preparsing
  455. Hashtable locationPairs = new Hashtable();
  456. // Process external schema location properties.
  457. // We don't call tokenizeSchemaLocationStr here, because we also want
  458. // to check whether the values are valid URI.
  459. processExternalHints(fExternalSchemas, fExternalNoNSSchema,
  460. locationPairs, fErrorReporter);
  461. SchemaGrammar grammar = loadSchema(desc, source, locationPairs);
  462. if(grammar != null && fGrammarPool != null) {
  463. fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, fGrammarBucket.getGrammars());
  464. // NOTE: we only need to verify full checking in case the schema was not provided via JAXP
  465. // since full checking already verified for all JAXP schemas
  466. if(fIsCheckedFully && fJAXPCache.get(grammar) != grammar) {
  467. XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
  468. }
  469. }
  470. return grammar;
  471. } // loadGrammar(XMLInputSource): Grammar
  472. /**
  473. * This method is called either from XMLGrammarLoader.loadGrammar or from XMLSchemaValidator.
  474. * Note: in either case, the EntityManager (or EntityResolvers) are not going to be invoked
  475. * to resolve the location of the schema in XSDDescription
  476. * @param desc
  477. * @param source
  478. * @param locationPairs
  479. * @return An XML Schema grammar
  480. * @throws IOException
  481. * @throws XNIException
  482. */
  483. SchemaGrammar loadSchema(XSDDescription desc,
  484. Source source,
  485. Hashtable locationPairs) throws IOException, XNIException {
  486. // this should only be done once per invocation of this object;
  487. // unless application alters JAXPSource in the mean time.
  488. if(!fJAXPProcessed) {
  489. processJAXPSchemaSource(locationPairs);
  490. }
  491. SchemaGrammar grammar = fSchemaHandler.parseSchema(source, desc, locationPairs);
  492. return grammar;
  493. } // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar
  494. /** This method tries to resolve location of the given schema.
  495. * The loader stores the namespace/location pairs in a hashtable (use "" as the
  496. * namespace of absent namespace). When resolving an entity, loader first tries
  497. * to find in the hashtable whether there is a value for that namespace,
  498. * if so, pass that location value to the user-defined entity resolver.
  499. *
  500. * @param desc
  501. * @param locationPairs
  502. * @param entityResolver
  503. * @return
  504. * @throws IOException
  505. */
  506. public static XMLInputSource resolveDocument(XSDDescription desc, Hashtable locationPairs,
  507. XMLEntityResolver entityResolver) throws IOException {
  508. String loc = null;
  509. // we consider the schema location properties for import
  510. if (desc.getContextType() == XSDDescription.CONTEXT_IMPORT ||
  511. desc.fromInstance()) {
  512. // use empty string as the key for absent namespace
  513. String namespace = desc.getTargetNamespace();
  514. String ns = namespace == null ? XMLSymbols.EMPTY_STRING : namespace;
  515. // get the location hint for that namespace
  516. LocationArray tempLA = (LocationArray)locationPairs.get(ns);
  517. if(tempLA != null)
  518. loc = tempLA.getFirstLocation();
  519. }
  520. // if it's not import, or if the target namespace is not set
  521. // in the schema location properties, use location hint
  522. if (loc == null) {
  523. String[] hints = desc.getLocationHints();
  524. if (hints != null && hints.length > 0)
  525. loc = hints[0];
  526. }
  527. String expandedLoc = XMLEntityManager.expandSystemId(loc, desc.getBaseSystemId(), false);
  528. desc.setLiteralSystemId(loc);
  529. desc.setExpandedSystemId(expandedLoc);
  530. return entityResolver.resolveEntity(desc);
  531. }
  532. // add external schema locations to the location pairs
  533. public static void processExternalHints(String sl, String nsl,
  534. Hashtable locations,
  535. XMLErrorReporter er) {
  536. if (sl != null) {
  537. try {
  538. // get the attribute decl for xsi:schemaLocation
  539. // because external schema location property has the same syntax
  540. // as xsi:schemaLocation
  541. XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_SCHEMALOCATION);
  542. // validation the string value to get the list of URI's
  543. attrDecl.fType.validate(sl, null, null);
  544. if (!tokenizeSchemaLocationStr(sl, locations)) {
  545. // report warning (odd number of items)
  546. er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  547. "SchemaLocation",
  548. new Object[]{sl},
  549. XMLErrorReporter.SEVERITY_WARNING);
  550. }
  551. }
  552. catch (InvalidDatatypeValueException ex) {
  553. // report warning (not list of URI's)
  554. er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  555. ex.getKey(), ex.getArgs(),
  556. XMLErrorReporter.SEVERITY_WARNING);
  557. }
  558. }
  559. if (nsl != null) {
  560. try {
  561. // similarly for no ns schema location property
  562. XSAttributeDecl attrDecl = SchemaGrammar.SG_XSI.getGlobalAttributeDecl(SchemaSymbols.XSI_NONAMESPACESCHEMALOCATION);
  563. attrDecl.fType.validate(nsl, null, null);
  564. LocationArray la = ((LocationArray)locations.get(XMLSymbols.EMPTY_STRING));
  565. if(la == null) {
  566. la = new LocationArray();
  567. locations.put(XMLSymbols.EMPTY_STRING, la);
  568. }
  569. la.addLocation(nsl);
  570. }
  571. catch (InvalidDatatypeValueException ex) {
  572. // report warning (not a URI)
  573. er.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  574. ex.getKey(), ex.getArgs(),
  575. XMLErrorReporter.SEVERITY_WARNING);
  576. }
  577. }
  578. }
  579. // this method takes a SchemaLocation string.
  580. // If an error is encountered, false is returned;
  581. // otherwise, true is returned. In either case, locations
  582. // is augmented to include as many tokens as possible.
  583. // @param schemaStr The schemaLocation string to tokenize
  584. // @param locations Hashtable mapping namespaces to LocationArray objects holding lists of locaitons
  585. // @return true if no problems; false if string could not be tokenized
  586. public static boolean tokenizeSchemaLocationStr(String schemaStr, Hashtable locations) {
  587. if (schemaStr!= null) {
  588. StringTokenizer t = new StringTokenizer(schemaStr, " \n\t\r");
  589. String namespace, location;
  590. while (t.hasMoreTokens()) {
  591. namespace = t.nextToken ();
  592. if (!t.hasMoreTokens()) {
  593. return false; // error!
  594. }
  595. location = t.nextToken();
  596. LocationArray la = ((LocationArray)locations.get(namespace));
  597. if(la == null) {
  598. la = new LocationArray();
  599. locations.put(namespace, la);
  600. }
  601. la.addLocation(location);
  602. }
  603. }
  604. return true;
  605. } // tokenizeSchemaLocation(String, Hashtable): boolean
  606. /**
  607. * Translate the various JAXP SchemaSource property types to XNI
  608. * XMLInputSource. Valid types are: String, org.xml.sax.InputSource,
  609. * InputStream, File, or Object[] of any of previous types.
  610. * REVISIT: the JAXP 1.2 spec is less than clear as to whether this property
  611. * should be available to imported schemas. I have assumed
  612. * that it should. - NG
  613. * Note: all JAXP schema files will be checked for full-schema validity if the feature was set up
  614. *
  615. */
  616. private void processJAXPSchemaSource(Hashtable locationPairs) throws IOException {
  617. fJAXPProcessed = true;
  618. if (fJAXPSource == null) {
  619. return;
  620. }
  621. Class componentType = fJAXPSource.getClass().getComponentType();
  622. XMLInputSource xis = null;
  623. String sid = null;
  624. if (componentType == null) {
  625. // Not an array
  626. if(fJAXPSource instanceof InputStream ||
  627. fJAXPSource instanceof InputSource) {
  628. SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(fJAXPSource);
  629. if(g != null) {
  630. fGrammarBucket.putGrammar(g);
  631. return;
  632. }
  633. }
  634. fXSDDescription.reset();
  635. xis = xsdToXMLInputSource(fJAXPSource);
  636. sid = xis.getSystemId();
  637. fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
  638. if (sid != null) {
  639. fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
  640. fXSDDescription.setLiteralSystemId(sid);
  641. fXSDDescription.setExpandedSystemId(sid);
  642. fXSDDescription.fLocationHints = new String[]{sid};
  643. }
  644. SchemaGrammar g = loadSchema(fXSDDescription, xis.toSource(), locationPairs);
  645. // it is possible that we won't be able to resolve JAXP schema-source location
  646. if (g != null){
  647. if(fJAXPSource instanceof InputStream ||
  648. fJAXPSource instanceof InputSource) {
  649. fJAXPCache.put(fJAXPSource, g);
  650. if(fIsCheckedFully) {
  651. XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
  652. }
  653. }
  654. fGrammarBucket.putGrammar(g);
  655. }
  656. return ;
  657. } else if ( (componentType != Object.class) &&
  658. (componentType != String.class) &&
  659. (componentType != File.class) &&
  660. (componentType != InputStream.class) &&
  661. (componentType != InputSource.class)
  662. ) {
  663. // Not an Object[], String[], File[], InputStream[], InputSource[]
  664. throw new XMLConfigurationException(
  665. XMLConfigurationException.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
  666. "\" property cannot have an array of type {"+componentType.getName()+
  667. "}. Possible types of the array supported are Object, String, File, "+
  668. "InputStream, InputSource.");
  669. }
  670. // JAXP spec. allow []s of type String, File, InputStream,
  671. // InputSource also, apart from [] of type Object.
  672. Object[] objArr = (Object[]) fJAXPSource;
  673. //make local vector for storing targetn namespaces of schemasources specified in object arrays.
  674. Vector jaxpSchemaSourceNamespaces = new Vector() ;
  675. for (int i = 0; i < objArr.length; i++) {
  676. if(objArr[i] instanceof InputStream ||
  677. objArr[i] instanceof InputSource) {
  678. SchemaGrammar g = (SchemaGrammar)fJAXPCache.get(objArr[i]);
  679. if (g != null) {
  680. fGrammarBucket.putGrammar(g);
  681. continue;
  682. }
  683. }
  684. fXSDDescription.reset();
  685. xis = xsdToXMLInputSource(objArr[i]);
  686. sid = xis.getSystemId();
  687. fXSDDescription.fContextType = XSDDescription.CONTEXT_PREPARSE;
  688. if (sid != null) {
  689. fXSDDescription.setBaseSystemId(xis.getBaseSystemId());
  690. fXSDDescription.setLiteralSystemId(sid);
  691. fXSDDescription.setExpandedSystemId(sid);
  692. fXSDDescription.fLocationHints = new String[]{sid};
  693. }
  694. String targetNamespace = null ;
  695. // load schema
  696. SchemaGrammar grammar = fSchemaHandler.parseSchema(xis.toSource(),fXSDDescription, locationPairs);
  697. if(fIsCheckedFully) {
  698. XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter);
  699. }
  700. if(grammar != null){
  701. targetNamespace = grammar.getTargetNamespace() ;
  702. if(jaxpSchemaSourceNamespaces.contains(targetNamespace)){
  703. //when an array of objects is passed it is illegal to have two schemas that share same namespace.
  704. throw new java.lang.IllegalArgumentException(
  705. " When using array of Objects as the value of SCHEMA_SOURCE property , " +
  706. "no two Schemas should share the same targetNamespace. " );
  707. }
  708. else{
  709. jaxpSchemaSourceNamespaces.add(targetNamespace) ;
  710. }
  711. if(objArr[i] instanceof InputStream ||
  712. objArr[i] instanceof InputSource) {
  713. fJAXPCache.put(objArr[i], grammar);
  714. }
  715. fGrammarBucket.putGrammar(grammar);
  716. }
  717. else{
  718. //REVISIT: What should be the acutal behavior if grammar can't be loaded as specified in schema source?
  719. }
  720. }
  721. }//processJAXPSchemaSource
  722. private XMLInputSource xsdToXMLInputSource(
  723. Object val)
  724. {
  725. if (val instanceof String) {
  726. // String value is treated as a URI that is passed through the
  727. // EntityResolver
  728. String loc = (String) val;
  729. fXSDDescription.reset();
  730. fXSDDescription.setValues(null, loc, null, null);
  731. XMLInputSource xis = null;
  732. try {
  733. xis = fEntityManager.resolveEntity(fXSDDescription);
  734. } catch (IOException ex) {
  735. fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  736. "schema_reference.4",
  737. new Object[] { loc }, XMLErrorReporter.SEVERITY_ERROR);
  738. }
  739. if (xis == null) {
  740. // REVISIT: can this happen?
  741. // Treat value as a URI and pass in as systemId
  742. return new XMLInputSource(null, loc, null);
  743. }
  744. return xis;
  745. } else if (val instanceof InputSource) {
  746. return saxToXMLInputSource((InputSource) val);
  747. } else if (val instanceof InputStream) {
  748. return new XMLInputSource(null, null, null,
  749. (InputStream) val, null);
  750. } else if (val instanceof File) {
  751. File file = (File) val;
  752. InputStream is = null;
  753. try {
  754. is = new BufferedInputStream(new FileInputStream(file));
  755. } catch (FileNotFoundException ex) {
  756. fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  757. "schema_reference.4", new Object[] { file.toString() },
  758. XMLErrorReporter.SEVERITY_ERROR);
  759. }
  760. return new XMLInputSource(null, null, null, is, null);
  761. }
  762. throw new XMLConfigurationException(
  763. XMLConfigurationException.NOT_SUPPORTED, "\""+JAXP_SCHEMA_SOURCE+
  764. "\" property cannot have a value of type {"+val.getClass().getName()+
  765. "}. Possible types of the value supported are String, File, InputStream, "+
  766. "InputSource OR an array of these types.");
  767. }
  768. //Convert a SAX InputSource to an equivalent XNI XMLInputSource
  769. private static XMLInputSource saxToXMLInputSource(InputSource sis) {
  770. String publicId = sis.getPublicId();
  771. String systemId = sis.getSystemId();
  772. Reader charStream = sis.getCharacterStream();
  773. if (charStream != null) {
  774. return new XMLInputSource(publicId, systemId, null, charStream,
  775. null);
  776. }
  777. InputStream byteStream = sis.getByteStream();
  778. if (byteStream != null) {
  779. return new XMLInputSource(publicId, systemId, null, byteStream,
  780. sis.getEncoding());
  781. }
  782. return new XMLInputSource(publicId, systemId, null);
  783. }
  784. static class LocationArray{
  785. int length ;
  786. String [] locations = new String[2];
  787. public void resize(int oldLength , int newLength){
  788. String [] temp = new String[newLength] ;
  789. System.arraycopy(locations, 0, temp, 0, Math.min(oldLength, newLength));
  790. locations = temp ;
  791. length = Math.min(oldLength, newLength);
  792. }
  793. public void addLocation(String location){
  794. if(length >= locations.length ){
  795. resize(length, Math.max(1, length*2));
  796. }
  797. locations[length++] = location;
  798. }//setLocation()
  799. public String [] getLocationArray(){
  800. if(length < locations.length ){
  801. resize(locations.length, length);
  802. }
  803. return locations;
  804. }//getLocationArray()
  805. public String getFirstLocation(){
  806. return length > 0 ? locations[0] : null;
  807. }
  808. public int getLength(){
  809. return length ;
  810. }
  811. } //locationArray
  812. /* (non-Javadoc)
  813. * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getFeatureDefault(java.lang.String)
  814. */
  815. public Boolean getFeatureDefault(String featureId) {
  816. if (featureId.equals(AUGMENT_PSVI)){
  817. return Boolean.TRUE;
  818. }
  819. return null;
  820. }
  821. /* (non-Javadoc)
  822. * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getPropertyDefault(java.lang.String)
  823. */
  824. public Object getPropertyDefault(String propertyId) {
  825. // TODO Auto-generated method stub
  826. return null;
  827. }
  828. /* (non-Javadoc)
  829. * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#reset(com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager)
  830. */
  831. public void reset(XMLComponentManager componentManager) throws XMLConfigurationException {
  832. fGrammarBucket.reset();
  833. fSubGroupHandler.reset();
  834. // set full validation to false
  835. fIsCheckedFully = false;
  836. boolean parser_settings;
  837. try {
  838. parser_settings = componentManager.getFeature(PARSER_SETTINGS);
  839. }
  840. catch (XMLConfigurationException e){
  841. parser_settings = true;
  842. }
  843. if (!parser_settings || !fSettingsChanged){
  844. // reinitialize grammar bucket
  845. initGrammarBucket();
  846. return;
  847. }
  848. // get registered entity manager to be able to resolve JAXP schema-source property:
  849. // Note: in case XMLSchemaValidator has created the loader,
  850. // the entity manager property is null
  851. fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER);
  852. boolean psvi = true;
  853. try {
  854. psvi = componentManager.getFeature(AUGMENT_PSVI);
  855. } catch (XMLConfigurationException e) {
  856. psvi = false;
  857. }
  858. if (!psvi) {
  859. fDeclPool.reset();
  860. fCMBuilder.setDeclPool(fDeclPool);
  861. fSchemaHandler.setDeclPool(fDeclPool);
  862. } else {
  863. fCMBuilder.setDeclPool(null);
  864. fSchemaHandler.setDeclPool(null);
  865. }
  866. // get schema location properties
  867. try {
  868. fExternalSchemas = (String) componentManager.getProperty(SCHEMA_LOCATION);
  869. fExternalNoNSSchema =
  870. (String) componentManager.getProperty(SCHEMA_NONS_LOCATION);
  871. } catch (XMLConfigurationException e) {
  872. fExternalSchemas = null;
  873. fExternalNoNSSchema = null;
  874. }
  875. // get JAXP sources if available
  876. try {
  877. fJAXPSource = componentManager.getProperty(JAXP_SCHEMA_SOURCE);
  878. fJAXPProcessed = false;
  879. } catch (XMLConfigurationException e) {
  880. fJAXPSource = null;
  881. fJAXPProcessed = false;
  882. }
  883. // clear grammars, and put the one for schema namespace there
  884. try {
  885. fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL);
  886. } catch (XMLConfigurationException e) {
  887. fGrammarPool = null;
  888. }
  889. initGrammarBucket();
  890. // get continue-after-fatal-error feature
  891. try {
  892. boolean fatalError = componentManager.getFeature(CONTINUE_AFTER_FATAL_ERROR);
  893. fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, fatalError);
  894. } catch (XMLConfigurationException e) {
  895. }
  896. // set full validation to false
  897. try {
  898. fIsCheckedFully = componentManager.getFeature(SCHEMA_FULL_CHECKING);
  899. }
  900. catch (XMLConfigurationException e){
  901. fIsCheckedFully = false;
  902. }
  903. fSchemaHandler.reset(componentManager);
  904. }
  905. private void initGrammarBucket(){
  906. if(fGrammarPool != null) {
  907. Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA);
  908. for (int i = 0; i < initialGrammars.length; i++) {
  909. // put this grammar into the bucket, along with grammars
  910. // imported by it (directly or indirectly)
  911. if (!fGrammarBucket.putGrammar((SchemaGrammar)(initialGrammars[i]), true)) {
  912. // REVISIT: a conflict between new grammar(s) and grammars
  913. // in the bucket. What to do? A warning? An exception?
  914. fErrorReporter.reportError(XSMessageFormatter.SCHEMA_DOMAIN,
  915. "GrammarConflict", null,
  916. XMLErrorReporter.SEVERITY_WARNING);
  917. }
  918. }
  919. }
  920. }
  921. /* (non-Javadoc)
  922. * @see com.sun.org.apache.xerces.internal.xs.XSLoader#getConfig()
  923. */
  924. public DOMConfiguration getConfig() {
  925. return this;
  926. }
  927. /* (non-Javadoc)
  928. * @see com.sun.org.apache.xerces.internal.xs.XSLoader#load(org.w3c.dom.ls.LSInput)
  929. */
  930. public XSModel load(LSInput is) {
  931. try {
  932. Grammar g = loadGrammar(dom2xmlInputSource(is));
  933. return ((XSGrammar) g).toXSModel();
  934. } catch (Exception e) {
  935. if (fErrorHandler != null) {
  936. DOMErrorImpl error = new DOMErrorImpl();
  937. error.fException = e;
  938. error.fMessage = e.getMessage();
  939. error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
  940. fErrorHandler.getErrorHandler().handleError(error);
  941. }
  942. return null;
  943. }
  944. }
  945. /* (non-Javadoc)
  946. * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.DOMInputList)
  947. */
  948. public XSModel loadInputList(LSInputList is) {
  949. int length = is.getLength();
  950. if (length == 0) {
  951. return null;
  952. }
  953. SchemaGrammar[] gs = new SchemaGrammar[length];
  954. for (int i = 0; i < length; i++) {
  955. try {
  956. gs[i] = (SchemaGrammar) loadGrammar(dom2xmlInputSource(is.item(i)));
  957. } catch (Exception e) {
  958. if (fErrorHandler != null) {
  959. DOMErrorImpl error = new DOMErrorImpl();
  960. error.fException = e;
  961. error.fMessage = e.getMessage();
  962. error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
  963. fErrorHandler.getErrorHandler().handleError(error);
  964. }
  965. return null;
  966. }
  967. }
  968. return new XSModelImpl(gs);
  969. }
  970. /* (non-Javadoc)
  971. * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURI(java.lang.String)
  972. */
  973. public XSModel loadURI(String uri) {
  974. try {
  975. Grammar g = loadGrammar(new XMLInputSource(null, uri, null));
  976. return ((XSGrammar)g).toXSModel();
  977. }
  978. catch (Exception e){
  979. if (fErrorHandler != null) {
  980. DOMErrorImpl error = new DOMErrorImpl();
  981. error.fException = e;
  982. error.fMessage = e.getMessage();
  983. error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
  984. fErrorHandler.getErrorHandler().handleError(error);
  985. }
  986. return null;
  987. }
  988. }
  989. /* (non-Javadoc)
  990. * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURIList(com.sun.org.apache.xerces.internal.xs.StringList)
  991. */
  992. public XSModel loadURIList(StringList uriList) {
  993. int length = uriList.getLength();
  994. if (length == 0) {
  995. return null;
  996. }
  997. SchemaGrammar[] gs = new SchemaGrammar[length];
  998. for (int i = 0; i < length; i++) {
  999. try {
  1000. gs[i] =
  1001. (SchemaGrammar) loadGrammar(new XMLInputSource(null, uriList.item(i), null));
  1002. } catch (Exception e) {
  1003. if (fErrorHandler != null) {
  1004. DOMErrorImpl error = new DOMErrorImpl();
  1005. error.fException = e;
  1006. error.fMessage = e.getMessage();
  1007. error.fSeverity = DOMError.SEVERITY_FATAL_ERROR;
  1008. fErrorHandler.getErrorHandler().handleError(error);
  1009. }
  1010. return null;
  1011. }
  1012. }
  1013. return new XSModelImpl(gs);
  1014. }
  1015. /* (non-Javadoc)
  1016. * @see org.w3c.dom.DOMConfiguration#canSetParameter(java.lang.String, java.lang.Object)
  1017. */
  1018. public boolean canSetParameter(String name, Object value) {
  1019. if(value instanceof Boolean){
  1020. // boolean state = ((Boolean)value).booleanValue();
  1021. if (name.equals(Constants.DOM_VALIDATE) ||
  1022. name.equals(SCHEMA_FULL_CHECKING) ||
  1023. name.equals(CONTINUE_AFTER_FATAL_ERROR) ||
  1024. name.equals(ALLOW_JAVA_ENCODINGS) ||
  1025. name.equals(STANDARD_URI_CONFORMANT_FEATURE)){
  1026. return true;
  1027. }
  1028. return false;
  1029. }
  1030. if (name.equals(Constants.DOM_ERROR_HANDLER)||
  1031. name.equals(SYMBOL_TABLE) ||
  1032. name.equals(ERROR_REPORTER) ||
  1033. name.equals(ERROR_HANDLER) ||
  1034. name.equals(ENTITY_RESOLVER) ||
  1035. name.equals(XMLGRAMMAR_POOL) ||
  1036. name.equals(SCHEMA_LOCATION) ||
  1037. name.equals(SCHEMA_NONS_LOCATION) ||
  1038. name.equals(JAXP_SCHEMA_SOURCE)){
  1039. return true;
  1040. }
  1041. return false;
  1042. }
  1043. /* (non-Javadoc)
  1044. * @see org.w3c.dom.DOMConfiguration#getParameter(java.lang.String)
  1045. */
  1046. public Object getParameter(String name) throws DOMException {
  1047. if (name.equals(Constants.DOM_ERROR_HANDLER)){
  1048. if (fErrorHandler != null){
  1049. return fErrorHandler.getErrorHandler();
  1050. }
  1051. }
  1052. try {
  1053. boolean feature = getFeature(name);
  1054. return (feature) ? Boolean.TRUE : Boolean.FALSE;
  1055. } catch (Exception e) {
  1056. Object property;
  1057. try {
  1058. property = getProperty(name);
  1059. return property;
  1060. } catch (Exception ex) {
  1061. String msg =
  1062. DOMMessageFormatter.formatMessage(
  1063. DOMMessageFormatter.DOM_DOMAIN,
  1064. "FEATURE_NOT_SUPPORTED",
  1065. new Object[] { name });
  1066. throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
  1067. }
  1068. }
  1069. }
  1070. /* (non-Javadoc)
  1071. * @see org.w3c.dom.DOMConfiguration#getParameterNames()
  1072. */
  1073. public DOMStringList getParameterNames() {
  1074. if (fRecognizedParameters == null){
  1075. Vector v = new Vector();
  1076. v.add("validate");
  1077. v.add(SYMBOL_TABLE);
  1078. v.add(ERROR_REPORTER);
  1079. v.add(ERROR_HANDLER);
  1080. v.add(ENTITY_RESOLVER);
  1081. v.add(XMLGRAMMAR_POOL);
  1082. v.add(SCHEMA_LOCATION);
  1083. v.add(SCHEMA_NONS_LOCATION);
  1084. v.add(JAXP_SCHEMA_SOURCE);
  1085. v.add(SCHEMA_FULL_CHECKING);
  1086. v.add(CONTINUE_AFTER_FATAL_ERROR);
  1087. v.add(ALLOW_JAVA_ENCODINGS);
  1088. v.add(STANDARD_URI_CONFORMANT_FEATURE);
  1089. fRecognizedParameters = new DOMStringListImpl(v);
  1090. }
  1091. return fRecognizedParameters;
  1092. }
  1093. /* (non-Javadoc)
  1094. * @see org.w3c.dom.DOMConfiguration#setParameter(java.lang.String, java.lang.Object)
  1095. */
  1096. public void setParameter(String name, Object value) throws DOMException {
  1097. if (value instanceof Boolean) {
  1098. boolean state = ((Boolean) value).booleanValue();
  1099. if (name.equals("validate") && state) {
  1100. return;
  1101. }
  1102. try {
  1103. setFeature(name, state);
  1104. } catch (Exception e) {
  1105. String msg =
  1106. DOMMessageFormatter.formatMessage(
  1107. DOMMessageFormatter.DOM_DOMAIN,
  1108. "FEATURE_NOT_SUPPORTED",
  1109. new Object[] { name });
  1110. throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
  1111. }
  1112. return;
  1113. }
  1114. if (name.equals(Constants.DOM_ERROR_HANDLER)) {
  1115. if (value instanceof DOMErrorHandler) {
  1116. try {
  1117. fErrorHandler = new DOMErrorHandlerWrapper((DOMErrorHandler) value);
  1118. setErrorHandler(fErrorHandler);
  1119. } catch (XMLConfigurationException e) {
  1120. }
  1121. } else {
  1122. // REVISIT: type mismatch
  1123. String msg =
  1124. DOMMessageFormatter.formatMessage(
  1125. DOMMessageFormatter.DOM_DOMAIN,
  1126. "FEATURE_NOT_SUPPORTED",
  1127. new Object[] { name });
  1128. throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
  1129. }
  1130. return;
  1131. }
  1132. try {
  1133. setProperty(name, value);
  1134. } catch (Exception ex) {
  1135. String msg =
  1136. DOMMessageFormatter.formatMessage(
  1137. DOMMessageFormatter.DOM_DOMAIN,
  1138. "FEATURE_NOT_SUPPORTED",
  1139. new Object[] { name });
  1140. throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg);
  1141. }
  1142. }
  1143. private XMLInputSource dom2xmlInputSource(LSInput is) {
  1144. // need to wrap the LSInput with an XMLInputSource
  1145. XMLInputSource xis = null;
  1146. // if there is a string data, use a StringReader
  1147. // according to DOM, we need to treat such data as "UTF-16".
  1148. if (is.getStringData() != null) {
  1149. xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
  1150. is.getBaseURI(), new StringReader(is.getStringData()),
  1151. "UTF-16");
  1152. }
  1153. // check whether there is a Reader
  1154. // according to DOM, we need to treat such reader as "UTF-16".
  1155. else if (is.getCharacterStream() != null) {
  1156. xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
  1157. is.getBaseURI(), is.getCharacterStream(),
  1158. "UTF-16");
  1159. }
  1160. // check whether there is an InputStream
  1161. else if (is.getByteStream() != null) {
  1162. xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
  1163. is.getBaseURI(), is.getByteStream(),
  1164. is.getEncoding());
  1165. }
  1166. // otherwise, just use the public/system/base Ids
  1167. else {
  1168. xis = new XMLInputSource(is.getPublicId(), is.getSystemId(),
  1169. is.getBaseURI());
  1170. }
  1171. return xis;
  1172. }
  1173. } // XMLGrammarLoader