1 57 58 package com.sun.org.apache.xerces.internal.impl; 59 60 import java.io.IOException ; 61 import java.io.InputStream ; 62 import java.io.InputStreamReader ; 63 import java.io.Reader ; 64 import java.io.StringReader ; 65 import java.net.HttpURLConnection ; 66 import java.net.URL ; 67 import java.net.URLConnection ; 68 import java.util.Hashtable ; 69 import java.util.Locale ; 70 import java.util.Stack ; 71 import java.util.Vector ; 72 73 import com.sun.org.apache.xerces.internal.impl.io.ASCIIReader; 74 import com.sun.org.apache.xerces.internal.impl.io.UCSReader; 75 import com.sun.org.apache.xerces.internal.impl.io.UTF8Reader; 76 import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; 77 import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; 78 import com.sun.org.apache.xerces.internal.util.AugmentationsImpl; 79 import com.sun.org.apache.xerces.internal.util.EncodingMap; 80 import com.sun.org.apache.xerces.internal.util.SymbolTable; 81 import com.sun.org.apache.xerces.internal.util.URI; 82 import com.sun.org.apache.xerces.internal.util.XMLChar; 83 import com.sun.org.apache.xerces.internal.util.XMLEntityDescriptionImpl; 84 import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; 85 import com.sun.org.apache.xerces.internal.util.SecurityManager; 86 import com.sun.org.apache.xerces.internal.xni.Augmentations; 87 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; 88 import com.sun.org.apache.xerces.internal.xni.XNIException; 89 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; 90 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; 91 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; 92 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; 93 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; 94 import com.sun.org.apache.xerces.internal.xinclude.XIncludeHandler; 95 import com.sun.org.apache.xerces.internal.xinclude.XIncludeInputSource; 96 122 public class XMLEntityManager 123 implements XMLComponent, XMLEntityResolver { 124 125 129 130 public static final int DEFAULT_BUFFER_SIZE = 2048; 131 132 133 public static final int DEFAULT_XMLDECL_BUFFER_SIZE = 64; 134 135 136 public static final int DEFAULT_INTERNAL_BUFFER_SIZE = 1024; 137 138 140 141 protected static final String VALIDATION = 142 Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; 143 144 145 protected static final String EXTERNAL_GENERAL_ENTITIES = 146 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_GENERAL_ENTITIES_FEATURE; 147 148 149 protected static final String EXTERNAL_PARAMETER_ENTITIES = 150 Constants.SAX_FEATURE_PREFIX + Constants.EXTERNAL_PARAMETER_ENTITIES_FEATURE; 151 152 153 protected static final String ALLOW_JAVA_ENCODINGS = 154 Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; 155 156 157 protected static final String WARN_ON_DUPLICATE_ENTITYDEF = 158 Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE; 159 160 161 protected static final String STANDARD_URI_CONFORMANT = 162 Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE; 163 164 protected static final String PARSER_SETTINGS = 165 Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; 166 167 169 170 protected static final String SYMBOL_TABLE = 171 Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; 172 173 174 protected static final String ERROR_REPORTER = 175 Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; 176 177 178 protected static final String ENTITY_RESOLVER = 179 Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; 180 181 protected static final String VALIDATION_MANAGER = 183 Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; 184 185 186 protected static final String BUFFER_SIZE = 187 Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY; 188 189 190 protected static final String SECURITY_MANAGER = 191 Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; 192 193 195 196 private static final String [] RECOGNIZED_FEATURES = { 197 VALIDATION, 198 EXTERNAL_GENERAL_ENTITIES, 199 EXTERNAL_PARAMETER_ENTITIES, 200 ALLOW_JAVA_ENCODINGS, 201 WARN_ON_DUPLICATE_ENTITYDEF, 202 STANDARD_URI_CONFORMANT 203 }; 204 205 206 private static final Boolean [] FEATURE_DEFAULTS = { 207 null, 208 Boolean.TRUE, 209 Boolean.TRUE, 210 Boolean.TRUE, 211 Boolean.FALSE, 212 Boolean.FALSE 213 }; 214 215 216 private static final String [] RECOGNIZED_PROPERTIES = { 217 SYMBOL_TABLE, 218 ERROR_REPORTER, 219 ENTITY_RESOLVER, 220 VALIDATION_MANAGER, 221 BUFFER_SIZE, 222 SECURITY_MANAGER, 223 }; 224 225 226 private static final Object [] PROPERTY_DEFAULTS = { 227 null, 228 null, 229 null, 230 null, 231 new Integer (DEFAULT_BUFFER_SIZE), 232 null, 233 }; 234 235 private static final String XMLEntity = "[xml]".intern(); 236 private static final String DTDEntity = "[dtd]".intern(); 237 238 240 245 private static final boolean DEBUG_BUFFER = false; 246 247 248 private static final boolean DEBUG_ENTITIES = false; 249 250 251 private static final boolean DEBUG_ENCODINGS = false; 252 253 private static final boolean DEBUG_RESOLVER = false; 255 256 260 262 266 protected boolean fValidation; 267 268 272 protected boolean fExternalGeneralEntities = true; 273 274 278 protected boolean fExternalParameterEntities = true; 279 280 284 protected boolean fAllowJavaEncodings; 285 286 289 protected boolean fWarnDuplicateEntityDef; 290 291 295 protected boolean fStrictURI; 296 297 protected boolean fCharsetOverrideXmlEncoding; 298 300 304 protected SymbolTable fSymbolTable; 305 306 310 protected XMLErrorReporter fErrorReporter; 311 312 316 protected XMLEntityResolver fEntityResolver; 317 318 322 protected ValidationManager fValidationManager; 323 324 326 331 protected int fBufferSize = DEFAULT_BUFFER_SIZE; 332 333 protected SecurityManager fSecurityManager = null; 336 337 341 protected boolean fStandalone; 342 343 protected boolean fInExternalSubset = false; 346 347 349 350 protected XMLEntityHandler fEntityHandler; 351 352 354 355 protected XMLEntityScanner fEntityScanner; 356 357 358 protected XMLEntityScanner fXML10EntityScanner; 359 360 361 protected XMLEntityScanner fXML11EntityScanner; 362 363 protected int fEntityExpansionLimit = 0; 366 protected int fEntityExpansionCount = 0; 368 369 371 372 protected Hashtable fEntities = new Hashtable (); 373 374 375 protected Stack fEntityStack = new Stack (); 376 377 378 protected ScannedEntity fCurrentEntity; 379 380 382 383 protected Hashtable fDeclaredEntities; 384 385 387 388 private final XMLResourceIdentifierImpl fResourceIdentifier = new XMLResourceIdentifierImpl(); 389 390 391 private final Augmentations fEntityAugs = new AugmentationsImpl(); 392 393 397 398 public XMLEntityManager() { 399 this(null); 400 } 402 410 public XMLEntityManager(XMLEntityManager entityManager) { 411 412 413 fDeclaredEntities = entityManager != null 415 ? entityManager.getDeclaredEntities() : null; 416 417 setScannerVersion(Constants.XML_VERSION_1_0); 418 } 420 424 429 public void setStandalone(boolean standalone) { 430 fStandalone = standalone; 431 } 433 434 public boolean isStandalone() { 435 return fStandalone; 436 } 438 444 public void setEntityHandler(XMLEntityHandler entityHandler) { 445 fEntityHandler = entityHandler; 446 } 448 public XMLResourceIdentifier getCurrentResourceIdentifier() { 454 return fResourceIdentifier; 455 } 456 457 public ScannedEntity getCurrentEntity() { 463 return fCurrentEntity; 464 } 465 466 480 public void addInternalEntity(String name, String text) { 481 if (!fEntities.containsKey(name)) { 482 Entity entity = new InternalEntity(name, text, fInExternalSubset); 483 fEntities.put(name, entity); 484 } 485 else{ 486 if(fWarnDuplicateEntityDef){ 487 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 488 "MSG_DUPLICATE_ENTITY_DEFINITION", 489 new Object []{ name }, 490 XMLErrorReporter.SEVERITY_WARNING ); 491 } 492 } 493 494 } 496 518 public void addExternalEntity(String name, 519 String publicId, String literalSystemId, 520 String baseSystemId) throws IOException { 521 if (!fEntities.containsKey(name)) { 522 if (baseSystemId == null) { 523 int size = fEntityStack.size(); 525 if (size == 0 && fCurrentEntity != null && fCurrentEntity.entityLocation != null) { 526 baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId(); 527 } 528 for (int i = size - 1; i >= 0 ; i--) { 529 ScannedEntity externalEntity = 530 (ScannedEntity)fEntityStack.elementAt(i); 531 if (externalEntity.entityLocation != null && externalEntity.entityLocation.getExpandedSystemId() != null) { 532 baseSystemId = externalEntity.entityLocation.getExpandedSystemId(); 533 break; 534 } 535 } 536 } 537 Entity entity = new ExternalEntity(name, 538 new XMLEntityDescriptionImpl(name, publicId, literalSystemId, baseSystemId, 539 expandSystemId(literalSystemId, baseSystemId, false)), null, fInExternalSubset); 540 fEntities.put(name, entity); 541 } 542 else{ 543 if(fWarnDuplicateEntityDef){ 544 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 545 "MSG_DUPLICATE_ENTITY_DEFINITION", 546 new Object []{ name }, 547 XMLErrorReporter.SEVERITY_WARNING ); 548 } 549 } 550 551 } 553 560 public boolean isExternalEntity(String entityName) { 561 562 Entity entity = (Entity)fEntities.get(entityName); 563 if (entity == null) { 564 return false; 565 } 566 return entity.isExternal(); 567 } 568 569 577 public boolean isEntityDeclInExternalSubset(String entityName) { 578 579 Entity entity = (Entity)fEntities.get(entityName); 580 if (entity == null) { 581 return false; 582 } 583 return entity.isEntityDeclInExternalSubset(); 584 } 585 586 602 public void addUnparsedEntity(String name, 603 String publicId, String systemId, 604 String baseSystemId, String notation) { 605 if (!fEntities.containsKey(name)) { 606 Entity entity = new ExternalEntity(name, 607 new XMLEntityDescriptionImpl(name, publicId, systemId, baseSystemId, null), 608 notation, fInExternalSubset); 609 fEntities.put(name, entity); 610 } 611 else{ 612 if(fWarnDuplicateEntityDef){ 613 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 614 "MSG_DUPLICATE_ENTITY_DEFINITION", 615 new Object []{ name }, 616 XMLErrorReporter.SEVERITY_WARNING ); 617 } 618 } 619 } 621 628 public boolean isUnparsedEntity(String entityName) { 629 630 Entity entity = (Entity)fEntities.get(entityName); 631 if (entity == null) { 632 return false; 633 } 634 return entity.isUnparsed(); 635 } 636 637 643 public boolean isDeclaredEntity(String entityName) { 644 645 Entity entity = (Entity)fEntities.get(entityName); 646 return entity != null; 647 } 648 649 671 public XMLInputSource resolveEntity(XMLResourceIdentifier resourceIdentifier) 672 throws IOException , XNIException { 673 if(resourceIdentifier == null ) return null; 674 String publicId = resourceIdentifier.getPublicId(); 675 String literalSystemId = resourceIdentifier.getLiteralSystemId(); 676 String baseSystemId = resourceIdentifier.getBaseSystemId(); 677 String expandedSystemId = resourceIdentifier.getExpandedSystemId(); 678 boolean needExpand = (expandedSystemId == null); 685 if (baseSystemId == null && fCurrentEntity != null && fCurrentEntity.entityLocation != null) { 689 baseSystemId = fCurrentEntity.entityLocation.getExpandedSystemId(); 690 if (baseSystemId != null) 691 needExpand = true; 692 } 693 if (needExpand) 694 expandedSystemId = expandSystemId(literalSystemId, baseSystemId, false); 695 696 XMLInputSource xmlInputSource = null; 698 if (fEntityResolver != null) { 699 resourceIdentifier.setBaseSystemId(baseSystemId); 700 resourceIdentifier.setExpandedSystemId(expandedSystemId); 701 xmlInputSource = fEntityResolver.resolveEntity(resourceIdentifier); 702 } 703 704 if (xmlInputSource == null) { 710 xmlInputSource = new XMLInputSource(publicId, literalSystemId, baseSystemId); 714 } 715 716 if (DEBUG_RESOLVER) { 717 System.err.println("XMLEntityManager.resolveEntity(" + publicId + ")"); 718 System.err.println(" = " + xmlInputSource); 719 } 720 721 return xmlInputSource; 722 723 } 725 735 public void startEntity(String entityName, boolean literal) 736 throws IOException , XNIException { 737 738 Entity entity = (Entity)fEntities.get(entityName); 740 if (entity == null) { 741 if (fEntityHandler != null) { 742 String encoding = null; 743 fResourceIdentifier.clear(); 744 fEntityAugs.removeAllItems(); 745 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 746 fEntityHandler.startEntity(entityName, fResourceIdentifier, encoding, fEntityAugs); 747 fEntityAugs.removeAllItems(); 748 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 749 fEntityHandler.endEntity(entityName, fEntityAugs); 750 } 751 return; 752 } 753 754 boolean external = entity.isExternal(); 756 if (external && (fValidationManager == null || !fValidationManager.isCachedDTD())) { 757 boolean unparsed = entity.isUnparsed(); 758 boolean parameter = entityName.startsWith("%"); 759 boolean general = !parameter; 760 if (unparsed || (general && !fExternalGeneralEntities) || 761 (parameter && !fExternalParameterEntities)) { 762 if (fEntityHandler != null) { 763 fResourceIdentifier.clear(); 764 final String encoding = null; 765 ExternalEntity externalEntity = (ExternalEntity)entity; 766 String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null); 770 String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null); 771 String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, false); 772 fResourceIdentifier.setValues( 773 (externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null), 774 extLitSysId, extBaseSysId, expandedSystemId); 775 fEntityAugs.removeAllItems(); 776 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 777 fEntityHandler.startEntity(entityName, fResourceIdentifier, encoding, fEntityAugs); 778 fEntityAugs.removeAllItems(); 779 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 780 fEntityHandler.endEntity(entityName, fEntityAugs); 781 } 782 return; 783 } 784 } 785 786 int size = fEntityStack.size(); 788 for (int i = size; i >= 0; i--) { 789 Entity activeEntity = i == size 790 ? fCurrentEntity 791 : (Entity)fEntityStack.elementAt(i); 792 if (activeEntity.name == entityName) { 793 String path = entityName; 794 for (int j = i + 1; j < size; j++) { 795 activeEntity = (Entity)fEntityStack.elementAt(j); 796 path = path + " -> " + activeEntity.name; 797 } 798 path = path + " -> " + fCurrentEntity.name; 799 path = path + " -> " + entityName; 800 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 801 "RecursiveReference", 802 new Object [] { entityName, path }, 803 XMLErrorReporter.SEVERITY_FATAL_ERROR); 804 if (fEntityHandler != null) { 805 fResourceIdentifier.clear(); 806 final String encoding = null; 807 if (external) { 808 ExternalEntity externalEntity = (ExternalEntity)entity; 809 String extLitSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getLiteralSystemId() : null); 811 String extBaseSysId = (externalEntity.entityLocation != null ? externalEntity.entityLocation.getBaseSystemId() : null); 812 String expandedSystemId = expandSystemId(extLitSysId, extBaseSysId, false); 813 fResourceIdentifier.setValues( 814 (externalEntity.entityLocation != null ? externalEntity.entityLocation.getPublicId() : null), 815 extLitSysId, extBaseSysId, expandedSystemId); 816 } 817 fEntityAugs.removeAllItems(); 818 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 819 fEntityHandler.startEntity(entityName, fResourceIdentifier, encoding, fEntityAugs); 820 fEntityAugs.removeAllItems(); 821 fEntityAugs.putItem(Constants.ENTITY_SKIPPED, Boolean.TRUE); 822 fEntityHandler.endEntity(entityName, fEntityAugs); 823 } 824 return; 825 } 826 } 827 828 XMLInputSource xmlInputSource = null; 830 if (external) { 831 ExternalEntity externalEntity = (ExternalEntity)entity; 832 xmlInputSource = resolveEntity(externalEntity.entityLocation); 833 } 834 835 else { 837 InternalEntity internalEntity = (InternalEntity)entity; 838 Reader reader = new StringReader (internalEntity.text); 839 xmlInputSource = new XMLInputSource(null, null, null, reader, null); 840 } 841 842 startEntity(entityName, xmlInputSource, literal, external); 844 845 } 847 856 public void startDocumentEntity(XMLInputSource xmlInputSource) 857 throws IOException , XNIException { 858 startEntity(XMLEntity, xmlInputSource, false, true); 859 } 861 870 public void startDTDEntity(XMLInputSource xmlInputSource) 871 throws IOException , XNIException { 872 startEntity(DTDEntity, xmlInputSource, false, true); 873 } 875 public void startExternalSubset() { 878 fInExternalSubset = true; 879 } 880 881 public void endExternalSubset() { 882 fInExternalSubset = false; 883 } 884 885 900 public void startEntity(String name, 901 XMLInputSource xmlInputSource, 902 boolean literal, boolean isExternal) 903 throws IOException , XNIException { 904 905 String encoding = setupCurrentEntity(name, xmlInputSource, literal, isExternal); 906 907 fEntityExpansionCount++; 912 if( fSecurityManager != null && fEntityExpansionCount > fEntityExpansionLimit ){ 913 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 914 "EntityExpansionLimitExceeded", 915 new Object []{new Integer (fEntityExpansionLimit) }, 916 XMLErrorReporter.SEVERITY_FATAL_ERROR ); 917 fEntityExpansionCount = 0; 921 } 922 923 if (fEntityHandler != null) { 925 fEntityHandler.startEntity(name, fResourceIdentifier, encoding, null); 926 } 927 928 } 930 943 public String setupCurrentEntity(String name, XMLInputSource xmlInputSource, 944 boolean literal, boolean isExternal) 945 throws IOException , XNIException { 946 948 final String publicId = xmlInputSource.getPublicId(); 949 String literalSystemId = xmlInputSource.getSystemId(); 950 String baseSystemId = xmlInputSource.getBaseSystemId(); 951 String encoding = xmlInputSource.getEncoding(); 952 Boolean isBigEndian = null; 953 boolean declaredEncoding = false; 954 955 InputStream stream = null; 957 Reader reader = xmlInputSource.getCharacterStream(); 958 String expandedSystemId = expandSystemId(literalSystemId, baseSystemId, fStrictURI); 960 if (baseSystemId == null) { 961 baseSystemId = expandedSystemId; 962 } 963 if (reader == null) { 964 stream = xmlInputSource.getByteStream(); 965 if(stream != null && encoding != null) 966 declaredEncoding = true; 967 if (stream == null) { 968 URL location = new URL (expandedSystemId); 969 URLConnection connect = location.openConnection(); 970 if (connect instanceof HttpURLConnection ) { 971 setHttpProperties(connect,xmlInputSource); 972 } 973 stream = connect.getInputStream(); 974 975 if (connect instanceof HttpURLConnection ) { 979 String redirect = connect.getURL().toString(); 980 if (!redirect.equals(expandedSystemId)) { 983 literalSystemId = redirect; 984 expandedSystemId = redirect; 985 } 986 } 987 } 988 stream = new RewindableInputStream(stream); 990 991 if (encoding == null) { 993 final byte[] b4 = new byte[4]; 995 int count = 0; 996 for (; count<4; count++ ) { 997 b4[count] = (byte)stream.read(); 998 } 999 if (count == 4) { 1000 Object [] encodingDesc = getEncodingName(b4, count); 1001 encoding = (String )(encodingDesc[0]); 1002 isBigEndian = (Boolean )(encodingDesc[1]); 1003 1004 stream.reset(); 1005 if (count > 2 && encoding.equals("UTF-8")) { 1009 int b0 = b4[0] & 0xFF; 1010 int b1 = b4[1] & 0xFF; 1011 int b2 = b4[2] & 0xFF; 1012 if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { 1013 stream.skip(3); 1015 } 1016 } 1017 reader = createReader(stream, encoding, isBigEndian); 1018 } 1019 else { 1020 reader = createReader(stream, encoding, isBigEndian); 1021 } 1022 } 1023 1024 else { 1026 encoding = encoding.toUpperCase(Locale.ENGLISH); 1027 1028 if (encoding.equals("UTF-8")) { 1030 final int[] b3 = new int[3]; 1031 int count = 0; 1032 for (; count < 3; ++count) { 1033 b3[count] = stream.read(); 1034 if (b3[count] == -1) 1035 break; 1036 } 1037 if (count == 3) { 1038 if (b3[0] != 0xEF || b3[1] != 0xBB || b3[2] != 0xBF) { 1039 stream.reset(); 1041 } 1042 } 1043 else { 1044 stream.reset(); 1045 } 1046 } 1047 else if (encoding.equals("ISO-10646-UCS-4")) { 1050 final int[] b4 = new int[4]; 1051 int count = 0; 1052 for (; count < 4; ++count) { 1053 b4[count] = stream.read(); 1054 if (b4[count] == -1) 1055 break; 1056 } 1057 stream.reset(); 1058 1059 if (count == 4) { 1061 if (b4[0] == 0x00 && b4[1] == 0x00 && b4[2] == 0x00 && b4[3] == 0x3C) { 1063 isBigEndian = Boolean.TRUE; 1064 } 1065 else if (b4[0] == 0x3C && b4[1] == 0x00 && b4[2] == 0x00 && b4[3] == 0x00) { 1067 isBigEndian = Boolean.FALSE; 1068 } 1069 } 1070 } 1071 else if (encoding.equals("ISO-10646-UCS-2")) { 1074 final int[] b4 = new int[4]; 1075 int count = 0; 1076 for (; count < 4; ++count) { 1077 b4[count] = stream.read(); 1078 if (b4[count] == -1) 1079 break; 1080 } 1081 stream.reset(); 1082 1083 if (count == 4) { 1084 if (b4[0] == 0x00 && b4[1] == 0x3C && b4[2] == 0x00 && b4[3] == 0x3F) { 1086 isBigEndian = Boolean.TRUE; 1087 } 1088 else if (b4[0] == 0x3C && b4[1] == 0x00 && b4[2] == 0x3F && b4[3] == 0x00) { 1090 isBigEndian = Boolean.FALSE; 1091 } 1092 } 1093 } 1094 1095 reader = createReader(stream, encoding, isBigEndian); 1096 } 1097 1098 if (DEBUG_ENCODINGS) { 1102 System.out.println("$$$ no longer wrapping reader in OneCharReader"); 1103 } 1104 } 1106 1107 fReaderStack.push(reader); 1110 1111 if (fCurrentEntity != null) { 1113 fEntityStack.push(fCurrentEntity); 1114 } 1115 1116 fCurrentEntity = new ScannedEntity(name, 1118 new XMLResourceIdentifierImpl(publicId, literalSystemId, baseSystemId, expandedSystemId), 1119 stream, reader, encoding, literal, false, isExternal); 1120 fCurrentEntity.setDeclaredEncoding(declaredEncoding); 1121 fEntityScanner.setCurrentEntity(fCurrentEntity); 1122 fResourceIdentifier.setValues(publicId, literalSystemId, baseSystemId, expandedSystemId); 1123 return encoding; 1124 } 1126 void setHttpProperties(URLConnection conn, XMLInputSource source ){ 1127 1128 if( source instanceof XIncludeInputSource ){ 1129 String fAccept = null; 1130 String fAcceptCharset = null; 1131 String fAcceptLanguage = null; 1132 1133 XIncludeInputSource xiSrc= (XIncludeInputSource)source; 1134 1135 fAccept = (String )xiSrc.getProperty(XIncludeHandler.HTTP_ACCEPT); 1136 fAcceptCharset = (String )xiSrc.getProperty(XIncludeHandler.HTTP_ACCEPT_CHARSET); 1137 fAcceptLanguage = (String )xiSrc.getProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE); 1138 1139 if( fAccept != null && fAccept.length() > 0) { 1140 conn.setRequestProperty(XIncludeHandler.HTTP_ACCEPT, fAccept); 1141 } 1142 if( fAcceptCharset != null && fAcceptCharset.length() > 0) { 1143 conn.setRequestProperty(XIncludeHandler.HTTP_ACCEPT_CHARSET, fAcceptCharset); 1144 } 1145 if( fAcceptLanguage != null && fAcceptLanguage.length() > 0) { 1146 conn.setRequestProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE, fAcceptLanguage); 1147 } 1148 } 1149 } 1150 1151 public void setScannerVersion(short version) { 1153 if(version == Constants.XML_VERSION_1_0) { 1154 if(fXML10EntityScanner == null) { 1155 fXML10EntityScanner = new XMLEntityScanner(); 1156 } 1157 fXML10EntityScanner.reset(fSymbolTable, this, fErrorReporter); 1158 fEntityScanner = fXML10EntityScanner; 1159 fEntityScanner.setCurrentEntity(fCurrentEntity); 1160 } else { 1161 if(fXML11EntityScanner == null) { 1162 fXML11EntityScanner = new XML11EntityScanner(); 1163 } 1164 fXML11EntityScanner.reset(fSymbolTable, this, fErrorReporter); 1165 fEntityScanner = fXML11EntityScanner; 1166 fEntityScanner.setCurrentEntity(fCurrentEntity); 1167 } 1168 } 1170 1171 public XMLEntityScanner getEntityScanner() { 1172 if(fEntityScanner == null) { 1173 if(fXML10EntityScanner == null) { 1175 fXML10EntityScanner = new XMLEntityScanner(); 1176 } 1177 fXML10EntityScanner.reset(fSymbolTable, this, fErrorReporter); 1178 fEntityScanner = fXML10EntityScanner; 1179 } 1180 return fEntityScanner; 1181 } 1183 protected Stack fReaderStack = new Stack (); 1185 1186 1189 public void closeReaders() { 1190 for (int i = fReaderStack.size()-1; i >= 0; i--) { 1192 try { 1193 ((Reader )fReaderStack.pop()).close(); 1194 } catch (IOException e) { 1195 } 1197 } 1198 } 1199 1200 1204 1218 public void reset(XMLComponentManager componentManager) 1219 throws XMLConfigurationException { 1220 1221 boolean parser_settings; 1222 try { 1223 parser_settings = componentManager.getFeature(PARSER_SETTINGS); 1224 } catch (XMLConfigurationException e) { 1225 parser_settings = true; 1226 } 1227 1228 if (!parser_settings) { 1229 reset(); 1231 return; 1232 } 1233 1234 try { 1236 fValidation = componentManager.getFeature(VALIDATION); 1237 } 1238 catch (XMLConfigurationException e) { 1239 fValidation = false; 1240 } 1241 try { 1242 fExternalGeneralEntities = componentManager.getFeature(EXTERNAL_GENERAL_ENTITIES); 1243 } 1244 catch (XMLConfigurationException e) { 1245 fExternalGeneralEntities = true; 1246 } 1247 try { 1248 fExternalParameterEntities = componentManager.getFeature(EXTERNAL_PARAMETER_ENTITIES); 1249 } 1250 catch (XMLConfigurationException e) { 1251 fExternalParameterEntities = true; 1252 } 1253 1254 try { 1256 fAllowJavaEncodings = componentManager.getFeature(ALLOW_JAVA_ENCODINGS); 1257 } 1258 catch (XMLConfigurationException e) { 1259 fAllowJavaEncodings = false; 1260 } 1261 1262 try { 1263 fWarnDuplicateEntityDef = componentManager.getFeature(WARN_ON_DUPLICATE_ENTITYDEF); 1264 } 1265 catch (XMLConfigurationException e) { 1266 fWarnDuplicateEntityDef = false; 1267 } 1268 1269 try { 1270 fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT); 1271 } 1272 catch (XMLConfigurationException e) { 1273 fStrictURI = false; 1274 } 1275 try { 1276 fCharsetOverrideXmlEncoding = componentManager.getFeature(Constants.DOM_CHARSET_OVERRIDES_XML_ENCODING); 1277 } 1278 catch (XMLConfigurationException e) { 1279 fCharsetOverrideXmlEncoding = true; 1280 } 1281 fSymbolTable = (SymbolTable)componentManager.getProperty(SYMBOL_TABLE); 1283 fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); 1284 try { 1285 fEntityResolver = (XMLEntityResolver)componentManager.getProperty(ENTITY_RESOLVER); 1286 } 1287 catch (XMLConfigurationException e) { 1288 fEntityResolver = null; 1289 } 1290 try { 1291 fValidationManager = (ValidationManager)componentManager.getProperty(VALIDATION_MANAGER); 1292 } 1293 catch (XMLConfigurationException e) { 1294 fValidationManager = null; 1295 } 1296 try { 1297 fSecurityManager = (SecurityManager )componentManager.getProperty(SECURITY_MANAGER); 1298 } 1299 catch (XMLConfigurationException e) { 1300 fSecurityManager = null; 1301 } 1302 1303 reset(); 1305 1306 } 1308 public void reset() { 1312 fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; 1313 1314 fStandalone = false; 1316 fEntities.clear(); 1317 fEntityStack.removeAllElements(); 1318 fEntityExpansionCount = 0; 1319 1320 fCurrentEntity = null; 1321 if(fXML10EntityScanner != null){ 1323 fXML10EntityScanner.reset(fSymbolTable, this, fErrorReporter); 1324 } 1325 if(fXML11EntityScanner != null) { 1326 fXML11EntityScanner.reset(fSymbolTable, this, fErrorReporter); 1327 } 1328 1329 if (DEBUG_ENTITIES) { 1331 addInternalEntity("text", "Hello, World."); 1332 addInternalEntity("empty-element", "<foo/>"); 1333 addInternalEntity("balanced-element", "<foo></foo>"); 1334 addInternalEntity("balanced-element-with-text", "<foo>Hello, World</foo>"); 1335 addInternalEntity("balanced-element-with-entity", "<foo>&text;</foo>"); 1336 addInternalEntity("unbalanced-entity", "<foo>"); 1337 addInternalEntity("recursive-entity", "<foo>&recursive-entity2;</foo>"); 1338 addInternalEntity("recursive-entity2", "<bar>&recursive-entity3;</bar>"); 1339 addInternalEntity("recursive-entity3", "<baz>&recursive-entity;</baz>"); 1340 try { 1341 addExternalEntity("external-text", null, "external-text.ent", "test/external-text.xml"); 1342 addExternalEntity("external-balanced-element", null, "external-balanced-element.ent", "test/external-balanced-element.xml"); 1343 addExternalEntity("one", null, "ent/one.ent", "test/external-entity.xml"); 1344 addExternalEntity("two", null, "ent/two.ent", "test/ent/one.xml"); 1345 } 1346 catch (IOException ex) { 1347 } 1349 } 1350 1351 if (fDeclaredEntities != null) { 1353 java.util.Enumeration keys = fDeclaredEntities.keys(); 1354 while (keys.hasMoreElements()) { 1355 Object key = keys.nextElement(); 1356 Object value = fDeclaredEntities.get(key); 1357 fEntities.put(key, value); 1358 } 1359 } 1360 fEntityHandler = null; 1361 1362 } 1364 1369 public String [] getRecognizedFeatures() { 1370 return (String [])(RECOGNIZED_FEATURES.clone()); 1371 } 1373 1388 public void setFeature(String featureId, boolean state) 1389 throws XMLConfigurationException { 1390 1391 if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { 1393 final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); 1394 if (suffixLength == Constants.ALLOW_JAVA_ENCODINGS_FEATURE.length() && 1395 featureId.endsWith(Constants.ALLOW_JAVA_ENCODINGS_FEATURE)) { 1396 fAllowJavaEncodings = state; 1397 } 1398 } 1399 1400 } 1402 1407 public String [] getRecognizedProperties() { 1408 return (String [])(RECOGNIZED_PROPERTIES.clone()); 1409 } 1411 1426 public void setProperty(String propertyId, Object value) 1427 throws XMLConfigurationException { 1428 1429 if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { 1431 final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); 1432 1433 if (suffixLength == Constants.SYMBOL_TABLE_PROPERTY.length() && 1434 propertyId.endsWith(Constants.SYMBOL_TABLE_PROPERTY)) { 1435 fSymbolTable = (SymbolTable)value; 1436 return; 1437 } 1438 if (suffixLength == Constants.ERROR_REPORTER_PROPERTY.length() && 1439 propertyId.endsWith(Constants.ERROR_REPORTER_PROPERTY)) { 1440 fErrorReporter = (XMLErrorReporter)value; 1441 return; 1442 } 1443 if (suffixLength == Constants.ENTITY_RESOLVER_PROPERTY.length() && 1444 propertyId.endsWith(Constants.ENTITY_RESOLVER_PROPERTY)) { 1445 fEntityResolver = (XMLEntityResolver)value; 1446 return; 1447 } 1448 if (suffixLength == Constants.BUFFER_SIZE_PROPERTY.length() && 1449 propertyId.endsWith(Constants.BUFFER_SIZE_PROPERTY)) { 1450 Integer bufferSize = (Integer )value; 1451 if (bufferSize != null && 1452 bufferSize.intValue() > DEFAULT_XMLDECL_BUFFER_SIZE) { 1453 fBufferSize = bufferSize.intValue(); 1454 fEntityScanner.setBufferSize(fBufferSize); 1455 } 1456 } 1457 if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && 1458 propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) { 1459 fSecurityManager = (SecurityManager )value; 1460 fEntityExpansionLimit = (fSecurityManager != null)?fSecurityManager.getEntityExpansionLimit():0; 1461 } 1462 } 1463 1464 } 1466 1475 public Boolean getFeatureDefault(String featureId) { 1476 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { 1477 if (RECOGNIZED_FEATURES[i].equals(featureId)) { 1478 return FEATURE_DEFAULTS[i]; 1479 } 1480 } 1481 return null; 1482 } 1484 1493 public Object getPropertyDefault(String propertyId) { 1494 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { 1495 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { 1496 return PROPERTY_DEFAULTS[i]; 1497 } 1498 } 1499 return null; 1500 } 1502 1506 private static String gUserDir; 1508 private static String gEscapedUserDir; 1510 private static boolean gNeedEscaping[] = new boolean[128]; 1512 private static char gAfterEscaping1[] = new char[128]; 1514 private static char gAfterEscaping2[] = new char[128]; 1516 private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', 1517 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; 1518 static { 1520 for (int i = 0; i <= 0x1f; i++) { 1521 gNeedEscaping[i] = true; 1522 gAfterEscaping1[i] = gHexChs[i >> 4]; 1523 gAfterEscaping2[i] = gHexChs[i & 0xf]; 1524 } 1525 gNeedEscaping[0x7f] = true; 1526 gAfterEscaping1[0x7f] = '7'; 1527 gAfterEscaping2[0x7f] = 'F'; 1528 char[] escChs = {' ', '<', '>', '#', '%', '"', '{', '}', 1529 '|', '\\', '^', '~', '[', ']', '`'}; 1530 int len = escChs.length; 1531 char ch; 1532 for (int i = 0; i < len; i++) { 1533 ch = escChs[i]; 1534 gNeedEscaping[ch] = true; 1535 gAfterEscaping1[ch] = gHexChs[ch >> 4]; 1536 gAfterEscaping2[ch] = gHexChs[ch & 0xf]; 1537 } 1538 } 1539 private static synchronized String getUserDir() { 1550 String userDir = ""; 1552 try { 1553 userDir = System.getProperty("user.dir"); 1554 } 1555 catch (SecurityException se) { 1556 } 1557 1558 if (userDir.length() == 0) 1560 return ""; 1561 1562 if (userDir.equals(gUserDir)) { 1565 return gEscapedUserDir; 1566 } 1567 1568 gUserDir = userDir; 1570 1571 char separator = java.io.File.separatorChar; 1572 userDir = userDir.replace(separator, '/'); 1573 1574 int len = userDir.length(), ch; 1575 StringBuffer buffer = new StringBuffer (len*3); 1576 if (len >= 2 && userDir.charAt(1) == ':') { 1578 ch = Character.toUpperCase(userDir.charAt(0)); 1579 if (ch >= 'A' && ch <= 'Z') { 1580 buffer.append('/'); 1581 } 1582 } 1583 1584 int i = 0; 1586 for (; i < len; i++) { 1587 ch = userDir.charAt(i); 1588 if (ch >= 128) 1590 break; 1591 if (gNeedEscaping[ch]) { 1592 buffer.append('%'); 1593 buffer.append(gAfterEscaping1[ch]); 1594 buffer.append(gAfterEscaping2[ch]); 1595 } 1597 else { 1598 buffer.append((char)ch); 1599 } 1600 } 1601 1602 if (i < len) { 1604 byte[] bytes = null; 1606 byte b; 1607 try { 1608 bytes = userDir.substring(i).getBytes("UTF-8"); 1609 } catch (java.io.UnsupportedEncodingException e) { 1610 return userDir; 1612 } 1613 len = bytes.length; 1614 1615 for (i = 0; i < len; i++) { 1617 b = bytes[i]; 1618 if (b < 0) { 1620 ch = b + 256; 1621 buffer.append('%'); 1622 buffer.append(gHexChs[ch >> 4]); 1623 buffer.append(gHexChs[ch & 0xf]); 1624 } 1625 else if (gNeedEscaping[b]) { 1626 buffer.append('%'); 1627 buffer.append(gAfterEscaping1[b]); 1628 buffer.append(gAfterEscaping2[b]); 1629 } 1630 else { 1631 buffer.append((char)b); 1632 } 1633 } 1634 } 1635 1636 if (!userDir.endsWith("/")) 1638 buffer.append('/'); 1639 1640 gEscapedUserDir = buffer.toString(); 1641 1642 return gEscapedUserDir; 1643 } 1644 1645 1658 public static String expandSystemId(String systemId, String baseSystemId, 1659 boolean strict) 1660 throws URI.MalformedURIException { 1661 1662 if (strict) { 1664 1665 if (systemId == null) { 1668 return null; 1669 } 1670 1671 try { 1672 new URI(systemId); 1674 return systemId; 1675 } 1676 catch (URI.MalformedURIException ex) { 1677 } 1678 URI base = null; 1679 if (baseSystemId == null || baseSystemId.length() == 0) { 1681 base = new URI("file", "", getUserDir(), null, null); 1682 } 1683 else { 1685 try { 1686 base = new URI(baseSystemId); 1687 } 1688 catch (URI.MalformedURIException e) { 1689 String dir = getUserDir(); 1691 dir = dir + baseSystemId; 1692 base = new URI("file", "", dir, null, null); 1693 } 1694 } 1695 URI uri = new URI(base, systemId); 1697 return uri.toString(); 1699 1700 } 1702 1703 if (systemId == null || systemId.length() == 0) { 1705 return systemId; 1706 } 1707 try { 1709 URI uri = new URI(systemId.trim()); 1710 if (uri != null) { 1711 return systemId; 1712 } 1713 } 1714 catch (URI.MalformedURIException e) { 1715 } 1717 String id = fixURI(systemId); 1719 1720 URI base = null; 1722 URI uri = null; 1723 try { 1724 if (baseSystemId == null || baseSystemId.length() == 0 || 1725 baseSystemId.equals(systemId)) { 1726 String dir = getUserDir(); 1727 base = new URI("file", "", dir, null, null); 1728 } 1729 else { 1730 try { 1731 base = new URI(fixURI(baseSystemId).trim()); 1732 } 1733 catch (URI.MalformedURIException e) { 1734 if (baseSystemId.indexOf(':') != -1) { 1735 base = new URI("file", "", fixURI(baseSystemId).trim(), null, null); 1738 } 1739 else { 1740 String dir = getUserDir(); 1741 dir = dir + fixURI(baseSystemId); 1742 base = new URI("file", "", dir, null, null); 1743 } 1744 } 1745 } 1746 uri = new URI(base, id.trim()); 1748 } 1749 catch (Exception e) { 1750 1752 } 1753 1754 if (uri == null) { 1755 return systemId; 1756 } 1757 return uri.toString(); 1758 1759 } 1761 1765 1770 void endEntity() throws XNIException { 1771 1772 if (DEBUG_BUFFER) { 1774 System.out.print("(endEntity: "); 1775 print(fCurrentEntity); 1776 System.out.println(); 1777 } 1778 if (fEntityHandler != null) { 1779 fEntityHandler.endEntity(fCurrentEntity.name, null); 1780 } 1781 1782 try { 1787 fCurrentEntity.reader.close(); 1788 } 1789 catch (IOException e) { 1790 } 1792 if(!fReaderStack.isEmpty()) { 1796 fReaderStack.pop(); 1797 } 1798 1799 fCurrentEntity = fEntityStack.size() > 0 1801 ? (ScannedEntity)fEntityStack.pop() : null; 1802 fEntityScanner.setCurrentEntity(fCurrentEntity); 1803 if (DEBUG_BUFFER) { 1804 System.out.print(")endEntity: "); 1805 print(fCurrentEntity); 1806 System.out.println(); 1807 } 1808 1809 1811 } 1813 1823 protected Object [] getEncodingName(byte[] b4, int count) { 1824 1825 if (count < 2) { 1826 return new Object []{"UTF-8", null}; 1827 } 1828 1829 int b0 = b4[0] & 0xFF; 1831 int b1 = b4[1] & 0xFF; 1832 if (b0 == 0xFE && b1 == 0xFF) { 1833 return new Object [] {"UTF-16BE", new Boolean (true)}; 1835 } 1836 if (b0 == 0xFF && b1 == 0xFE) { 1837 return new Object [] {"UTF-16LE", new Boolean (false)}; 1839 } 1840 1841 if (count < 3) { 1844 return new Object [] {"UTF-8", null}; 1845 } 1846 1847 int b2 = b4[2] & 0xFF; 1849 if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF) { 1850 return new Object [] {"UTF-8", null}; 1851 } 1852 1853 if (count < 4) { 1856 return new Object [] {"UTF-8", null}; 1857 } 1858 1859 int b3 = b4[3] & 0xFF; 1861 if (b0 == 0x00 && b1 == 0x00 && b2 == 0x00 && b3 == 0x3C) { 1862 return new Object [] {"ISO-10646-UCS-4", new Boolean (true)}; 1864 } 1865 if (b0 == 0x3C && b1 == 0x00 && b2 == 0x00 && b3 == 0x00) { 1866 return new Object [] {"ISO-10646-UCS-4", new Boolean (false)}; 1868 } 1869 if (b0 == 0x00 && b1 == 0x00 && b2 == 0x3C && b3 == 0x00) { 1870 return new Object [] {"ISO-10646-UCS-4", null}; 1873 } 1874 if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x00) { 1875 return new Object [] {"ISO-10646-UCS-4", null}; 1878 } 1879 if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F) { 1880 return new Object [] {"UTF-16BE", new Boolean (true)}; 1884 } 1885 if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00) { 1886 return new Object [] {"UTF-16LE", new Boolean (false)}; 1889 } 1890 if (b0 == 0x4C && b1 == 0x6F && b2 == 0xA7 && b3 == 0x94) { 1891 return new Object [] {"CP037", null}; 1894 } 1895 1896 return new Object [] {"UTF-8", null}; 1898 1899 } 1901 1917 protected Reader createReader(InputStream inputStream, String encoding, Boolean isBigEndian) 1918 throws IOException { 1919 1920 if (encoding == null) { 1922 encoding = "UTF-8"; 1923 } 1924 1925 String ENCODING = encoding.toUpperCase(Locale.ENGLISH); 1927 if (ENCODING.equals("UTF-8")) { 1928 if (DEBUG_ENCODINGS) { 1929 System.out.println("$$$ creating UTF8Reader"); 1930 } 1931 return new UTF8Reader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale() ); 1932 } 1933 if(ENCODING.equals("ISO-10646-UCS-4")) { 1934 if(isBigEndian != null) { 1935 boolean isBE = isBigEndian.booleanValue(); 1936 if(isBE) { 1937 return new UCSReader(inputStream, UCSReader.UCS4BE); 1938 } else { 1939 return new UCSReader(inputStream, UCSReader.UCS4LE); 1940 } 1941 } else { 1942 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 1943 "EncodingByteOrderUnsupported", 1944 new Object [] { encoding }, 1945 XMLErrorReporter.SEVERITY_FATAL_ERROR); 1946 } 1947 } 1948 if(ENCODING.equals("ISO-10646-UCS-2")) { 1949 if(isBigEndian != null) { boolean isBE = isBigEndian.booleanValue(); 1951 if(isBE) { 1952 return new UCSReader(inputStream, UCSReader.UCS2BE); 1953 } else { 1954 return new UCSReader(inputStream, UCSReader.UCS2LE); 1955 } 1956 } else { 1957 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 1958 "EncodingByteOrderUnsupported", 1959 new Object [] { encoding }, 1960 XMLErrorReporter.SEVERITY_FATAL_ERROR); 1961 } 1962 } 1963 1964 boolean validIANA = XMLChar.isValidIANAEncoding(encoding); 1966 boolean validJava = XMLChar.isValidJavaEncoding(encoding); 1967 if (!validIANA || (fAllowJavaEncodings && !validJava)) { 1968 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 1969 "EncodingDeclInvalid", 1970 new Object [] { encoding }, 1971 XMLErrorReporter.SEVERITY_FATAL_ERROR); 1972 encoding = "ISO-8859-1"; 1981 } 1982 1983 String javaEncoding = EncodingMap.getIANA2JavaMapping(ENCODING); 1985 if (javaEncoding == null) { 1986 if(fAllowJavaEncodings) { 1987 javaEncoding = encoding; 1988 } else { 1989 fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, 1990 "EncodingDeclInvalid", 1991 new Object [] { encoding }, 1992 XMLErrorReporter.SEVERITY_FATAL_ERROR); 1993 javaEncoding = "ISO8859_1"; 1995 } 1996 } 1997 else if (javaEncoding.equals("ASCII")) { 1998 if (DEBUG_ENCODINGS) { 1999 System.out.println("$$$ creating ASCIIReader"); 2000 } 2001 return new ASCIIReader(inputStream, fBufferSize, fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN), fErrorReporter.getLocale()); 2002 } 2003 2004 2005 if (DEBUG_ENCODINGS) { 2006 System.out.print("$$$ creating Java InputStreamReader: encoding="+javaEncoding); 2007 if (javaEncoding == encoding) { 2008 System.out.print(" (IANA encoding)"); 2009 } 2010 System.out.println(); 2011 } 2012 return new InputStreamReader (inputStream, javaEncoding); 2013 2014 } 2016 2020 2027 protected static String fixURI(String str) { 2028 2029 str = str.replace(java.io.File.separatorChar, '/'); 2031 2032 StringBuffer sb = null; 2033 2034 if (str.length() >= 2) { 2036 char ch1 = str.charAt(1); 2037 if (ch1 == ':') { 2039 char ch0 = Character.toUpperCase(str.charAt(0)); 2040 if (ch0 >= 'A' && ch0 <= 'Z') { 2041 sb = new StringBuffer (str.length()); 2042 sb.append('/'); 2043 } 2044 } 2045 else if (ch1 == '/' && str.charAt(0) == '/') { 2047 sb = new StringBuffer (str.length()); 2048 sb.append("file:"); 2049 } 2050 } 2051 2052 int pos = str.indexOf(' '); 2053 if (pos < 0) { 2056 if (sb != null) { 2057 sb.append(str); 2058 str = sb.toString(); 2059 } 2060 } 2061 else { 2065 if (sb == null) 2066 sb = new StringBuffer (str.length()); 2067 for (int i = 0; i < pos; i++) 2069 sb.append(str.charAt(i)); 2070 sb.append("%20"); 2072 for (int i = pos+1; i < str.length(); i++) { 2074 if (str.charAt(i) == ' ') 2075 sb.append("%20"); 2076 else 2077 sb.append(str.charAt(i)); 2078 } 2079 str = sb.toString(); 2080 } 2081 2082 return str; 2084 2085 } 2087 2091 2099 Hashtable getDeclaredEntities() { 2100 return fEntities; 2101 } 2103 2104 static final void print(ScannedEntity currentEntity) { 2105 if (DEBUG_BUFFER) { 2106 if (currentEntity != null) { 2107 System.out.print('['); 2108 System.out.print(currentEntity.count); 2109 System.out.print(' '); 2110 System.out.print(currentEntity.position); 2111 if (currentEntity.count > 0) { 2112 System.out.print(" \""); 2113 for (int i = 0; i < currentEntity.count; i++) { 2114 if (i == currentEntity.position) { 2115 System.out.print('^'); 2116 } 2117 char c = currentEntity.ch[i]; 2118 switch (c) { 2119 case '\n': { 2120 System.out.print("\\n"); 2121 break; 2122 } 2123 case '\r': { 2124 System.out.print("\\r"); 2125 break; 2126 } 2127 case '\t': { 2128 System.out.print("\\t"); 2129 break; 2130 } 2131 case '\\': { 2132 System.out.print("\\\\"); 2133 break; 2134 } 2135 default: { 2136 System.out.print(c); 2137 } 2138 } 2139 } 2140 if (currentEntity.position == currentEntity.count) { 2141 System.out.print('^'); 2142 } 2143 System.out.print('"'); 2144 } 2145 System.out.print(']'); 2146 System.out.print(" @ "); 2147 System.out.print(currentEntity.lineNumber); 2148 System.out.print(','); 2149 System.out.print(currentEntity.columnNumber); 2150 } 2151 else { 2152 System.out.print("*NO CURRENT ENTITY*"); 2153 } 2154 } 2155 } 2157 2161 2166 public static abstract class Entity { 2167 2168 2172 2173 public String name; 2174 2175 public boolean inExternalSubset; 2178 2179 2183 2184 public Entity() { 2185 clear(); 2186 } 2188 2189 public Entity(String name, boolean inExternalSubset) { 2190 this.name = name; 2191 this.inExternalSubset = inExternalSubset; 2192 } 2194 2198 2199 public boolean isEntityDeclInExternalSubset () { 2200 return inExternalSubset; 2201 } 2202 2203 2204 public abstract boolean isExternal(); 2205 2206 2207 public abstract boolean isUnparsed(); 2208 2209 2210 public void clear() { 2211 name = null; 2212 inExternalSubset = false; 2213 } 2215 2216 public void setValues(Entity entity) { 2217 name = entity.name; 2218 inExternalSubset = entity.inExternalSubset; 2219 } 2221 } 2223 2228 protected static class InternalEntity 2229 extends Entity { 2230 2231 2235 2236 public String text; 2237 2238 2242 2243 public InternalEntity() { 2244 clear(); 2245 } 2247 2248 public InternalEntity(String name, String text, boolean inExternalSubset) { 2249 super(name,inExternalSubset); 2250 this.text = text; 2251 } 2253 2257 2258 public final boolean isExternal() { 2259 return false; 2260 } 2262 2263 public final boolean isUnparsed() { 2264 return false; 2265 } 2267 2268 public void clear() { 2269 super.clear(); 2270 text = null; 2271 } 2273 2274 public void setValues(Entity entity) { 2275 super.setValues(entity); 2276 text = null; 2277 } 2279 2280 public void setValues(InternalEntity entity) { 2281 super.setValues(entity); 2282 text = entity.text; 2283 } 2285 } 2287 2292 protected static class ExternalEntity 2293 extends Entity { 2294 2295 2299 2300 public XMLResourceIdentifier entityLocation; 2301 2302 2303 public String notation; 2304 2305 2309 2310 public ExternalEntity() { 2311 clear(); 2312 } 2314 2315 public ExternalEntity(String name, XMLResourceIdentifier entityLocation, 2316 String notation, boolean inExternalSubset) { 2317 super(name,inExternalSubset); 2318 this.entityLocation = entityLocation; 2319 this.notation = notation; 2320 } 2322 2326 2327 public final boolean isExternal() { 2328 return true; 2329 } 2331 2332 public final boolean isUnparsed() { 2333 return notation != null; 2334 } 2336 2337 public void clear() { 2338 super.clear(); 2339 entityLocation = null; 2340 notation = null; 2341 } 2343 2344 public void setValues(Entity entity) { 2345 super.setValues(entity); 2346 entityLocation = null; 2347 notation = null; 2348 } 2350 2351 public void setValues(ExternalEntity entity) { 2352 super.setValues(entity); 2353 entityLocation = entity.entityLocation; 2354 notation = entity.notation; 2355 } 2357 } 2359 2364 public class ScannedEntity 2365 extends Entity { 2366 2367 2371 2373 2374 public InputStream stream; 2375 2376 2377 public Reader reader; 2378 2379 2381 2382 public XMLResourceIdentifier entityLocation; 2383 2384 2385 public int lineNumber = 1; 2386 2387 2388 public int columnNumber = 1; 2389 2390 2392 2393 public String encoding; 2394 2395 2396 boolean declaredEncoding = false; 2397 2398 2400 2401 public boolean literal; 2402 2403 public boolean isExternal; 2405 2406 2408 2409 public char[] ch = null; 2410 2411 2412 public int position; 2413 2414 2415 public int count; 2416 2417 public boolean mayReadChunks; 2419 2420 2424 2425 public ScannedEntity(String name, 2426 XMLResourceIdentifier entityLocation, 2427 InputStream stream, Reader reader, 2428 String encoding, boolean literal, boolean mayReadChunks, boolean isExternal) { 2429 super(name,XMLEntityManager.this.fInExternalSubset); 2430 this.entityLocation = entityLocation; 2431 this.stream = stream; 2432 this.reader = reader; 2433 this.encoding = encoding; 2434 this.literal = literal; 2435 this.mayReadChunks = mayReadChunks; 2436 this.isExternal = isExternal; 2437 this.ch = new char[isExternal ? fBufferSize : DEFAULT_INTERNAL_BUFFER_SIZE]; 2438 } 2440 2444 2445 public final boolean isExternal() { 2446 return isExternal; 2447 } 2449 2450 public final boolean isUnparsed() { 2451 return false; 2452 } 2454 public void setReader(InputStream stream, String encoding, Boolean isBigEndian) throws IOException { 2455 reader = createReader(stream, encoding, isBigEndian); 2456 } 2457 2458 public String getExpandedSystemId() { 2462 2463 int size = fEntityStack.size(); 2465 for (int i = size - 1; i >= 0 ; i--) { 2466 ScannedEntity externalEntity = 2467 (ScannedEntity)fEntityStack.elementAt(i); 2468 2469 if (externalEntity.entityLocation != null && 2470 externalEntity.entityLocation.getExpandedSystemId() != null) { 2471 return externalEntity.entityLocation.getExpandedSystemId(); 2472 } 2473 } 2474 return null; 2475 } 2476 2477 public String getLiteralSystemId() { 2480 int size = fEntityStack.size(); 2482 for (int i = size - 1; i >= 0 ; i--) { 2483 ScannedEntity externalEntity = 2484 (ScannedEntity)fEntityStack.elementAt(i); 2485 2486 if (externalEntity.entityLocation != null && 2487 externalEntity.entityLocation.getLiteralSystemId() != null) { 2488 return externalEntity.entityLocation.getLiteralSystemId(); 2489 } 2490 } 2491 return null; 2492 } 2493 2494 public int getLineNumber() { 2497 int size = fEntityStack.size(); 2499 for (int i=size-1; i>0 ; i--) { 2500 ScannedEntity firstExternalEntity = (ScannedEntity)fEntityStack.elementAt(i); 2501 if (firstExternalEntity.isExternal()) { 2502 return firstExternalEntity.lineNumber; 2503 } 2504 } 2505 return -1; 2506 } 2507 2508 public int getColumnNumber() { 2511 int size = fEntityStack.size(); 2513 for (int i=size-1; i>0 ; i--) { 2514 ScannedEntity firstExternalEntity = (ScannedEntity)fEntityStack.elementAt(i); 2515 if (firstExternalEntity.isExternal()) { 2516 return firstExternalEntity.columnNumber; 2517 } 2518 } 2519 return -1; 2520 } 2521 2522 public String getEncoding() { 2524 int size = fEntityStack.size(); 2526 for (int i=size-1; i>0 ; i--) { 2527 ScannedEntity firstExternalEntity = (ScannedEntity)fEntityStack.elementAt(i); 2528 if (firstExternalEntity.isExternal()) { 2529 return firstExternalEntity.encoding; 2530 } 2531 } 2532 return null; 2533 } 2534 2535 2539 2540 public String toString() { 2541 2542 StringBuffer str = new StringBuffer (); 2543 str.append("name=\""+name+'"'); 2544 str.append(",ch="); 2545 str.append(ch); 2546 str.append(",position="+position); 2547 str.append(",count="+count); 2548 return str.toString(); 2549 2550 } 2552 public boolean isDeclaredEncoding() { 2553 return declaredEncoding; 2554 } 2555 2556 public void setDeclaredEncoding(boolean value) { 2557 declaredEncoding = value; 2558 } 2559 2560 } 2562 2581 protected final class RewindableInputStream extends InputStream { 2582 2583 private InputStream fInputStream; 2584 private byte[] fData; 2585 private int fStartOffset; 2586 private int fEndOffset; 2587 private int fOffset; 2588 private int fLength; 2589 private int fMark; 2590 2591 public RewindableInputStream(InputStream is) { 2592 fData = new byte[DEFAULT_XMLDECL_BUFFER_SIZE]; 2593 fInputStream = is; 2594 fStartOffset = 0; 2595 fEndOffset = -1; 2596 fOffset = 0; 2597 fLength = 0; 2598 fMark = 0; 2599 } 2600 2601 public void setStartOffset(int offset) { 2602 fStartOffset = offset; 2603 } 2604 2605 public void rewind() { 2606 fOffset = fStartOffset; 2607 } 2608 2609 public int read() throws IOException { 2610 int b = 0; 2611 if (fOffset < fLength) { 2612 return fData[fOffset++] & 0xff; 2613 } 2614 if (fOffset == fEndOffset) { 2615 return -1; 2616 } 2617 if (fOffset == fData.length) { 2618 byte[] newData = new byte[fOffset << 1]; 2619 System.arraycopy(fData, 0, newData, 0, fOffset); 2620 fData = newData; 2621 } 2622 b = fInputStream.read(); 2623 if (b == -1) { 2624 fEndOffset = fOffset; 2625 return -1; 2626 } 2627 fData[fLength++] = (byte)b; 2628 fOffset++; 2629 return b & 0xff; 2630 } 2631 2632 public int read(byte[] b, int off, int len) throws IOException { 2633 int bytesLeft = fLength - fOffset; 2634 if (bytesLeft == 0) { 2635 if (fOffset == fEndOffset) { 2636 return -1; 2637 } 2638 if(fCurrentEntity.mayReadChunks) { 2640 return fInputStream.read(b, off, len); 2641 } 2642 int returnedVal = read(); 2643 if(returnedVal == -1) { 2644 fEndOffset = fOffset; 2645 return -1; 2646 } 2647 b[off] = (byte)returnedVal; 2648 return 1; 2649 } 2650 if (len < bytesLeft) { 2651 if (len <= 0) { 2652 return 0; 2653 } 2654 } 2655 else { 2656 len = bytesLeft; 2657 } 2658 if (b != null) { 2659 System.arraycopy(fData, fOffset, b, off, len); 2660 } 2661 fOffset += len; 2662 return len; 2663 } 2664 2665 public long skip(long n) 2666 throws IOException 2667 { 2668 int bytesLeft; 2669 if (n <= 0) { 2670 return 0; 2671 } 2672 bytesLeft = fLength - fOffset; 2673 if (bytesLeft == 0) { 2674 if (fOffset == fEndOffset) { 2675 return 0; 2676 } 2677 return fInputStream.skip(n); 2678 } 2679 if (n <= bytesLeft) { 2680 fOffset += n; 2681 return n; 2682 } 2683 fOffset += bytesLeft; 2684 if (fOffset == fEndOffset) { 2685 return bytesLeft; 2686 } 2687 n -= bytesLeft; 2688 2696 return fInputStream.skip(n) + bytesLeft; 2697 } 2698 2699 public int available() throws IOException { 2700 int bytesLeft = fLength - fOffset; 2701 if (bytesLeft == 0) { 2702 if (fOffset == fEndOffset) { 2703 return -1; 2704 } 2705 return fCurrentEntity.mayReadChunks ? fInputStream.available() 2706 : 0; 2707 } 2708 return bytesLeft; 2709 } 2710 2711 public void mark(int howMuch) { 2712 fMark = fOffset; 2713 } 2714 2715 public void reset() { 2716 fOffset = fMark; 2717 } 2718 2719 public boolean markSupported() { 2720 return true; 2721 } 2722 2723 public void close() throws IOException { 2724 if (fInputStream != null) { 2725 fInputStream.close(); 2726 fInputStream = null; 2727 } 2728 } 2729 } 2731} | Popular Tags |