1 /* 2 * reserved comment block 3 * DO NOT REMOVE OR ALTER! 4 */ 5 /* 6 * Copyright 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.jaxp.validation; 22 23 import java.io.IOException; 24 import java.io.InputStream; 25 import java.io.Reader; 26 import java.io.StringReader; 27 import java.util.HashMap; 28 29 import javax.xml.XMLConstants; 30 import javax.xml.parsers.FactoryConfigurationError; 31 import javax.xml.parsers.SAXParserFactory; 32 import javax.xml.transform.Result; 33 import javax.xml.transform.Source; 34 import javax.xml.transform.sax.SAXResult; 35 import javax.xml.transform.sax.SAXSource; 36 import javax.xml.validation.TypeInfoProvider; 37 import javax.xml.validation.ValidatorHandler; 38 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.XSSimpleType; 43 import com.sun.org.apache.xerces.internal.impl.validation.EntityState; 44 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 45 import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; 46 import com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl; 47 import com.sun.org.apache.xerces.internal.util.AttributesProxy; 48 import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper; 49 import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; 50 import com.sun.org.apache.xerces.internal.util.Status; 51 import com.sun.org.apache.xerces.internal.util.SymbolTable; 52 import com.sun.org.apache.xerces.internal.util.SecurityManager; 53 import com.sun.org.apache.xerces.internal.util.URI; 54 import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; 55 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 56 import com.sun.org.apache.xerces.internal.xni.Augmentations; 57 import com.sun.org.apache.xerces.internal.xni.NamespaceContext; 58 import com.sun.org.apache.xerces.internal.xni.QName; 59 import com.sun.org.apache.xerces.internal.xni.XMLAttributes; 60 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; 61 import com.sun.org.apache.xerces.internal.xni.XMLLocator; 62 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 63 import com.sun.org.apache.xerces.internal.xni.XMLString; 64 import com.sun.org.apache.xerces.internal.xni.XNIException; 65 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 66 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource; 67 import com.sun.org.apache.xerces.internal.xni.parser.XMLParseException; 68 import com.sun.org.apache.xerces.internal.xs.AttributePSVI; 69 import com.sun.org.apache.xerces.internal.xs.ElementPSVI; 70 import com.sun.org.apache.xerces.internal.xs.ItemPSVI; 71 import com.sun.org.apache.xerces.internal.xs.PSVIProvider; 72 import com.sun.org.apache.xerces.internal.xs.XSTypeDefinition; 73 import org.w3c.dom.TypeInfo; 74 import org.w3c.dom.ls.LSInput; 75 import org.w3c.dom.ls.LSResourceResolver; 76 import org.xml.sax.Attributes; 77 import org.xml.sax.ContentHandler; 78 import org.xml.sax.DTDHandler; 79 import org.xml.sax.ErrorHandler; 80 import org.xml.sax.InputSource; 81 import org.xml.sax.Locator; 82 import org.xml.sax.SAXException; 83 import org.xml.sax.SAXNotRecognizedException; 84 import org.xml.sax.SAXNotSupportedException; 85 import org.xml.sax.XMLReader; 86 import org.xml.sax.ext.Attributes2; 87 import org.xml.sax.ext.EntityResolver2; 88 89 /** 90 * <p>Implementation of ValidatorHandler for W3C XML Schemas and 91 * also a validator helper for <code>SAXSource</code>s.</p> 92 * 93 * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) 94 * @author Michael Glavassevich, IBM 95 * 96 * @version $Id: ValidatorHandlerImpl.java,v 1.10 2010-11-01 04:40:08 joehw Exp $ 97 */ 98 final class ValidatorHandlerImpl extends ValidatorHandler implements 99 DTDHandler, EntityState, PSVIProvider, ValidatorHelper, XMLDocumentHandler { 100 101 // feature identifiers 102 103 /** Feature identifier: namespace prefixes. */ 104 private static final String NAMESPACE_PREFIXES = 105 Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACE_PREFIXES_FEATURE; 106 107 /** Feature identifier: string interning. */ 108 protected static final String STRING_INTERNING = 109 Constants.SAX_FEATURE_PREFIX + Constants.STRING_INTERNING_FEATURE; 110 111 // property identifiers 112 113 /** Property identifier: error reporter. */ 114 private static final String ERROR_REPORTER = 115 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 116 117 /** Property identifier: namespace context. */ 118 private static final String NAMESPACE_CONTEXT = 119 Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_CONTEXT_PROPERTY; 120 121 /** Property identifier: XML Schema validator. */ 122 private static final String SCHEMA_VALIDATOR = 123 Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; 124 125 /** Property identifier: security manager. */ 126 private static final String SECURITY_MANAGER = 127 Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; 128 129 /** Property identifier: symbol table. */ 130 private static final String SYMBOL_TABLE = 131 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 132 133 /** Property identifier: validation manager. */ 134 private static final String VALIDATION_MANAGER = 135 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 136 137 // 138 // Data 139 // 140 141 /** Error reporter. */ 142 private XMLErrorReporter fErrorReporter; 143 144 /** The namespace context of this document: stores namespaces in scope */ 145 private NamespaceContext fNamespaceContext; 146 147 /** Schema validator. **/ 148 private XMLSchemaValidator fSchemaValidator; 149 150 /** Symbol table **/ 151 private SymbolTable fSymbolTable; 152 153 /** Validation manager. */ 154 private ValidationManager fValidationManager; 155 156 /** Component manager. **/ 157 private XMLSchemaValidatorComponentManager fComponentManager; 158 159 /** XML Locator wrapper for SAX. **/ 160 private final SAXLocatorWrapper fSAXLocatorWrapper = new SAXLocatorWrapper(); 161 162 /** Flag used to track whether the namespace context needs to be pushed. */ 163 private boolean fNeedPushNSContext = true; 164 165 /** Map for tracking unparsed entities. */ 166 private HashMap fUnparsedEntities = null; 167 168 /** Flag used to track whether XML names and Namespace URIs have been internalized. */ 169 private boolean fStringsInternalized = false; 170 171 /** Fields for start element, end element and characters. */ 172 private final QName fElementQName = new QName(); 173 private final QName fAttributeQName = new QName(); 174 private final XMLAttributesImpl fAttributes = new XMLAttributesImpl(); 175 private final AttributesProxy fAttrAdapter = new AttributesProxy(fAttributes); 176 private final XMLString fTempString = new XMLString(); 177 178 // 179 // User Objects 180 // 181 182 private ContentHandler fContentHandler = null; 183 184 /* 185 * Constructors 186 */ 187 188 public ValidatorHandlerImpl(XSGrammarPoolContainer grammarContainer) { 189 this(new XMLSchemaValidatorComponentManager(grammarContainer)); 190 fComponentManager.addRecognizedFeatures(new String [] {NAMESPACE_PREFIXES}); 191 fComponentManager.setFeature(NAMESPACE_PREFIXES, false); 192 setErrorHandler(null); 193 setResourceResolver(null); 194 } 195 196 public ValidatorHandlerImpl(XMLSchemaValidatorComponentManager componentManager) { 197 fComponentManager = componentManager; 198 fErrorReporter = (XMLErrorReporter) fComponentManager.getProperty(ERROR_REPORTER); 199 fNamespaceContext = (NamespaceContext) fComponentManager.getProperty(NAMESPACE_CONTEXT); 200 fSchemaValidator = (XMLSchemaValidator) fComponentManager.getProperty(SCHEMA_VALIDATOR); 201 fSymbolTable = (SymbolTable) fComponentManager.getProperty(SYMBOL_TABLE); 202 fValidationManager = (ValidationManager) fComponentManager.getProperty(VALIDATION_MANAGER); 203 } 204 205 /* 206 * ValidatorHandler methods 207 */ 208 209 public void setContentHandler(ContentHandler receiver) { 210 fContentHandler = receiver; 211 } 212 213 public ContentHandler getContentHandler() { 214 return fContentHandler; 215 } 216 217 public void setErrorHandler(ErrorHandler errorHandler) { 218 fComponentManager.setErrorHandler(errorHandler); 219 } 220 221 public ErrorHandler getErrorHandler() { 222 return fComponentManager.getErrorHandler(); 223 } 224 225 public void setResourceResolver(LSResourceResolver resourceResolver) { 226 fComponentManager.setResourceResolver(resourceResolver); 227 } 228 229 public LSResourceResolver getResourceResolver() { 230 return fComponentManager.getResourceResolver(); 231 } 232 233 public TypeInfoProvider getTypeInfoProvider() { 234 return fTypeInfoProvider; 235 } 236 237 public boolean getFeature(String name) 238 throws SAXNotRecognizedException, SAXNotSupportedException { 239 if (name == null) { 240 throw new NullPointerException(); 241 } 242 try { 243 return fComponentManager.getFeature(name); 244 } 245 catch (XMLConfigurationException e) { 246 final String identifier = e.getIdentifier(); 247 final String key = e.getType() == Status.NOT_RECOGNIZED ? 248 "feature-not-recognized" : "feature-not-supported"; 249 throw new SAXNotRecognizedException( 250 SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), 251 key, new Object [] {identifier})); 252 } 253 } 254 255 public void setFeature(String name, boolean value) 256 throws SAXNotRecognizedException, SAXNotSupportedException { 257 if (name == null) { 258 throw new NullPointerException(); 259 } 260 try { 261 fComponentManager.setFeature(name, value); 262 } 263 catch (XMLConfigurationException e) { 264 final String identifier = e.getIdentifier(); 265 final String key; 266 if (e.getType() == Status.NOT_ALLOWED) { 267 //for now, the identifier can only be (XMLConstants.FEATURE_SECURE_PROCESSING) 268 throw new SAXNotSupportedException( 269 SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), 270 "jaxp-secureprocessing-feature", null)); 271 } else if (e.getType() == Status.NOT_RECOGNIZED) { 272 key = "feature-not-recognized"; 273 } else { 274 key = "feature-not-supported"; 275 } 276 throw new SAXNotRecognizedException( 277 SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), 278 key, new Object [] {identifier})); 279 } 280 } 281 282 public Object getProperty(String name) 283 throws SAXNotRecognizedException, SAXNotSupportedException { 284 if (name == null) { 285 throw new NullPointerException(); 286 } 287 try { 288 return fComponentManager.getProperty(name); 289 } 290 catch (XMLConfigurationException e) { 291 final String identifier = e.getIdentifier(); 292 final String key = e.getType() == Status.NOT_RECOGNIZED ? 293 "property-not-recognized" : "property-not-supported"; 294 throw new SAXNotRecognizedException( 295 SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), 296 key, new Object [] {identifier})); 297 } 298 } 299 300 public void setProperty(String name, Object object) 301 throws SAXNotRecognizedException, SAXNotSupportedException { 302 if (name == null) { 303 throw new NullPointerException(); 304 } 305 try { 306 fComponentManager.setProperty(name, object); 307 } 308 catch (XMLConfigurationException e) { 309 final String identifier = e.getIdentifier(); 310 final String key = e.getType() == Status.NOT_RECOGNIZED ? 311 "property-not-recognized" : "property-not-supported"; 312 throw new SAXNotRecognizedException( 313 SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), 314 key, new Object [] {identifier})); 315 } 316 } 317 318 /* 319 * EntityState methods 320 */ 321 322 public boolean isEntityDeclared(String name) { 323 return false; 324 } 325 326 public boolean isEntityUnparsed(String name) { 327 if (fUnparsedEntities != null) { 328 return fUnparsedEntities.containsKey(name); 329 } 330 return false; 331 } 332 333 /* 334 * XMLDocumentHandler methods 335 */ 336 337 public void startDocument(XMLLocator locator, String encoding, 338 NamespaceContext namespaceContext, Augmentations augs) 339 throws XNIException { 340 if (fContentHandler != null) { 341 try { 342 fContentHandler.startDocument(); 343 } 344 catch (SAXException e) { 345 throw new XNIException(e); 346 } 347 } 348 } 349 350 public void xmlDecl(String version, String encoding, String standalone, 351 Augmentations augs) throws XNIException {} 352 353 public void doctypeDecl(String rootElement, String publicId, 354 String systemId, Augmentations augs) throws XNIException {} 355 356 public void comment(XMLString text, Augmentations augs) throws XNIException {} 357 358 public void processingInstruction(String target, XMLString data, 359 Augmentations augs) throws XNIException { 360 if (fContentHandler != null) { 361 try { 362 fContentHandler.processingInstruction(target, data.toString()); 363 } 364 catch (SAXException e) { 365 throw new XNIException(e); 366 } 367 } 368 } 369 370 public void startElement(QName element, XMLAttributes attributes, 371 Augmentations augs) throws XNIException { 372 if (fContentHandler != null) { 373 try { 374 fTypeInfoProvider.beginStartElement(augs, attributes); 375 fContentHandler.startElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING, 376 element.localpart, element.rawname, fAttrAdapter); 377 } 378 catch (SAXException e) { 379 throw new XNIException(e); 380 } 381 finally { 382 fTypeInfoProvider.finishStartElement(); 383 } 384 } 385 } 386 387 public void emptyElement(QName element, XMLAttributes attributes, 388 Augmentations augs) throws XNIException { 389 /** Split empty element event. **/ 390 startElement(element, attributes, augs); 391 endElement(element, augs); 392 } 393 394 public void startGeneralEntity(String name, 395 XMLResourceIdentifier identifier, String encoding, 396 Augmentations augs) throws XNIException {} 397 398 public void textDecl(String version, String encoding, Augmentations augs) 399 throws XNIException {} 400 401 public void endGeneralEntity(String name, Augmentations augs) 402 throws XNIException {} 403 404 public void characters(XMLString text, Augmentations augs) 405 throws XNIException { 406 if (fContentHandler != null) { 407 // if the type is union it is possible that we receive 408 // a character call with empty data 409 if (text.length == 0) { 410 return; 411 } 412 try { 413 fContentHandler.characters(text.ch, text.offset, text.length); 414 } 415 catch (SAXException e) { 416 throw new XNIException(e); 417 } 418 } 419 } 420 421 public void ignorableWhitespace(XMLString text, Augmentations augs) 422 throws XNIException { 423 if (fContentHandler != null) { 424 try { 425 fContentHandler.ignorableWhitespace(text.ch, text.offset, text.length); 426 } 427 catch (SAXException e) { 428 throw new XNIException(e); 429 } 430 } 431 } 432 433 public void endElement(QName element, Augmentations augs) 434 throws XNIException { 435 if (fContentHandler != null) { 436 try { 437 fTypeInfoProvider.beginEndElement(augs); 438 fContentHandler.endElement((element.uri != null) ? element.uri : XMLSymbols.EMPTY_STRING, 439 element.localpart, element.rawname); 440 } 441 catch (SAXException e) { 442 throw new XNIException(e); 443 } 444 finally { 445 fTypeInfoProvider.finishEndElement(); 446 } 447 } 448 } 449 450 public void startCDATA(Augmentations augs) throws XNIException {} 451 452 public void endCDATA(Augmentations augs) throws XNIException {} 453 454 public void endDocument(Augmentations augs) throws XNIException { 455 if (fContentHandler != null) { 456 try { 457 fContentHandler.endDocument(); 458 } 459 catch (SAXException e) { 460 throw new XNIException(e); 461 } 462 } 463 } 464 465 // NO-OP 466 public void setDocumentSource(XMLDocumentSource source) {} 467 468 public XMLDocumentSource getDocumentSource() { 469 return fSchemaValidator; 470 } 471 472 /* 473 * ContentHandler methods 474 */ 475 476 public void setDocumentLocator(Locator locator) { 477 fSAXLocatorWrapper.setLocator(locator); 478 if (fContentHandler != null) { 479 fContentHandler.setDocumentLocator(locator); 480 } 481 } 482 483 public void startDocument() throws SAXException { 484 fComponentManager.reset(); 485 fSchemaValidator.setDocumentHandler(this); 486 fValidationManager.setEntityState(this); 487 fTypeInfoProvider.finishStartElement(); // cleans up TypeInfoProvider 488 fNeedPushNSContext = true; 489 if (fUnparsedEntities != null && !fUnparsedEntities.isEmpty()) { 490 // should only clear this if the last document contained unparsed entities 491 fUnparsedEntities.clear(); 492 } 493 fErrorReporter.setDocumentLocator(fSAXLocatorWrapper); 494 try { 495 fSchemaValidator.startDocument(fSAXLocatorWrapper, fSAXLocatorWrapper.getEncoding(), fNamespaceContext, null); 496 } 497 catch (XMLParseException e) { 498 throw Util.toSAXParseException(e); 499 } 500 catch (XNIException e) { 501 throw Util.toSAXException(e); 502 } 503 } 504 505 public void endDocument() throws SAXException { 506 fSAXLocatorWrapper.setLocator(null); 507 try { 508 fSchemaValidator.endDocument(null); 509 } 510 catch (XMLParseException e) { 511 throw Util.toSAXParseException(e); 512 } 513 catch (XNIException e) { 514 throw Util.toSAXException(e); 515 } 516 } 517 518 public void startPrefixMapping(String prefix, String uri) 519 throws SAXException { 520 String prefixSymbol; 521 String uriSymbol; 522 if (!fStringsInternalized) { 523 prefixSymbol = (prefix != null) ? fSymbolTable.addSymbol(prefix) : XMLSymbols.EMPTY_STRING; 524 uriSymbol = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null; 525 } 526 else { 527 prefixSymbol = (prefix != null) ? prefix : XMLSymbols.EMPTY_STRING; 528 uriSymbol = (uri != null && uri.length() > 0) ? uri : null; 529 } 530 if (fNeedPushNSContext) { 531 fNeedPushNSContext = false; 532 fNamespaceContext.pushContext(); 533 } 534 fNamespaceContext.declarePrefix(prefixSymbol, uriSymbol); 535 if (fContentHandler != null) { 536 fContentHandler.startPrefixMapping(prefix, uri); 537 } 538 } 539 540 public void endPrefixMapping(String prefix) throws SAXException { 541 if (fContentHandler != null) { 542 fContentHandler.endPrefixMapping(prefix); 543 } 544 } 545 546 public void startElement(String uri, String localName, String qName, 547 Attributes atts) throws SAXException { 548 if (fNeedPushNSContext) { 549 fNamespaceContext.pushContext(); 550 } 551 fNeedPushNSContext = true; 552 553 // Fill element QName 554 fillQName(fElementQName, uri, localName, qName); 555 556 // Fill XMLAttributes 557 if (atts instanceof Attributes2) { 558 fillXMLAttributes2((Attributes2) atts); 559 } 560 else { 561 fillXMLAttributes(atts); 562 } 563 564 try { 565 fSchemaValidator.startElement(fElementQName, fAttributes, null); 566 } 567 catch (XMLParseException e) { 568 throw Util.toSAXParseException(e); 569 } 570 catch (XNIException e) { 571 throw Util.toSAXException(e); 572 } 573 } 574 575 public void endElement(String uri, String localName, String qName) 576 throws SAXException { 577 fillQName(fElementQName, uri, localName, qName); 578 try { 579 fSchemaValidator.endElement(fElementQName, null); 580 } 581 catch (XMLParseException e) { 582 throw Util.toSAXParseException(e); 583 } 584 catch (XNIException e) { 585 throw Util.toSAXException(e); 586 } 587 finally { 588 fNamespaceContext.popContext(); 589 } 590 } 591 592 public void characters(char[] ch, int start, int length) 593 throws SAXException { 594 try { 595 fTempString.setValues(ch, start, length); 596 fSchemaValidator.characters(fTempString, null); 597 } 598 catch (XMLParseException e) { 599 throw Util.toSAXParseException(e); 600 } 601 catch (XNIException e) { 602 throw Util.toSAXException(e); 603 } 604 } 605 606 public void ignorableWhitespace(char[] ch, int start, int length) 607 throws SAXException { 608 try { 609 fTempString.setValues(ch, start, length); 610 fSchemaValidator.ignorableWhitespace(fTempString, null); 611 } 612 catch (XMLParseException e) { 613 throw Util.toSAXParseException(e); 614 } 615 catch (XNIException e) { 616 throw Util.toSAXException(e); 617 } 618 } 619 620 public void processingInstruction(String target, String data) 621 throws SAXException { 622 /** 623 * Processing instructions do not participate in schema validation, 624 * so just forward the event to the application's content 625 * handler. 626 */ 627 if (fContentHandler != null) { 628 fContentHandler.processingInstruction(target, data); 629 } 630 } 631 632 public void skippedEntity(String name) throws SAXException { 633 // there seems to be no corresponding method on XMLDocumentFilter. 634 // just pass it down to the output, if any. 635 if (fContentHandler != null) { 636 fContentHandler.skippedEntity(name); 637 } 638 } 639 640 /* 641 * DTDHandler methods 642 */ 643 644 public void notationDecl(String name, String publicId, 645 String systemId) throws SAXException {} 646 647 public void unparsedEntityDecl(String name, String publicId, 648 String systemId, String notationName) throws SAXException { 649 if (fUnparsedEntities == null) { 650 fUnparsedEntities = new HashMap(); 651 } 652 fUnparsedEntities.put(name, name); 653 } 654 655 /* 656 * ValidatorHelper methods 657 */ 658 659 public void validate(Source source, Result result) 660 throws SAXException, IOException { 661 if (result instanceof SAXResult || result == null) { 662 final SAXSource saxSource = (SAXSource) source; 663 final SAXResult saxResult = (SAXResult) result; 664 665 if (result != null) { 666 setContentHandler(saxResult.getHandler()); 667 } 668 669 try { 670 XMLReader reader = saxSource.getXMLReader(); 671 if( reader==null ) { 672 // create one now 673 SAXParserFactory spf = fComponentManager.getFeature(Constants.ORACLE_FEATURE_SERVICE_MECHANISM) ? 674 SAXParserFactory.newInstance() : new SAXParserFactoryImpl(); 675 spf.setNamespaceAware(true); 676 try { 677 reader = spf.newSAXParser().getXMLReader(); 678 // If this is a Xerces SAX parser, set the security manager if there is one 679 if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { 680 SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); 681 if (securityManager != null) { 682 try { 683 reader.setProperty(SECURITY_MANAGER, securityManager); 684 } 685 // Ignore the exception if the security manager cannot be set. 686 catch (SAXException exc) {} 687 } 688 try { 689 reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, 690 fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); 691 } catch (SAXException exc) { 692 System.err.println("Warning: " + reader.getClass().getName() + ": " + 693 exc.getMessage()); 694 } 695 } 696 } catch( Exception e ) { 697 // this is impossible, but better safe than sorry 698 throw new FactoryConfigurationError(e); 699 } 700 } 701 702 // If XML names and Namespace URIs are already internalized we 703 // can avoid running them through the SymbolTable. 704 try { 705 fStringsInternalized = reader.getFeature(STRING_INTERNING); 706 } 707 catch (SAXException exc) { 708 // The feature isn't recognized or getting it is not supported. 709 // In either case, assume that strings are not internalized. 710 fStringsInternalized = false; 711 } 712 713 ErrorHandler errorHandler = fComponentManager.getErrorHandler(); 714 reader.setErrorHandler(errorHandler != null ? errorHandler : DraconianErrorHandler.getInstance()); 715 reader.setEntityResolver(fResolutionForwarder); 716 fResolutionForwarder.setEntityResolver(fComponentManager.getResourceResolver()); 717 reader.setContentHandler(this); 718 reader.setDTDHandler(this); 719 720 InputSource is = saxSource.getInputSource(); 721 reader.parse(is); 722 } 723 finally { 724 // release the reference to user's handler ASAP 725 setContentHandler(null); 726 } 727 return; 728 } 729 throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), 730 "SourceResultMismatch", 731 new Object [] {source.getClass().getName(), result.getClass().getName()})); 732 } 733 734 /* 735 * PSVIProvider methods 736 */ 737 738 public ElementPSVI getElementPSVI() { 739 return fTypeInfoProvider.getElementPSVI(); 740 } 741 742 public AttributePSVI getAttributePSVI(int index) { 743 return fTypeInfoProvider.getAttributePSVI(index); 744 } 745 746 public AttributePSVI getAttributePSVIByName(String uri, String localname) { 747 return fTypeInfoProvider.getAttributePSVIByName(uri, localname); 748 } 749 750 // 751 // 752 // helper methods 753 // 754 // 755 756 /** Fills in a QName object. */ 757 private void fillQName(QName toFill, String uri, String localpart, String raw) { 758 if (!fStringsInternalized) { 759 uri = (uri != null && uri.length() > 0) ? fSymbolTable.addSymbol(uri) : null; 760 localpart = (localpart != null) ? fSymbolTable.addSymbol(localpart) : XMLSymbols.EMPTY_STRING; 761 raw = (raw != null) ? fSymbolTable.addSymbol(raw) : XMLSymbols.EMPTY_STRING; 762 } 763 else { 764 if (uri != null && uri.length() == 0) { 765 uri = null; 766 } 767 if (localpart == null) { 768 localpart = XMLSymbols.EMPTY_STRING; 769 } 770 if (raw == null) { 771 raw = XMLSymbols.EMPTY_STRING; 772 } 773 } 774 String prefix = XMLSymbols.EMPTY_STRING; 775 int prefixIdx = raw.indexOf(':'); 776 if (prefixIdx != -1) { 777 prefix = fSymbolTable.addSymbol(raw.substring(0, prefixIdx)); 778 } 779 toFill.setValues(prefix, localpart, raw, uri); 780 } 781 782 /** Fills in the XMLAttributes object. */ 783 private void fillXMLAttributes(Attributes att) { 784 fAttributes.removeAllAttributes(); 785 final int len = att.getLength(); 786 for (int i = 0; i < len; ++i) { 787 fillXMLAttribute(att, i); 788 fAttributes.setSpecified(i, true); 789 } 790 } 791 792 /** Fills in the XMLAttributes object. */ 793 private void fillXMLAttributes2(Attributes2 att) { 794 fAttributes.removeAllAttributes(); 795 final int len = att.getLength(); 796 for (int i = 0; i < len; ++i) { 797 fillXMLAttribute(att, i); 798 fAttributes.setSpecified(i, att.isSpecified(i)); 799 if (att.isDeclared(i)) { 800 fAttributes.getAugmentations(i).putItem(Constants.ATTRIBUTE_DECLARED, Boolean.TRUE); 801 } 802 } 803 } 804 805 /** Adds an attribute to the XMLAttributes object. */ 806 private void fillXMLAttribute(Attributes att, int index) { 807 fillQName(fAttributeQName, att.getURI(index), att.getLocalName(index), att.getQName(index)); 808 String type = att.getType(index); 809 fAttributes.addAttributeNS(fAttributeQName, (type != null) ? type : XMLSymbols.fCDATASymbol, att.getValue(index)); 810 } 811 812 /** 813 * {@link TypeInfoProvider} implementation. 814 * 815 * REVISIT: I'm not sure if this code should belong here. 816 */ 817 private final XMLSchemaTypeInfoProvider fTypeInfoProvider = new XMLSchemaTypeInfoProvider(); 818 private class XMLSchemaTypeInfoProvider extends TypeInfoProvider { 819 820 /** Element augmentations: contains ElementPSVI. **/ 821 private Augmentations fElementAugs; 822 823 /** Attributes: augmentations for each attribute contain AttributePSVI. **/ 824 private XMLAttributes fAttributes; 825 826 /** In start element. **/ 827 private boolean fInStartElement = false; 828 829 /** In end element. **/ 830 private boolean fInEndElement = false; 831 832 /** Initializes the TypeInfoProvider with type information for the current element. **/ 833 void beginStartElement(Augmentations elementAugs, XMLAttributes attributes) { 834 fInStartElement = true; 835 fElementAugs = elementAugs; 836 fAttributes = attributes; 837 } 838 839 /** Cleanup at the end of start element. **/ 840 void finishStartElement() { 841 fInStartElement = false; 842 fElementAugs = null; 843 fAttributes = null; 844 } 845 846 /** Initializes the TypeInfoProvider with type information for the current element. **/ 847 void beginEndElement(Augmentations elementAugs) { 848 fInEndElement = true; 849 fElementAugs = elementAugs; 850 } 851 852 /** Cleanup at the end of end element. **/ 853 void finishEndElement() { 854 fInEndElement = false; 855 fElementAugs = null; 856 } 857 858 /** 859 * Throws a {@link IllegalStateException} if we are not in 860 * the startElement callback. the JAXP API requires this 861 * for most of the public methods. 862 */ 863 private void checkState(boolean forElementInfo) { 864 if (! (fInStartElement || (fInEndElement && forElementInfo))) { 865 throw new IllegalStateException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), 866 "TypeInfoProviderIllegalState", null)); 867 } 868 } 869 870 public TypeInfo getAttributeTypeInfo(int index) { 871 checkState(false); 872 return getAttributeType(index); 873 } 874 875 private TypeInfo getAttributeType( int index ) { 876 checkState(false); 877 if( index<0 || fAttributes.getLength()<=index ) 878 throw new IndexOutOfBoundsException(Integer.toString(index)); 879 Augmentations augs = fAttributes.getAugmentations(index); 880 if (augs == null) return null; 881 AttributePSVI psvi = (AttributePSVI)augs.getItem(Constants.ATTRIBUTE_PSVI); 882 return getTypeInfoFromPSVI(psvi); 883 } 884 885 public TypeInfo getAttributeTypeInfo(String attributeUri, String attributeLocalName) { 886 checkState(false); 887 return getAttributeTypeInfo(fAttributes.getIndex(attributeUri,attributeLocalName)); 888 } 889 890 public TypeInfo getAttributeTypeInfo(String attributeQName) { 891 checkState(false); 892 return getAttributeTypeInfo(fAttributes.getIndex(attributeQName)); 893 } 894 895 public TypeInfo getElementTypeInfo() { 896 checkState(true); 897 if (fElementAugs == null) return null; 898 ElementPSVI psvi = (ElementPSVI)fElementAugs.getItem(Constants.ELEMENT_PSVI); 899 return getTypeInfoFromPSVI(psvi); 900 } 901 902 private TypeInfo getTypeInfoFromPSVI( ItemPSVI psvi ) { 903 if(psvi==null) return null; 904 905 // TODO: make sure if this is correct. 906 // TODO: since the number of types in a schema is quite limited, 907 // TypeInfoImpl should be pooled. Even better, it should be a part 908 // of the element decl. 909 if( psvi.getValidity()== ElementPSVI.VALIDITY_VALID ) { 910 XSTypeDefinition t = psvi.getMemberTypeDefinition(); 911 if (t != null) { 912 return (t instanceof TypeInfo) ? (TypeInfo) t : null; 913 } 914 } 915 916 XSTypeDefinition t = psvi.getTypeDefinition(); 917 // TODO: can t be null? 918 if (t != null) { 919 return (t instanceof TypeInfo) ? (TypeInfo) t : null; 920 } 921 return null; 922 } 923 924 public boolean isIdAttribute(int index) { 925 checkState(false); 926 XSSimpleType type = (XSSimpleType)getAttributeType(index); 927 if(type==null) return false; 928 return type.isIDType(); 929 } 930 931 public boolean isSpecified(int index) { 932 checkState(false); 933 return fAttributes.isSpecified(index); 934 } 935 936 /* 937 * Other methods 938 */ 939 940 // PSVIProvider support 941 ElementPSVI getElementPSVI() { 942 return (fElementAugs != null) ? (ElementPSVI) fElementAugs.getItem(Constants.ELEMENT_PSVI) : null; 943 } 944 945 AttributePSVI getAttributePSVI(int index) { 946 if (fAttributes != null) { 947 Augmentations augs = fAttributes.getAugmentations(index); 948 if (augs != null) { 949 return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI); 950 } 951 } 952 return null; 953 } 954 955 AttributePSVI getAttributePSVIByName(String uri, String localname) { 956 if (fAttributes != null) { 957 Augmentations augs = fAttributes.getAugmentations(uri, localname); 958 if (augs != null) { 959 return (AttributePSVI) augs.getItem(Constants.ATTRIBUTE_PSVI); 960 } 961 } 962 return null; 963 } 964 } 965 966 /** SAX adapter for an LSResourceResolver. */ 967 private final ResolutionForwarder fResolutionForwarder = new ResolutionForwarder(null); 968 static final class ResolutionForwarder 969 implements EntityResolver2 { 970 971 // 972 // Data 973 // 974 975 /** XML 1.0 type constant according to DOM L3 LS REC spec "http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/" */ 976 private static final String XML_TYPE = "http://www.w3.org/TR/REC-xml"; 977 978 /** The DOM entity resolver. */ 979 protected LSResourceResolver fEntityResolver; 980 981 // 982 // Constructors 983 // 984 985 /** Default constructor. */ 986 public ResolutionForwarder() {} 987 988 /** Wraps the specified DOM entity resolver. */ 989 public ResolutionForwarder(LSResourceResolver entityResolver) { 990 setEntityResolver(entityResolver); 991 } 992 993 // 994 // Public methods 995 // 996 997 /** Sets the DOM entity resolver. */ 998 public void setEntityResolver(LSResourceResolver entityResolver) { 999 fEntityResolver = entityResolver; 1000 } // setEntityResolver(LSResourceResolver) 1001 1002 /** Returns the DOM entity resolver. */ 1003 public LSResourceResolver getEntityResolver() { 1004 return fEntityResolver; 1005 } // getEntityResolver():LSResourceResolver 1006 1007 /** 1008 * Always returns <code>null</code>. An LSResourceResolver has no corresponding method. 1009 */ 1010 public InputSource getExternalSubset(String name, String baseURI) 1011 throws SAXException, IOException { 1012 return null; 1013 } 1014 1015 /** 1016 * Resolves the given resource and adapts the <code>LSInput</code> 1017 * returned into an <code>InputSource</code>. 1018 */ 1019 public InputSource resolveEntity(String name, String publicId, 1020 String baseURI, String systemId) throws SAXException, IOException { 1021 if (fEntityResolver != null) { 1022 LSInput lsInput = fEntityResolver.resolveResource(XML_TYPE, null, publicId, systemId, baseURI); 1023 if (lsInput != null) { 1024 final String pubId = lsInput.getPublicId(); 1025 final String sysId = lsInput.getSystemId(); 1026 final String baseSystemId = lsInput.getBaseURI(); 1027 final Reader charStream = lsInput.getCharacterStream(); 1028 final InputStream byteStream = lsInput.getByteStream(); 1029 final String data = lsInput.getStringData(); 1030 final String encoding = lsInput.getEncoding(); 1031 1032 /** 1033 * An LSParser looks at inputs specified in LSInput in 1034 * the following order: characterStream, byteStream, 1035 * stringData, systemId, publicId. For consistency 1036 * with the DOM Level 3 Load and Save Recommendation 1037 * use the same lookup order here. 1038 */ 1039 InputSource inputSource = new InputSource(); 1040 inputSource.setPublicId(pubId); 1041 inputSource.setSystemId((baseSystemId != null) ? resolveSystemId(systemId, baseSystemId) : systemId); 1042 1043 if (charStream != null) { 1044 inputSource.setCharacterStream(charStream); 1045 } 1046 else if (byteStream != null) { 1047 inputSource.setByteStream(byteStream); 1048 } 1049 else if (data != null && data.length() != 0) { 1050 inputSource.setCharacterStream(new StringReader(data)); 1051 } 1052 inputSource.setEncoding(encoding); 1053 return inputSource; 1054 } 1055 } 1056 return null; 1057 } 1058 1059 /** Delegates to EntityResolver2.resolveEntity(String, String, String, String). */ 1060 public InputSource resolveEntity(String publicId, String systemId) 1061 throws SAXException, IOException { 1062 return resolveEntity(null, publicId, null, systemId); 1063 } 1064 1065 /** Resolves a system identifier against a base URI. */ 1066 private String resolveSystemId(String systemId, String baseURI) { 1067 try { 1068 return XMLEntityManager.expandSystemId(systemId, baseURI, false); 1069 } 1070 // In the event that resolution failed against the 1071 // base URI, just return the system id as is. There's not 1072 // much else we can do. 1073 catch (URI.MalformedURIException ex) { 1074 return systemId; 1075 } 1076 } 1077 } 1078 }