1 7 8 package org.dom4j.io; 9 10 import java.io.File ; 11 import java.io.FileInputStream ; 12 import java.io.FileNotFoundException ; 13 import java.io.InputStream ; 14 import java.io.Reader ; 15 import java.io.Serializable ; 16 import java.net.URL ; 17 18 import org.dom4j.Document; 19 import org.dom4j.DocumentException; 20 import org.dom4j.DocumentFactory; 21 import org.dom4j.ElementHandler; 22 23 import org.xml.sax.EntityResolver ; 24 import org.xml.sax.ErrorHandler ; 25 import org.xml.sax.InputSource ; 26 import org.xml.sax.SAXException ; 27 import org.xml.sax.SAXParseException ; 28 import org.xml.sax.XMLFilter ; 29 import org.xml.sax.XMLReader ; 30 import org.xml.sax.helpers.DefaultHandler ; 31 import org.xml.sax.helpers.XMLReaderFactory ; 32 33 79 public class SAXReader { 80 private static final String SAX_STRING_INTERNING = 81 "http://xml.org/sax/features/string-interning"; 82 private static final String SAX_NAMESPACE_PREFIXES = 83 "http://xml.org/sax/features/namespace-prefixes"; 84 private static final String SAX_NAMESPACES = 85 "http://xml.org/sax/features/namespaces"; 86 private static final String SAX_DECL_HANDLER = 87 "http://xml.org/sax/properties/declaration-handler"; 88 private static final String SAX_LEXICAL_HANDLER = 89 "http://xml.org/sax/properties/lexical-handler"; 90 private static final String SAX_LEXICALHANDLER = 91 "http://xml.org/sax/handlers/LexicalHandler"; 92 93 94 private DocumentFactory factory; 95 96 97 private XMLReader xmlReader; 98 99 100 private boolean validating; 101 102 103 private DispatchHandler dispatchHandler; 104 105 106 private ErrorHandler errorHandler; 107 108 109 private EntityResolver entityResolver; 110 111 112 private boolean stringInternEnabled = true; 113 114 115 private boolean includeInternalDTDDeclarations = false; 116 117 118 private boolean includeExternalDTDDeclarations = false; 119 120 121 private boolean mergeAdjacentText = false; 122 123 124 private boolean stripWhitespaceText = false; 125 126 127 private boolean ignoreComments = false; 128 129 130 private String encoding = null; 131 132 135 136 private XMLFilter xmlFilter; 137 138 public SAXReader() { 139 } 140 141 public SAXReader(boolean validating) { 142 this.validating = validating; 143 } 144 145 public SAXReader(DocumentFactory factory) { 146 this.factory = factory; 147 } 148 149 public SAXReader(DocumentFactory factory, boolean validating) { 150 this.factory = factory; 151 this.validating = validating; 152 } 153 154 public SAXReader(XMLReader xmlReader) { 155 this.xmlReader = xmlReader; 156 } 157 158 public SAXReader(XMLReader xmlReader, boolean validating) { 159 this.xmlReader = xmlReader; 160 this.validating = validating; 161 } 162 163 public SAXReader(String xmlReaderClassName) throws SAXException { 164 if (xmlReaderClassName != null) { 165 this.xmlReader = XMLReaderFactory 166 .createXMLReader(xmlReaderClassName); 167 } 168 } 169 170 public SAXReader(String xmlReaderClassName, boolean validating) 171 throws SAXException { 172 if (xmlReaderClassName != null) { 173 this.xmlReader = XMLReaderFactory 174 .createXMLReader(xmlReaderClassName); 175 } 176 177 this.validating = validating; 178 } 179 180 197 public void setProperty(String name, Object value) throws SAXException { 198 getXMLReader().setProperty(name, value); 199 } 200 201 217 public void setFeature(String name, boolean value) throws SAXException { 218 getXMLReader().setFeature(name, value); 219 } 220 221 234 public Document read(File file) throws DocumentException { 235 try { 236 243 InputSource source = new InputSource (new FileInputStream (file)); 244 if (this.encoding != null) { 245 source.setEncoding(this.encoding); 246 } 247 String path = file.getAbsolutePath(); 248 249 if (path != null) { 250 StringBuffer sb = new StringBuffer ("file://"); 252 253 if (!path.startsWith(File.separator)) { 255 sb.append("/"); 256 } 257 258 path = path.replace('\\', '/'); 259 sb.append(path); 260 261 source.setSystemId(sb.toString()); 262 } 263 264 return read(source); 265 } catch (FileNotFoundException e) { 266 throw new DocumentException(e.getMessage(), e); 267 } 268 } 269 270 283 public Document read(URL url) throws DocumentException { 284 String systemID = url.toExternalForm(); 285 286 InputSource source = new InputSource (systemID); 287 if (this.encoding != null) { 288 source.setEncoding(this.encoding); 289 } 290 291 return read(source); 292 } 293 294 315 public Document read(String systemId) throws DocumentException { 316 InputSource source = new InputSource (systemId); 317 if (this.encoding != null) { 318 source.setEncoding(this.encoding); 319 } 320 321 return read(source); 322 } 323 324 337 public Document read(InputStream in) throws DocumentException { 338 InputSource source = new InputSource (in); 339 if (this.encoding != null) { 340 source.setEncoding(this.encoding); 341 } 342 343 return read(source); 344 } 345 346 359 public Document read(Reader reader) throws DocumentException { 360 InputSource source = new InputSource (reader); 361 if (this.encoding != null) { 362 source.setEncoding(this.encoding); 363 } 364 365 return read(source); 366 } 367 368 383 public Document read(InputStream in, String systemId) 384 throws DocumentException { 385 InputSource source = new InputSource (in); 386 source.setSystemId(systemId); 387 if (this.encoding != null) { 388 source.setEncoding(this.encoding); 389 } 390 391 return read(source); 392 } 393 394 409 public Document read(Reader reader, String systemId) 410 throws DocumentException { 411 InputSource source = new InputSource (reader); 412 source.setSystemId(systemId); 413 if (this.encoding != null) { 414 source.setEncoding(this.encoding); 415 } 416 417 return read(source); 418 } 419 420 433 public Document read(InputSource in) throws DocumentException { 434 try { 435 XMLReader reader = getXMLReader(); 436 437 reader = installXMLFilter(reader); 438 439 EntityResolver thatEntityResolver = this.entityResolver; 440 441 if (thatEntityResolver == null) { 442 thatEntityResolver = createDefaultEntityResolver(in 443 .getSystemId()); 444 this.entityResolver = thatEntityResolver; 445 } 446 447 reader.setEntityResolver(thatEntityResolver); 448 449 SAXContentHandler contentHandler = createContentHandler(reader); 450 contentHandler.setEntityResolver(thatEntityResolver); 451 contentHandler.setInputSource(in); 452 453 boolean internal = isIncludeInternalDTDDeclarations(); 454 boolean external = isIncludeExternalDTDDeclarations(); 455 456 contentHandler.setIncludeInternalDTDDeclarations(internal); 457 contentHandler.setIncludeExternalDTDDeclarations(external); 458 contentHandler.setMergeAdjacentText(isMergeAdjacentText()); 459 contentHandler.setStripWhitespaceText(isStripWhitespaceText()); 460 contentHandler.setIgnoreComments(isIgnoreComments()); 461 reader.setContentHandler(contentHandler); 462 463 configureReader(reader, contentHandler); 464 465 reader.parse(in); 466 467 return contentHandler.getDocument(); 468 } catch (Exception e) { 469 if (e instanceof SAXParseException ) { 470 SAXParseException parseException = (SAXParseException ) e; 472 String systemId = parseException.getSystemId(); 473 474 if (systemId == null) { 475 systemId = ""; 476 } 477 478 String message = "Error on line " 479 + parseException.getLineNumber() + " of document " 480 + systemId + " : " + parseException.getMessage(); 481 482 throw new DocumentException(message, e); 483 } else { 484 throw new DocumentException(e.getMessage(), e); 485 } 486 } 487 } 488 489 492 498 public boolean isValidating() { 499 return validating; 500 } 501 502 508 public void setValidation(boolean validation) { 509 this.validating = validation; 510 } 511 512 518 public boolean isIncludeInternalDTDDeclarations() { 519 return includeInternalDTDDeclarations; 520 } 521 522 530 public void setIncludeInternalDTDDeclarations(boolean include) { 531 this.includeInternalDTDDeclarations = include; 532 } 533 534 540 public boolean isIncludeExternalDTDDeclarations() { 541 return includeExternalDTDDeclarations; 542 } 543 544 552 public void setIncludeExternalDTDDeclarations(boolean include) { 553 this.includeExternalDTDDeclarations = include; 554 } 555 556 562 public boolean isStringInternEnabled() { 563 return stringInternEnabled; 564 } 565 566 573 public void setStringInternEnabled(boolean stringInternEnabled) { 574 this.stringInternEnabled = stringInternEnabled; 575 } 576 577 582 public boolean isMergeAdjacentText() { 583 return mergeAdjacentText; 584 } 585 586 593 public void setMergeAdjacentText(boolean mergeAdjacentText) { 594 this.mergeAdjacentText = mergeAdjacentText; 595 } 596 597 603 public boolean isStripWhitespaceText() { 604 return stripWhitespaceText; 605 } 606 607 614 public void setStripWhitespaceText(boolean stripWhitespaceText) { 615 this.stripWhitespaceText = stripWhitespaceText; 616 } 617 618 623 public boolean isIgnoreComments() { 624 return ignoreComments; 625 } 626 627 633 public void setIgnoreComments(boolean ignoreComments) { 634 this.ignoreComments = ignoreComments; 635 } 636 637 643 public DocumentFactory getDocumentFactory() { 644 if (factory == null) { 645 factory = DocumentFactory.getInstance(); 646 } 647 648 return factory; 649 } 650 651 662 public void setDocumentFactory(DocumentFactory documentFactory) { 663 this.factory = documentFactory; 664 } 665 666 671 public ErrorHandler getErrorHandler() { 672 return errorHandler; 673 } 674 675 682 public void setErrorHandler(ErrorHandler errorHandler) { 683 this.errorHandler = errorHandler; 684 } 685 686 691 public EntityResolver getEntityResolver() { 692 return entityResolver; 693 } 694 695 701 public void setEntityResolver(EntityResolver entityResolver) { 702 this.entityResolver = entityResolver; 703 } 704 705 713 public XMLReader getXMLReader() throws SAXException { 714 if (xmlReader == null) { 715 xmlReader = createXMLReader(); 716 } 717 718 return xmlReader; 719 } 720 721 727 public void setXMLReader(XMLReader reader) { 728 this.xmlReader = reader; 729 } 730 731 738 public String getEncoding() { 739 return encoding; 740 } 741 742 748 public void setEncoding(String encoding) { 749 this.encoding = encoding; 750 } 751 752 763 public void setXMLReaderClassName(String xmlReaderClassName) 764 throws SAXException { 765 setXMLReader(XMLReaderFactory.createXMLReader(xmlReaderClassName)); 766 } 767 768 778 public void addHandler(String path, ElementHandler handler) { 779 getDispatchHandler().addHandler(path, handler); 780 } 781 782 789 public void removeHandler(String path) { 790 getDispatchHandler().removeHandler(path); 791 } 792 793 802 public void setDefaultHandler(ElementHandler handler) { 803 getDispatchHandler().setDefaultHandler(handler); 804 } 805 806 811 public void resetHandlers() { 812 getDispatchHandler().resetHandlers(); 813 } 814 815 820 public XMLFilter getXMLFilter() { 821 return xmlFilter; 822 } 823 824 830 public void setXMLFilter(XMLFilter filter) { 831 this.xmlFilter = filter; 832 } 833 834 837 847 protected XMLReader installXMLFilter(XMLReader reader) { 848 XMLFilter filter = getXMLFilter(); 849 850 if (filter != null) { 851 XMLFilter root = filter; 853 854 while (true) { 855 XMLReader parent = root.getParent(); 856 857 if (parent instanceof XMLFilter ) { 858 root = (XMLFilter ) parent; 859 } else { 860 break; 861 } 862 } 863 864 root.setParent(reader); 865 866 return filter; 867 } 868 869 return reader; 870 } 871 872 protected DispatchHandler getDispatchHandler() { 873 if (dispatchHandler == null) { 874 dispatchHandler = new DispatchHandler(); 875 } 876 877 return dispatchHandler; 878 } 879 880 protected void setDispatchHandler(DispatchHandler dispatchHandler) { 881 this.dispatchHandler = dispatchHandler; 882 } 883 884 893 protected XMLReader createXMLReader() throws SAXException { 894 return SAXHelper.createXMLReader(isValidating()); 895 } 896 897 908 protected void configureReader(XMLReader reader, DefaultHandler handler) 909 throws DocumentException { 910 SAXHelper.setParserProperty(reader, SAX_LEXICALHANDLER, handler); 912 913 SAXHelper.setParserProperty(reader, SAX_LEXICAL_HANDLER, handler); 915 916 if (includeInternalDTDDeclarations || includeExternalDTDDeclarations) { 918 SAXHelper.setParserProperty(reader, SAX_DECL_HANDLER, handler); 919 } 920 921 SAXHelper.setParserFeature(reader, SAX_NAMESPACES, true); 923 924 SAXHelper.setParserFeature(reader, SAX_NAMESPACE_PREFIXES, false); 925 926 SAXHelper.setParserFeature(reader, SAX_STRING_INTERNING, 928 isStringInternEnabled()); 929 930 938 SAXHelper.setParserFeature(reader, 940 "http://xml.org/sax/features/use-locator2", true); 941 942 try { 943 reader.setFeature("http://xml.org/sax/features/validation", 945 isValidating()); 946 947 if (errorHandler != null) { 948 reader.setErrorHandler(errorHandler); 949 } else { 950 reader.setErrorHandler(handler); 951 } 952 } catch (Exception e) { 953 if (isValidating()) { 954 throw new DocumentException("Validation not supported for" 955 + " XMLReader: " + reader, e); 956 } 957 } 958 } 959 960 968 protected SAXContentHandler createContentHandler(XMLReader reader) { 969 return new SAXContentHandler(getDocumentFactory(), dispatchHandler); 970 } 971 972 protected EntityResolver createDefaultEntityResolver(String systemId) { 973 String prefix = null; 974 975 if ((systemId != null) && (systemId.length() > 0)) { 976 int idx = systemId.lastIndexOf('/'); 977 978 if (idx > 0) { 979 prefix = systemId.substring(0, idx + 1); 980 } 981 } 982 983 return new SAXEntityResolver(prefix); 984 } 985 986 protected static class SAXEntityResolver implements EntityResolver , 987 Serializable { 988 protected String uriPrefix; 989 990 public SAXEntityResolver(String uriPrefix) { 991 this.uriPrefix = uriPrefix; 992 } 993 994 public InputSource resolveEntity(String publicId, String systemId) { 995 if ((systemId != null) && (systemId.length() > 0)) { 997 if ((uriPrefix != null) && (systemId.indexOf(':') <= 0)) { 998 systemId = uriPrefix + systemId; 999 } 1000 } 1001 1002 return new InputSource (systemId); 1003 } 1004 } 1005} 1006 1007 1043 | Popular Tags |