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