| 1 57 58 package org.enhydra.apache.xerces.readers; 59 60 import java.io.FileNotFoundException ; 61 import java.io.UnsupportedEncodingException ; 62 import java.net.MalformedURLException ; 63 import java.util.Stack ; 64 import java.util.Vector ; 65 66 import org.enhydra.apache.xerces.framework.XMLErrorReporter; 67 import org.enhydra.apache.xerces.utils.ImplementationMessages; 68 import org.enhydra.apache.xerces.utils.QName; 69 import org.enhydra.apache.xerces.utils.StringPool; 70 import org.enhydra.apache.xerces.utils.URI; 71 import org.enhydra.apache.xerces.utils.XMLCharacterProperties; 72 import org.enhydra.apache.xerces.utils.XMLMessages; 73 import org.xml.sax.EntityResolver ; 74 import org.xml.sax.InputSource ; 75 import org.xml.sax.Locator ; 76 import org.xml.sax.helpers.LocatorImpl ; 77 78 83 public class DefaultEntityHandler 84 implements XMLEntityHandler, XMLEntityHandler.DTDHandler { 85 86 public interface EventHandler { 87 public void startEntityReference(int entityName, int entityType, int entityContext) throws Exception ; 88 public void endEntityReference(int entityName, int entityType, int entityContext) throws Exception ; 89 public void sendEndOfInputNotifications(int entityName, boolean moreToFollow) throws Exception ; 90 public void sendReaderChangeNotifications(XMLEntityHandler.EntityReader reader, int readerId) throws Exception ; 91 public boolean externalEntityStandaloneCheck(); 92 public boolean getValidating(); 93 } 94 95 private class ReaderState { 99 XMLEntityHandler.EntityReader reader; 100 InputSource source; 101 int entityName; 102 int entityType; 103 int entityContext; 104 String publicId; 105 String systemId; 106 int readerId; 107 int depth; 108 ReaderState nextReaderState; 109 } 110 private ReaderState fReaderStateFreeList = null; 111 private StringPool fStringPool = null; 112 private EventHandler fEventHandler = null; 113 private XMLEntityHandler.CharDataHandler fCharDataHandler = null; 114 private XMLErrorReporter fErrorReporter = null; 115 private EntityResolver fResolver = null; 116 private EntityPool fEntityPool = null; 117 private EntityPool fParameterEntityPool = null; 118 private byte[] fEntityTypeStack = null; 119 private int[] fEntityNameStack = null; 120 private int fEntityStackDepth = 0; 121 private Stack fReaderStack = new Stack (); 122 private XMLEntityHandler.EntityReader fReader = null; 123 private InputSource fSource = null; 124 private int fEntityName = -1; 125 private int fEntityType = -1; 126 private int fEntityContext = -1; 127 private String fPublicId = null; 128 private String fSystemId = null; 129 private int fReaderId = -1; 130 private int fReaderDepth = -1; 131 private int fNextReaderId = 0; 132 private NullReader fNullReader = null; 133 protected XMLEntityReaderFactory fReaderFactory = null; 134 private boolean fSendCharDataAsCharArray = false; 135 136 public DefaultEntityHandler(StringPool stringPool, XMLErrorReporter errorReporter) { 137 fStringPool = stringPool; 138 fErrorReporter = errorReporter; 139 fReaderFactory = new DefaultReaderFactory(); 140 fEntityPool = new EntityPool(fStringPool, fErrorReporter, true); 141 } 142 143 public void setEventHandler(EventHandler eventHandler) { 144 fEventHandler = eventHandler; 145 } 146 147 public void setCharDataHandler(XMLEntityHandler.CharDataHandler charDataHandler) { 148 fCharDataHandler = charDataHandler; 149 } 150 151 public XMLEntityHandler.CharDataHandler getCharDataHandler() { 152 return fCharDataHandler; 153 } 154 155 158 public void setSendCharDataAsCharArray(boolean flag) { 159 fSendCharDataAsCharArray = flag; 160 fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray); 161 } 162 163 166 public void setReaderFactory(XMLEntityReaderFactory readerFactory) { 167 fReaderFactory = readerFactory; 168 fReaderFactory.setSendCharDataAsCharArray(fSendCharDataAsCharArray); 169 } 170 171 174 public void reset(StringPool stringPool) { 175 fStringPool = stringPool; 176 fEntityPool.reset(fStringPool); 177 fParameterEntityPool = null; 178 fReaderStack.removeAllElements(); 179 fEntityStackDepth = 0; 180 fReader = null; 181 fSource = null; 182 fEntityName = -1; 183 fEntityType = -1; 184 fEntityContext = -1; 185 fPublicId = null; 186 fSystemId = null; 187 fReaderId = -1; 188 fReaderDepth = -1; 189 fNextReaderId = 0; 190 } 191 192 195 public void setAllowJavaEncodings(boolean flag) { 196 fReaderFactory.setAllowJavaEncodingName(flag); 197 } 198 201 public boolean getAllowJavaEncodings() { 202 return fReaderFactory.getAllowJavaEncodingName(); 203 } 204 205 public int addInternalPEDecl(int name, int value, boolean isExternal) throws Exception { 209 if (fParameterEntityPool == null) 210 fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false); 211 int entityHandle = fParameterEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal); 212 return entityHandle; 213 } 214 public int addExternalPEDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception { 215 if (fParameterEntityPool == null) 216 fParameterEntityPool = new EntityPool(fStringPool, fErrorReporter, false); 217 int entityHandle = fParameterEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal); 218 return entityHandle; 219 } 220 public int addInternalEntityDecl(int name, int value, boolean isExternal) throws Exception { 221 int entityHandle = fEntityPool.addEntityDecl(name, value, -1, -1, -1, -1, isExternal); 222 return entityHandle; 223 } 224 public int addExternalEntityDecl(int name, int publicId, int systemId, boolean isExternal) throws Exception { 225 int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), -1, isExternal); 226 return entityHandle; 227 } 228 public int addUnparsedEntityDecl(int name, int publicId, int systemId, int notationName, boolean isExternal) throws Exception { 229 int entityHandle = fEntityPool.addEntityDecl(name, -1, publicId, systemId, fStringPool.addSymbol(fSystemId), notationName, isExternal); 230 if (!fEntityPool.isNotationDeclared(notationName)) { 231 Object [] args = { fStringPool.toString(name), 232 fStringPool.toString(notationName) }; 233 fEntityPool.addRequiredNotation(notationName, 234 fErrorReporter.getLocator(), 235 XMLMessages.MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL, 236 XMLMessages.VC_NOTATION_DECLARED, 237 args); 238 } 239 return entityHandle; 240 } 241 public int addNotationDecl(int notationName, int publicId, int systemId, boolean isExternal) throws Exception { 242 int notationHandle = fEntityPool.addNotationDecl(notationName, publicId, systemId, fStringPool.addSymbol(fSystemId), isExternal); 243 return notationHandle; 244 } 245 public boolean isUnparsedEntity(int entityName) { 246 int entityHandle = fEntityPool.lookupEntity(entityName); 247 return (entityHandle != -1 && fEntityPool.isUnparsedEntity(entityHandle)); 248 } 249 public boolean isNotationDeclared(int notationName) { 250 return fEntityPool.isNotationDeclared(notationName); 251 } 252 public void addRequiredNotation(int notationName, Locator locator, int majorCode, int minorCode, Object [] args) { 253 fEntityPool.addRequiredNotation(notationName, locator, majorCode, minorCode, args); 254 } 255 public void checkRequiredNotations() throws Exception { 256 fEntityPool.checkRequiredNotations(); 257 } 258 259 protected int lookupEntity(int entityNameIndex) { 260 int entityIndex = fEntityPool.lookupEntity(entityNameIndex); 261 return entityIndex; 262 } 263 private void reportRecoverableXMLError(int majorCode, int minorCode, int stringIndex1) throws Exception { 264 Object [] args = { fStringPool.toString(stringIndex1) }; 265 fErrorReporter.reportError(fErrorReporter.getLocator(), 266 XMLMessages.XML_DOMAIN, 267 majorCode, 268 minorCode, 269 args, 270 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR); 271 } 272 public boolean externalReferenceInContent(int entityHandle) throws Exception { 273 boolean external = fEntityPool.isExternalEntity(entityHandle); 274 if (fEventHandler.externalEntityStandaloneCheck()) { 275 if (external) { 276 reportRecoverableXMLError(XMLMessages.MSG_EXTERNAL_ENTITY_NOT_PERMITTED, 277 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION, 278 fEntityName); 279 } else if (fEntityPool.getEntityDeclIsExternal(entityHandle)) { 280 reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE, 281 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION, 282 fEntityName); 283 } 284 } 285 return external; 286 } 287 protected int valueOfReferenceInAttValue(int entityHandle) throws Exception { 288 if (fEventHandler.externalEntityStandaloneCheck() && fEntityPool.getEntityDeclIsExternal(entityHandle)) { 289 reportRecoverableXMLError(XMLMessages.MSG_REFERENCE_TO_EXTERNALLY_DECLARED_ENTITY_WHEN_STANDALONE, 290 XMLMessages.VC_STANDALONE_DOCUMENT_DECLARATION, 291 fEntityName); 292 } 293 int entityValue = fEntityPool.getEntityValue(entityHandle); 294 return entityValue; 295 } 296 protected boolean isExternalEntity(int entityHandle) { 297 boolean external = fEntityPool.isExternalEntity(entityHandle); 298 return external; 299 } 300 protected int getEntityValue(int entityHandle) { 301 int value = fEntityPool.getEntityValue(entityHandle); 302 return value; 303 } 304 protected String getPublicIdOfEntity(int entityHandle) { 305 int publicId = fEntityPool.getPublicId(entityHandle); 306 return fStringPool.toString(publicId); 307 } 308 protected String getSystemIdOfEntity(int entityHandle) { 309 int systemId = fEntityPool.getSystemId(entityHandle); 310 return fStringPool.toString(systemId); 311 } 312 protected int lookupParameterEntity(int peName) throws Exception { 313 int entityHandle = -1; 314 if (fParameterEntityPool != null) 315 entityHandle = fParameterEntityPool.lookupEntity(peName); 316 return entityHandle; 317 } 318 protected boolean isExternalParameterEntity(int peIndex) { 319 boolean external = fParameterEntityPool.isExternalEntity(peIndex); 320 return external; 321 } 322 protected int getParameterEntityValue(int peIndex) { 323 int value = fParameterEntityPool.getEntityValue(peIndex); 324 return value; 325 } 326 protected String getPublicIdOfParameterEntity(int peIndex) { 327 int publicId = fParameterEntityPool.getPublicId(peIndex); 328 return fStringPool.toString(publicId); 329 } 330 protected String getSystemIdOfParameterEntity(int peIndex) { 331 int systemId = fParameterEntityPool.getSystemId(peIndex); 332 return fStringPool.toString(systemId); 333 } 334 335 338 public XMLEntityHandler.EntityReader getEntityReader() { 339 return fReader; 340 } 341 342 347 public void addRecognizer(XMLDeclRecognizer recognizer) { 348 fReaderFactory.addRecognizer(recognizer); 349 } 350 351 358 public void setEntityResolver(EntityResolver resolver) { 359 fResolver = resolver; 360 } 361 362 368 public EntityResolver getEntityResolver() { 369 return fResolver; 370 } 371 372 385 public String expandSystemId(String systemId) { 386 return expandSystemId(systemId, fSystemId); 387 } 388 private String expandSystemId(String systemId, String currentSystemId) { 389 String id = systemId; 390 391 if (id == null || id.length() == 0) { 393 return ""; 396 } 397 398 try { 400 URI uri = new URI(id); 401 if (uri != null) { 402 return systemId; 403 } 404 } 405 catch (URI.MalformedURIException e) { 406 } 408 409 id = fixURI(id); 411 412 URI base = null; 414 URI uri = null; 415 try { 416 if (currentSystemId == null) { 417 String dir; 418 try { 419 dir = fixURI(System.getProperty("user.dir")); 420 } 421 catch (SecurityException se) { 422 dir = ""; 423 } 424 if (!dir.endsWith("/")) { 425 dir = dir + "/"; 426 } 427 base = new URI("file", "", dir, null, null); 428 } 429 else { 430 base = new URI(currentSystemId); 431 } 432 433 uri = new URI(base, id); 435 } 436 catch (Exception e) { 437 } 439 if (uri == null) { 440 return systemId; 441 } 442 return uri.toString(); 443 } 444 445 449 456 private static String fixURI(String str) { 457 458 str = str.replace(java.io.File.separatorChar, '/'); 460 461 if (str.length() >= 2) { 463 char ch1 = str.charAt(1); 464 if (ch1 == ':') { 465 char ch0 = Character.toUpperCase(str.charAt(0)); 466 if (ch0 >= 'A' && ch0 <= 'Z') { 467 str = "/" + str; 468 } 469 } 470 } 471 472 return str; 474 } 475 476 public boolean startReadingFromDocument(InputSource source) throws Exception { 477 pushEntity(false, -2); fSystemId = null; 479 pushNullReader(); 480 fEntityName = -2; fEntityType = ENTITYTYPE_DOCUMENT; 482 fEntityContext = ENTITYREF_DOCUMENT; 483 fReaderDepth = 0; 484 fReaderId = fNextReaderId++; 485 fPublicId = source.getPublicId(); 486 fSystemId = source.getSystemId(); 487 fEventHandler.startEntityReference(fEntityName, fEntityType, fEntityContext); 488 fSystemId = expandSystemId(fSystemId, null); 489 fSource = source; 490 boolean xmlDecl = true; try { 492 fReader = fReaderFactory.createReader(this, fErrorReporter, source, fSystemId, xmlDecl, fStringPool); 493 } catch (MalformedURLException mu) { 494 String errorSystemId = fSystemId; 495 fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext); 496 popReader(); 497 popEntity(); 498 fReader = null; 499 Object [] args = { errorSystemId }; 500 fErrorReporter.reportError(fErrorReporter.getLocator(), 501 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN, 502 ImplementationMessages.IO0, 503 0, 504 args, 505 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 506 } catch (FileNotFoundException fnf) { 507 String errorSystemId = fSystemId; 510 fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext); 511 popReader(); 512 popEntity(); 513 fReader = null; 514 Object [] args = { errorSystemId }; 515 fErrorReporter.reportError(fErrorReporter.getLocator(), 516 ImplementationMessages.XERCES_IMPLEMENTATION_DOMAIN, 517 ImplementationMessages.IO0, 518 0, 519 args, 520 XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR); 521 throw fnf; 522 } catch (UnsupportedEncodingException uee) { 523 fEventHandler.endEntityReference(fEntityName, fEntityType, fEntityContext); 524 popReader(); 525 popEntity(); 526 fReader = null; 527 String encoding = uee.getMessage(); 528 if (encoding == null) { 529 fErrorReporter.reportError(fErrorReporter.getLocator(), 530 XMLMessages.XML_DOMAIN, 531 XMLMessages.MSG_ENCODING_REQUIRED, 532 XMLMessages.P81_REQUIRED, 533 null, 534 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 535 } else if (!XMLCharacterProperties.validEncName(encoding)) { 536 Object [] args = { encoding }; 537 fErrorReporter.reportError(fErrorReporter.getLocator(), 538 XMLMessages.XML_DOMAIN, 539 XMLMessages.MSG_ENCODINGDECL_INVALID, 540 XMLMessages.P81_INVALID_VALUE, 541 args, 542 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 543 } else { 544 Object [] args = { encoding }; 545 fErrorReporter.reportError(fErrorReporter.getLocator(), 546 XMLMessages.XML_DOMAIN, 547 XMLMessages.MSG_ENCODING_NOT_SUPPORTED, 548 XMLMessages.P81_NOT_SUPPORTED, 549 args, 550 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 551 } 552 } 553 fEventHandler.sendReaderChangeNotifications(fReader, fReaderId); 554 return fReader != null; 555 } 556 559 public void startReadingFromExternalSubset(String publicId, String systemId, int readerDepth) throws Exception { 560 pushEntity(true, -1); 561 pushReader(); 562 pushNullReader(); 563 fEntityName = -1; fEntityType = ENTITYTYPE_EXTERNAL_SUBSET; 565 fEntityContext = ENTITYREF_EXTERNAL_SUBSET; 566 fReaderDepth = readerDepth; 567 fReaderId = fNextReaderId++; 568 fPublicId = publicId; 569 fSystemId = systemId; 570 startReadingFromExternalEntity(false, -1); 571 } 572 575 public void stopReadingFromExternalSubset() throws Exception { 576 if (!(fReader instanceof NullReader)) 577 throw new RuntimeException ("FWK004 cannot happen 18"+"\n18"); 578 popReader(); 579 fEventHandler.sendReaderChangeNotifications(fReader, fReaderId); 580 } 581 582 585 public boolean startReadingFromEntity(int entityName, int readerDepth, int context) throws Exception { 586 if (context > XMLEntityHandler.ENTITYREF_IN_CONTENT) 587 return startReadingFromParameterEntity(entityName, readerDepth, context); 588 int entityHandle = lookupEntity(entityName); 589 if (entityHandle < 0) { 590 int minorCode = XMLMessages.VC_ENTITY_DECLARED; 591 int errorType = XMLErrorReporter.ERRORTYPE_RECOVERABLE_ERROR; 592 if (fEntityContext == ENTITYREF_DOCUMENT || fEntityContext == ENTITYREF_IN_ATTVALUE) { 594 minorCode = XMLMessages.WFC_ENTITY_DECLARED; 595 errorType = XMLErrorReporter.ERRORTYPE_FATAL_ERROR; 596 } else if (!fEventHandler.getValidating()) { 597 return false; 598 } 599 Object [] args = { fStringPool.toString(entityName) }; 600 fErrorReporter.reportError(fErrorReporter.getLocator(), 601 XMLMessages.XML_DOMAIN, 602 XMLMessages.MSG_ENTITY_NOT_DECLARED, 603 minorCode, 604 args, 605 errorType); 606 return false; 607 } 608 if (context == ENTITYREF_IN_CONTENT) { 609 if (fEntityPool.isUnparsedEntity(entityHandle)) { 610 Object [] args = { fStringPool.toString(entityName) }; 611 fErrorReporter.reportError(fErrorReporter.getLocator(), 612 XMLMessages.XML_DOMAIN, 613 XMLMessages.MSG_REFERENCE_TO_UNPARSED_ENTITY, 614 XMLMessages.WFC_PARSED_ENTITY, 615 args, 616 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 617 return false; 618 } 619 } else { 620 if (isExternalEntity(entityHandle)) { 621 Object [] args = { fStringPool.toString(entityName) }; 622 fErrorReporter.reportError(fErrorReporter.getLocator(), 623 XMLMessages.XML_DOMAIN, 624 XMLMessages.MSG_REFERENCE_TO_EXTERNAL_ENTITY, 625 XMLMessages.WFC_NO_EXTERNAL_ENTITY_REFERENCES, 626 args, 627 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 628 return false; 629 } 630 } 631 if (!pushEntity(false, entityName)) { 632 Object [] args = { fStringPool.toString(entityName), 633 entityReferencePath(false, entityName) }; 634 fErrorReporter.reportError(fErrorReporter.getLocator(), 635 XMLMessages.XML_DOMAIN, 636 XMLMessages.MSG_RECURSIVE_REFERENCE, 637 XMLMessages.WFC_NO_RECURSION, 638 args, 639 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 640 return false; 641 } 642 pushReader(); 643 fEntityName = entityName; 644 fEntityContext = context; 645 fReaderDepth = readerDepth; 646 fReaderId = fNextReaderId++; 647 if (context != ENTITYREF_IN_CONTENT || !externalReferenceInContent(entityHandle)) { 648 fEntityType = ENTITYTYPE_INTERNAL; 649 fPublicId = null; 650 fSystemId = fSystemId; int value = -1; 652 if (context == ENTITYREF_IN_CONTENT || context == ENTITYREF_IN_DEFAULTATTVALUE) 653 value = getEntityValue(entityHandle); 654 else 655 value = valueOfReferenceInAttValue(entityHandle); 656 startReadingFromInternalEntity(value, false); 657 return false; 658 } 659 fEntityType = ENTITYTYPE_EXTERNAL; 660 fPublicId = getPublicIdOfEntity(entityHandle); 661 fSystemId = getSystemIdOfEntity(entityHandle); 662 return startReadingFromExternalEntity(true, entityHandle); 663 } 664 private boolean startReadingFromParameterEntity(int peName, int readerDepth, int context) throws Exception { 665 int entityHandle = lookupParameterEntity(peName); 666 if (entityHandle == -1) { 667 if (fEventHandler.getValidating()) { 669 reportRecoverableXMLError(XMLMessages.MSG_ENTITY_NOT_DECLARED, 670 XMLMessages.VC_ENTITY_DECLARED, 671 peName); 672 } 673 return false; 674 } 675 if (!pushEntity(true, peName)) { 676 Object [] args = { fStringPool.toString(peName), 677 entityReferencePath(true, peName) }; 678 fErrorReporter.reportError(fErrorReporter.getLocator(), 679 XMLMessages.XML_DOMAIN, 680 XMLMessages.MSG_RECURSIVE_PEREFERENCE, 681 XMLMessages.WFC_NO_RECURSION, 682 args, 683 XMLErrorReporter.ERRORTYPE_FATAL_ERROR); 684 return false; 685 } 686 pushReader(); 687 fEntityName = peName; 688 fEntityContext = context; 689 fReaderDepth = readerDepth; 690 fReaderId = fNextReaderId++; 691 if (!isExternalParameterEntity(entityHandle)) { 692 fEntityType = ENTITYTYPE_INTERNAL_PE; 693 fPublicId = null; 694 fSystemId = fSystemId; int value = getParameterEntityValue(entityHandle); 696 startReadingFromInternalEntity(value, fEntityContext == ENTITYREF_IN_ENTITYVALUE ? false : true); 697 return false; 698 } 699 fEntityType = ENTITYTYPE_EXTERNAL_PE; 700 fPublicId = getPublicIdOfParameterEntity(entityHandle); 701 fSystemId = getSystemIdOfParameterEntity(entityHandle); 702 return startReadingFromExternalEntity(true, entityHandle); 703 } 704 private void startReadingFromInternalEntity(int value, boolean addSpaces) throws Exception { 705 if (fEntityContext == ENTITYREF_IN_ENTITYVALUE) { 706 |