1 23 24 package org.enhydra.xml.xmlc.parsers.xerces; 25 26 import java.io.IOException ; 27 28 import org.enhydra.apache.xerces.framework.XMLAttrList; 29 import org.enhydra.apache.xerces.framework.XMLContentSpec; 30 import org.enhydra.apache.xerces.framework.XMLDocumentHandler; 31 import org.enhydra.apache.xerces.framework.XMLParser; 32 import org.enhydra.apache.xerces.readers.XMLEntityHandler; 33 import org.enhydra.apache.xerces.utils.QName; 34 import org.enhydra.apache.xerces.validators.common.XMLAttributeDecl; 35 import org.enhydra.xml.io.ErrorReporter; 36 import org.enhydra.xml.io.XMLEntityResolver; 37 import org.enhydra.xml.xmlc.XMLCError; 38 import org.enhydra.xml.xmlc.XMLCException; 39 import org.enhydra.xml.xmlc.dom.XMLCDocument; 40 import org.enhydra.xml.xmlc.dom.XMLCDomFactory; 41 import org.enhydra.xml.xmlc.metadata.MetaData; 42 import org.enhydra.xml.xmlc.metadata.Parser; 43 import org.enhydra.xml.xmlc.misc.LineNumberMap; 44 import org.enhydra.xml.xmlc.parsers.DocBuilder; 45 import org.enhydra.xml.xmlc.parsers.ParseTracer; 46 import org.enhydra.xml.xmlc.parsers.XMLCParser; 47 import org.xml.sax.EntityResolver ; 48 import org.xml.sax.ErrorHandler ; 49 import org.xml.sax.InputSource ; 50 import org.xml.sax.SAXException ; 51 import org.xml.sax.SAXParseException ; 52 53 65 66 69 public class XercesParser extends XMLParser 70 implements XMLCParser, EntityResolver, 71 XMLDocumentHandler, XMLDocumentHandler.DTDHandler { 72 73 76 private class MappingErrorHandler implements ErrorHandler { 77 private ErrorReporter fErrorReporter; 78 private LineNumberMap fLineNumberMap; 79 80 83 public MappingErrorHandler(ErrorReporter errorReporter, 84 LineNumberMap lineNumberMap) { 85 fErrorReporter = errorReporter; 86 fLineNumberMap = lineNumberMap; 87 } 88 89 94 private SAXParseException mapException(SAXParseException exception) { 95 if (fLineNumberMap == null) { 96 return exception; 97 } else { 98 LineNumberMap.Line line 99 = fLineNumberMap.getLineFromLineNum(exception.getLineNumber()); 100 return new SAXParseException (exception.getMessage(), 101 exception.getPublicId(), 102 line.getFileName(), 103 line.getLineNum(), 104 exception.getColumnNumber(), 105 exception); 106 } 107 } 108 109 112 public void error(SAXParseException exception) throws SAXException { 113 fErrorReporter.error(mapException(exception)); 114 } 115 116 119 public void warning(SAXParseException exception) throws SAXException { 120 fErrorReporter.warning(mapException(exception)); 121 } 122 123 126 public void fatalError(SAXParseException exception) throws SAXException { 127 fErrorReporter.fatalError(mapException(exception)); 128 } 129 } 130 131 134 private XercesTracer fTracer; 135 136 139 private DocBuilder fDocBuilder; 140 141 144 private boolean fProcessingCDATASection = false; 145 146 149 private static final int PROCESSING_DOCUMENT = 0; 150 151 154 private static final int PROCESSING_EXTERNAL_SUBSET = 1; 155 156 159 private static final int PROCESSING_INTERNAL_SUBSET = 2; 160 161 164 private int fProcessingState; 165 166 169 private XMLEntityResolver fResolver; 170 171 174 private int fAmpIndex; 175 private int fLtIndex; 176 private int fGtIndex; 177 private int fAposIndex; 178 private int fQuotIndex; 179 180 181 184 public XMLCDocument parse(InputSource input, 185 LineNumberMap lineNumberMap, 186 XMLCDomFactory domFactory, 187 MetaData metaData, 188 ErrorReporter errorReporter, 189 ParseTracer tracer) 190 throws IOException , XMLCException, SAXException { 191 192 Parser parser = metaData.getParser(); 193 fTracer = new XercesTracer(fStringPool, tracer); 194 fDocBuilder = new DocBuilder(domFactory); 195 196 fProcessingState = PROCESSING_DOCUMENT; 197 198 initCharEntity(); 200 initHandlers(true, this, this); 201 setEntityResolver(this); 202 if (lineNumberMap != null) { 203 setErrorHandler(new MappingErrorHandler(errorReporter, 204 lineNumberMap)); 205 } else { 206 setErrorHandler(errorReporter); 207 } 208 setAllowJavaEncodings(true); 209 setNamespaces(true); 210 211 Boolean validate = parser.getValidate(); 212 setValidation((validate == null) ? true : validate.booleanValue()); 213 214 fResolver = new XMLEntityResolver(); 216 if (tracer.enabled()) { 217 fResolver.setDebugWriter(tracer); 218 } 219 fResolver.setDefaultResolving(); 221 222 String [] xCatalog = parser.getXCatalogURLs(); 223 for (int idx = 0; idx < xCatalog.length; idx++) { 224 fResolver.loadCatalog(new InputSource (xCatalog[idx])); 225 } 226 227 super.parse(input); 228 fDocBuilder.finish(); 229 230 return fDocBuilder.getDocument(); 231 232 } 233 234 237 private String getString(int index) { 238 return fStringPool.toString(index); 239 } 240 241 244 private void initCharEntity() { 245 fAmpIndex = fStringPool.addSymbol("amp"); 246 fLtIndex = fStringPool.addSymbol("lt"); 247 fGtIndex = fStringPool.addSymbol("gt"); 248 fAposIndex = fStringPool.addSymbol("apos"); 249 fQuotIndex = fStringPool.addSymbol("quot"); 250 } 251 252 256 boolean isCharEntity(int entityName) { 257 return ((entityName == fAmpIndex) || 258 (entityName == fGtIndex) || 259 (entityName == fLtIndex) || 260 (entityName == fAposIndex) || 261 (entityName == fQuotIndex)); 262 } 263 264 268 public InputSource resolveEntity(String publicId, 269 String systemId) 270 throws SAXException , IOException { 271 272 InputSource source = null; 273 if (fResolver != null) { 274 source = fResolver.resolveEntity(publicId, systemId); 275 } 276 fTracer.resolveEntity(publicId, systemId, source); 277 return source; 278 } 279 280 284 public void startDocument() throws Exception { 285 fTracer.startDocument(); 286 } 287 288 292 public void endDocument() throws Exception { 293 fTracer.endDocument(); 294 } 295 296 299 public void xmlDecl(int version, int encoding, int standalone) throws Exception { 300 fTracer.xmlDecl(version, encoding, standalone); 301 fDocBuilder.setXMLVersion(getString(version)); 302 fDocBuilder.setEncoding(getString(encoding)); 303 } 304 305 309 public void textDecl(int version, int encoding) throws Exception { 310 fTracer.textDecl(version, encoding); 311 } 312 313 318 public void startNamespaceDeclScope(int prefix, 319 int uri) throws Exception { 320 fTracer.startNamespaceDeclScope(prefix, uri); 321 } 323 324 329 public void endNamespaceDeclScope(int prefix) throws Exception { 330 fTracer.endNamespaceDeclScope(prefix); 331 } 332 333 337 public void startElement(QName element, 338 XMLAttrList attrList, 339 int attrListHandle) throws Exception { 340 fTracer.startElement(element, attrList, attrListHandle); 341 fDocBuilder.startElement(getString(element.uri), 342 getString(element.rawname)); 343 344 int attrIndex = attrListHandle; 345 while (attrIndex >= 0) { 346 if (attrList.isSpecified(attrIndex)) { 347 fDocBuilder.addAttribute(getString(attrList.getAttrURI(attrIndex)), 348 getString(attrList.getAttrName(attrIndex)), 349 getString(attrList.getAttValue(attrIndex))); 350 } 351 attrIndex = attrList.getNextAttr(attrIndex); 352 } 353 } 354 355 359 public void endElement(QName element) throws Exception { 360 fTracer.endElement(element); 361 fDocBuilder.finishElement(); 362 } 363 364 371 private boolean shouldProcessEntityReference(int entityName, 372 int entityContext) { 373 return ((entityName >= 0) && (fProcessingState == PROCESSING_DOCUMENT) 374 && (entityContext != XMLEntityHandler.ENTITYREF_IN_ATTVALUE)); 375 } 376 377 384 public void startEntityReference(int entityName, 385 int entityType, 386 int entityContext) throws Exception { 387 boolean shouldProcess 388 = shouldProcessEntityReference(entityName, entityContext); 389 fTracer.startEntityReference(entityName, entityType, entityContext, 390 shouldProcess); 391 if (shouldProcess && !isCharEntity(entityName)) { 392 fDocBuilder.startEntityReference(getString(entityName)); 393 } 394 } 395 396 400 public void endEntityReference(int entityName, 401 int entityType, 402 int entityContext) throws Exception { 403 boolean shouldProcess 404 = shouldProcessEntityReference(entityName, entityContext); 405 fTracer.endEntityReference(entityName, entityType, entityContext, shouldProcess); 406 407 if (shouldProcess && !isCharEntity(entityName)) { 408 fDocBuilder.endEntityReference(); 409 } 410 } 411 412 416 public void characters(int data) throws Exception { 417 throw new XMLCError("fatal error: method that should not be invoked called"); 418 } 419 420 424 public void ignorableWhitespace(int data) throws Exception { 425 throw new XMLCError("fatal error: method that should not be invoked called"); 426 } 427 428 432 public void startCDATA() { 433 fTracer.startCDATA(); 434 fProcessingCDATASection = true; 435 } 436 437 441 public void endCDATA() { 442 fTracer.endCDATA(); 443 fProcessingCDATASection = false; 444 } 445 446 451 public void processingInstruction(int target, 452 int data) throws Exception { 453 fTracer.processingInstruction(target, data); 454 if (fProcessingState == PROCESSING_DOCUMENT) { 455 fDocBuilder.addProcessingInstruction(getString(target), 456 getString(data)); 457 } 458 } 459 460 464 public void comment(int comment) throws Exception { 465 fTracer.comment(comment); 466 if (fProcessingState == PROCESSING_DOCUMENT) { 467 fDocBuilder.addComment(getString(comment)); 468 } 469 } 470 471 475 public void characters(char ch[], 476 int start, 477 int length) throws Exception { 478 fTracer.characters(ch, start, length); 479 if (fProcessingCDATASection) { 480 fDocBuilder.addCDATASection(new String (ch, start, length)); 481 } else { 482 fDocBuilder.addTextNode(new String (ch, start, length)); 483 } 484 } 485 486 490 public void ignorableWhitespace(char ch[], 491 int start, 492 int length) throws Exception { 493 fTracer.ignorableWhitespace(ch, start, length); 494 } 496 497 500 public void startDTD(QName rootElement, 501 int publicId, 502 int systemId) { 503 fTracer.startDTD(rootElement, publicId, systemId); 504 if ((publicId < 0) && (systemId < 0)) { 505 fProcessingState = PROCESSING_INTERNAL_SUBSET; 506 } else { 507 fProcessingState = PROCESSING_EXTERNAL_SUBSET; 508 } 509 fDocBuilder.setDocumentTypeName(getString(rootElement.rawname)); 510 fDocBuilder.setPublicId(getString(publicId)); 511 fDocBuilder.setSystemId(getString(systemId)); 512 } 513 514 517 public void internalSubset(int internalSubset) { 518 fTracer.internalSubset(internalSubset); 519 fDocBuilder.setInternalSubset(getString(internalSubset)); 520 } 521 522 525 public void endDTD() { 526 fTracer.endDTD(); 527 fProcessingState = PROCESSING_DOCUMENT; 528 } 529 530 534 private boolean searchForPCData(int contentSpecIndex, 535 XMLContentSpec.Provider provider, 536 XMLContentSpec contentSpec) { 537 if (!provider.getContentSpec(contentSpecIndex, contentSpec)) { 538 return false; 539 } 540 int value = contentSpec.value; 541 int otherValue = contentSpec.otherValue; 542 543 switch (contentSpec.type) { 544 case XMLContentSpec.CONTENTSPECNODE_LEAF: 545 if ((value == -1) && (otherValue == -1)) { 546 return true; } 548 break; 549 case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE: 550 case XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE: 551 case XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE: 552 if (searchForPCData(value, provider, contentSpec)) { 554 return true; } 556 break; 557 case XMLContentSpec.CONTENTSPECNODE_CHOICE: 558 case XMLContentSpec.CONTENTSPECNODE_SEQ: 559 if (searchForPCData(value, provider, contentSpec)) { 561 return true; } 563 if (searchForPCData(otherValue, provider, contentSpec)) { 564 return true; } 566 break; 567 case XMLContentSpec.CONTENTSPECNODE_ANY: 568 case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER: 569 case XMLContentSpec.CONTENTSPECNODE_ANY_NS: 570 case XMLContentSpec.CONTENTSPECNODE_ALL: 571 case XMLContentSpec.CONTENTSPECNODE_ANY_LAX: 572 case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_LAX: 573 case XMLContentSpec.CONTENTSPECNODE_ANY_NS_LAX: 574 case XMLContentSpec.CONTENTSPECNODE_ANY_SKIP: 575 case XMLContentSpec.CONTENTSPECNODE_ANY_OTHER_SKIP: 576 case XMLContentSpec.CONTENTSPECNODE_ANY_NS_SKIP: 577 default: 578 break; 580 } 581 return false; 582 } 583 584 588 private boolean hasPCData(int contentSpecIndex, 589 XMLContentSpec.Provider contentSpecProvider) { 590 return searchForPCData(contentSpecIndex, contentSpecProvider, 591 new XMLContentSpec()); 592 } 593 594 599 public void elementDecl(QName elementDecl, 600 int contentSpecType, 601 int contentSpecIndex, 602 XMLContentSpec.Provider contentSpecProvider) throws Exception { 603 fTracer.elementDecl(elementDecl, contentSpecType, contentSpecIndex, 604 contentSpecProvider); 605 if (hasPCData(contentSpecIndex, contentSpecProvider)) { 606 fDocBuilder.addPCDataContentElement(getString(elementDecl.rawname)); 607 } 608 } 609 610 615 public void attlistDecl(QName elementDecl, 616 QName attributeDecl, 617 int attType, 618 boolean attList, 619 String enumString, 620 int attDefaultType, 621 int attDefaultValue) throws Exception { 622 fTracer.attlistDecl(elementDecl, attributeDecl, attType, attList, 623 enumString, attDefaultType, attDefaultValue); 624 625 if (attType == XMLAttributeDecl.TYPE_ID) { 626 fDocBuilder.addIdAttribute(getString(elementDecl.localpart), 627 getString(attributeDecl.localpart)); 628 } 629 } 630 631 636 public void internalPEDecl(int entityName, 637 int entityValue) { 638 fTracer.internalPEDecl(entityName, entityValue); 639 } 640 641 646 public void externalPEDecl(int entityName, 647 int publicId, 648 int systemId) { 649 fTracer.externalPEDecl(entityName, publicId, systemId); 650 } 651 652 657 public void internalEntityDecl(int entityName, 658 int entityValue) { 659 fTracer.internalEntityDecl(entityName, entityValue); 660 } 661 662 667 public void externalEntityDecl(int entityName, 668 int publicId, 669 int systemId) { 670 fTracer.externalEntityDecl(entityName, publicId, systemId); 671 } 672 673 678 public void unparsedEntityDecl(int entityName, 679 int publicId, 680 int systemId, 681 int notationName) { 682 fTracer.unparsedEntityDecl(entityName, publicId, 683 systemId, notationName); 684 } 685 686 691 public void notationDecl(int notationName, 692 int publicId, 693 int systemId) { 694 fTracer.notationDecl(notationName, publicId, systemId); 695 } 696 } 697 | Popular Tags |