50 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
51 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
52 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
53 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
54 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
55 import com.sun.org.apache.xerces.internal.xni.XMLString;
56 import com.sun.org.apache.xerces.internal.xni.XNIException;
57 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
58 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
59 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
60 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDFilter;
61 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
62 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
63 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
64 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
65 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
66 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
67 import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler;
68 import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor;
69 import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
70
71 /**
72 * <p>
73 * This is a pipeline component which performs XInclude handling, according to the
74 * W3C specification for XML Inclusions.
75 * </p>
76 * <p>
77 * This component analyzes each event in the pipeline, looking for <include>
78 * elements. An <include> element is one which has a namespace of
79 * <code>http://www.w3.org/2001/XInclude</code> and a localname of <code>include</code>.
80 * When it finds an <include> element, it attempts to include the file specified
81 * in the <code>href</code> attribute of the element. If inclusion succeeds, all
82 * children of the <include> element are ignored (with the exception of
83 * checking for invalid children as outlined in the specification). If the inclusion
84 * fails, the <fallback> child of the <include> element is processed.
85 * </p>
86 * <p>
87 * See the <a href="http://www.w3.org/TR/xinclude/">XInclude specification</a> for
88 * more information on how XInclude is to be used.
89 * </p>
358
359 fSawFallback[fDepth] = false;
360 fSawInclude[fDepth] = false;
361 fState[fDepth] = STATE_NORMAL_PROCESSING;
362 fNotations = new ArrayList();
363 fUnparsedEntities = new ArrayList();
364
365 fBaseURIScope = new IntStack();
366 fBaseURI = new Stack();
367 fLiteralSystemID = new Stack();
368 fExpandedSystemID = new Stack();
369 fCurrentBaseURI = new XMLResourceIdentifierImpl();
370
371 fLanguageScope = new IntStack();
372 fLanguageStack = new Stack();
373 fCurrentLanguage = null;
374 }
375
376 // XMLComponent methods
377
378 public void reset(XMLComponentManager componentManager)
379 throws XNIException {
380 fNamespaceContext = null;
381 fDepth = 0;
382 fResultDepth = isRootDocument() ? 0 : fParentXIncludeHandler.getResultDepth();
383 fNotations.clear();
384 fUnparsedEntities.clear();
385 fParentRelativeURI = null;
386 fIsXML11 = false;
387 fInDTD = false;
388 fSeenRootElement = false;
389
390 fBaseURIScope.clear();
391 fBaseURI.clear();
392 fLiteralSystemID.clear();
393 fExpandedSystemID.clear();
394 fLanguageScope.clear();
395 fLanguageStack.clear();
396
397 // REVISIT: Find a better method for maintaining
563 // This is consistent with the behaviour on the main pipeline.
564 try {
565 if (componentManager.getFeature(SCHEMA_VALIDATION)) {
566 fSettings.setFeature(SCHEMA_VALIDATION, false);
567 if (componentManager.getFeature(VALIDATION)) {
568 fSettings.setFeature(DYNAMIC_VALIDATION, true);
569 }
570 }
571 }
572 catch (XMLConfigurationException e) {}
573
574 // Don't reset fChildConfig -- we don't want it to share the same components.
575 // It will be reset when it is actually used to parse something.
576 } // reset(XMLComponentManager)
577
578 /**
579 * Returns a list of feature identifiers that are recognized by
580 * this component. This method may return null if no features
581 * are recognized by this component.
582 */
583 public String[] getRecognizedFeatures() {
584 return (String[])(RECOGNIZED_FEATURES.clone());
585 } // getRecognizedFeatures():String[]
586
587 /**
588 * Sets the state of a feature. This method is called by the component
589 * manager any time after reset when a feature changes state.
590 * <p>
591 * <strong>Note:</strong> Components should silently ignore features
592 * that do not affect the operation of the component.
593 *
594 * @param featureId The feature identifier.
595 * @param state The state of the feature.
596 *
597 * @throws SAXNotRecognizedException The component should not throw
598 * this exception.
599 * @throws SAXNotSupportedException The component should not throw
600 * this exception.
601 */
602 public void setFeature(String featureId, boolean state)
603 throws XMLConfigurationException {
604 if (featureId.equals(ALLOW_UE_AND_NOTATION_EVENTS)) {
605 fSendUEAndNotationEvents = state;
606 }
607 if (fSettings != null) {
608 fNeedCopyFeatures = true;
609 fSettings.setFeature(featureId, state);
610 }
611 } // setFeature(String,boolean)
612
613 /**
614 * Returns a list of property identifiers that are recognized by
615 * this component. This method may return null if no properties
616 * are recognized by this component.
617 */
618 public String[] getRecognizedProperties() {
619 return (String[])(RECOGNIZED_PROPERTIES.clone());
620 } // getRecognizedProperties():String[]
621
622 /**
623 * Sets the value of a property. This method is called by the component
624 * manager any time after reset when a property changes value.
625 * <p>
626 * <strong>Note:</strong> Components should silently ignore properties
627 * that do not affect the operation of the component.
628 *
629 * @param propertyId The property identifier.
630 * @param value The value of the property.
631 *
632 * @throws SAXNotRecognizedException The component should not throw
633 * this exception.
634 * @throws SAXNotSupportedException The component should not throw
635 * this exception.
636 */
637 public void setProperty(String propertyId, Object value)
638 throws XMLConfigurationException {
639 if (propertyId.equals(SYMBOL_TABLE)) {
640 fSymbolTable = (SymbolTable)value;
641 if (fChildConfig != null) {
642 fChildConfig.setProperty(propertyId, value);
643 }
644 return;
645 }
646 if (propertyId.equals(ERROR_REPORTER)) {
647 setErrorReporter((XMLErrorReporter)value);
648 if (fChildConfig != null) {
649 fChildConfig.setProperty(propertyId, value);
650 }
651 return;
652 }
653 if (propertyId.equals(ENTITY_RESOLVER)) {
654 fEntityResolver = (XMLEntityResolver)value;
655 if (fChildConfig != null) {
656 fChildConfig.setProperty(propertyId, value);
677 }
678 // Reset XML 1.1 text reader.
679 if (fXInclude11TextReader != null) {
680 fXInclude11TextReader.setBufferSize(fBufferSize);
681 }
682 }
683 return;
684 }
685
686 } // setProperty(String,Object)
687
688 /**
689 * Returns the default state for a feature, or null if this
690 * component does not want to report a default value for this
691 * feature.
692 *
693 * @param featureId The feature identifier.
694 *
695 * @since Xerces 2.2.0
696 */
697 public Boolean getFeatureDefault(String featureId) {
698 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
699 if (RECOGNIZED_FEATURES[i].equals(featureId)) {
700 return FEATURE_DEFAULTS[i];
701 }
702 }
703 return null;
704 } // getFeatureDefault(String):Boolean
705
706 /**
707 * Returns the default state for a property, or null if this
708 * component does not want to report a default value for this
709 * property.
710 *
711 * @param propertyId The property identifier.
712 *
713 * @since Xerces 2.2.0
714 */
715 public Object getPropertyDefault(String propertyId) {
716 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
717 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
718 return PROPERTY_DEFAULTS[i];
719 }
720 }
721 return null;
722 } // getPropertyDefault(String):Object
723
724 public void setDocumentHandler(XMLDocumentHandler handler) {
725 fDocumentHandler = handler;
726 }
727
728 public XMLDocumentHandler getDocumentHandler() {
729 return fDocumentHandler;
730 }
731
732 // XMLDocumentHandler methods
733
734 /**
735 * Event sent at the start of the document.
736 *
737 * A fatal error will occur here, if it is detected that this document has been processed
738 * before.
739 *
740 * This event is only passed on to the document handler if this is the root document.
741 */
742 public void startDocument(
743 XMLLocator locator,
744 String encoding,
745 NamespaceContext namespaceContext,
746 Augmentations augs)
747 throws XNIException {
748
749 // we do this to ensure that the proper location is reported in errors
750 // otherwise, the locator from the root document would always be used
751 fErrorReporter.setDocumentLocator(locator);
752
753 if (!isRootDocument()
754 && fParentXIncludeHandler.searchForRecursiveIncludes(locator)) {
755 reportFatalError(
756 "RecursiveInclude",
757 new Object[] { locator.getExpandedSystemId()});
758 }
759
760 if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
761 reportFatalError("IncompatibleNamespaceContext");
769 fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
770 saveBaseURI();
771 if (augs == null) {
772 augs = new AugmentationsImpl();
773 }
774 augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
775
776 // initialize the current language
777 fCurrentLanguage = XMLSymbols.EMPTY_STRING;
778 saveLanguage(fCurrentLanguage);
779
780 if (isRootDocument() && fDocumentHandler != null) {
781 fDocumentHandler.startDocument(
782 locator,
783 encoding,
784 namespaceContext,
785 augs);
786 }
787 }
788
789 public void xmlDecl(
790 String version,
791 String encoding,
792 String standalone,
793 Augmentations augs)
794 throws XNIException {
795 fIsXML11 = "1.1".equals(version);
796 if (isRootDocument() && fDocumentHandler != null) {
797 fDocumentHandler.xmlDecl(version, encoding, standalone, augs);
798 }
799 }
800
801 public void doctypeDecl(
802 String rootElement,
803 String publicId,
804 String systemId,
805 Augmentations augs)
806 throws XNIException {
807 if (isRootDocument() && fDocumentHandler != null) {
808 fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
809 }
810 }
811
812 public void comment(XMLString text, Augmentations augs)
813 throws XNIException {
814 if (!fInDTD) {
815 if (fDocumentHandler != null
816 && getState() == STATE_NORMAL_PROCESSING) {
817 fDepth++;
818 augs = modifyAugmentations(augs);
819 fDocumentHandler.comment(text, augs);
820 fDepth--;
821 }
822 }
823 else if (fDTDHandler != null) {
824 fDTDHandler.comment(text, augs);
825 }
826 }
827
828 public void processingInstruction(
829 String target,
830 XMLString data,
831 Augmentations augs)
832 throws XNIException {
833 if (!fInDTD) {
834 if (fDocumentHandler != null
835 && getState() == STATE_NORMAL_PROCESSING) {
836 // we need to change the depth like this so that modifyAugmentations() works
837 fDepth++;
838 augs = modifyAugmentations(augs);
839 fDocumentHandler.processingInstruction(target, data, augs);
840 fDepth--;
841 }
842 }
843 else if (fDTDHandler != null) {
844 fDTDHandler.processingInstruction(target, data, augs);
845 }
846 }
847
848 public void startElement(
849 QName element,
850 XMLAttributes attributes,
851 Augmentations augs)
852 throws XNIException {
853 fDepth++;
854 int lastState = getState(fDepth - 1);
855 // If the last two states were fallback then this must be a descendant of an include
856 // child which isn't a fallback. The specification says we should ignore such elements
857 // and their children.
858 if (lastState == STATE_EXPECT_FALLBACK && getState(fDepth - 2) == STATE_EXPECT_FALLBACK) {
859 setState(STATE_IGNORE);
860 }
861 else {
862 setState(lastState);
863 }
864
865 // we process the xml:base and xml:lang attributes regardless
866 // of what type of element it is.
867 processXMLBaseAttributes(attributes);
898 }
899 if (fDocumentHandler != null) {
900 augs = modifyAugmentations(augs);
901 attributes = processAttributes(attributes);
902 fDocumentHandler.startElement(element, attributes, augs);
903 }
904 }
905 }
906 else if (getState() == STATE_NORMAL_PROCESSING) {
907 if (fResultDepth++ == 0) {
908 checkMultipleRootElements();
909 }
910 if (fDocumentHandler != null) {
911 augs = modifyAugmentations(augs);
912 attributes = processAttributes(attributes);
913 fDocumentHandler.startElement(element, attributes, augs);
914 }
915 }
916 }
917
918 public void emptyElement(
919 QName element,
920 XMLAttributes attributes,
921 Augmentations augs)
922 throws XNIException {
923 fDepth++;
924 int lastState = getState(fDepth - 1);
925 // If the last two states were fallback then this must be a descendant of an include
926 // child which isn't a fallback. The specification says we should ignore such elements
927 // and their children.
928 if (lastState == STATE_EXPECT_FALLBACK && getState(fDepth - 2) == STATE_EXPECT_FALLBACK) {
929 setState(STATE_IGNORE);
930 }
931 else {
932 setState(lastState);
933 }
934
935 // we process the xml:base and xml:lang attributes regardless
936 // of what type of element it is.
937 processXMLBaseAttributes(attributes);
979 checkMultipleRootElements();
980 }
981 if (fDocumentHandler != null) {
982 augs = modifyAugmentations(augs);
983 attributes = processAttributes(attributes);
984 fDocumentHandler.emptyElement(element, attributes, augs);
985 }
986 }
987 // reset the out of scope stack elements
988 setSawFallback(fDepth + 1, false);
989 setSawInclude(fDepth, false);
990
991 // check if an xml:base has gone out of scope
992 if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
993 // pop the values from the stack
994 restoreBaseURI();
995 }
996 fDepth--;
997 }
998
999 public void endElement(QName element, Augmentations augs)
1000 throws XNIException {
1001
1002 if (isIncludeElement(element)) {
1003 // if we're ending an include element, and we were expecting a fallback
1004 // we check to see if the children of this include element contained a fallback
1005 if (getState() == STATE_EXPECT_FALLBACK
1006 && !getSawFallback(fDepth + 1)) {
1007 reportFatalError("NoFallback",
1008 new Object[] { "unknown" });
1009 }
1010 }
1011 if (isFallbackElement(element)) {
1012 // the state would have been set to normal processing if we were expecting the fallback element
1013 // now that we're done processing it, we should ignore all the other children of the include element
1014 if (getState() == STATE_NORMAL_PROCESSING) {
1015 setState(STATE_IGNORE);
1016 }
1017 }
1018 else if (getState() == STATE_NORMAL_PROCESSING) {
1024
1025 // reset the out of scope stack elements
1026 setSawFallback(fDepth + 1, false);
1027 setSawInclude(fDepth, false);
1028
1029 // check if an xml:base has gone out of scope
1030 if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
1031 // pop the values from the stack
1032 restoreBaseURI();
1033 }
1034
1035 // check if an xml:lang has gone out of scope
1036 if (fLanguageScope.size() > 0 && fDepth == fLanguageScope.peek()) {
1037 // pop the language from the stack
1038 fCurrentLanguage = restoreLanguage();
1039 }
1040
1041 fDepth--;
1042 }
1043
1044 public void startGeneralEntity(
1045 String name,
1046 XMLResourceIdentifier resId,
1047 String encoding,
1048 Augmentations augs)
1049 throws XNIException {
1050 if (getState() == STATE_NORMAL_PROCESSING) {
1051 if (fResultDepth == 0) {
1052 if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
1053 reportFatalError("UnexpandedEntityReferenceIllegal");
1054 }
1055 }
1056 else if (fDocumentHandler != null) {
1057 fDocumentHandler.startGeneralEntity(name, resId, encoding, augs);
1058 }
1059 }
1060 }
1061
1062 public void textDecl(String version, String encoding, Augmentations augs)
1063 throws XNIException {
1064 if (fDocumentHandler != null
1065 && getState() == STATE_NORMAL_PROCESSING) {
1066 fDocumentHandler.textDecl(version, encoding, augs);
1067 }
1068 }
1069
1070 public void endGeneralEntity(String name, Augmentations augs)
1071 throws XNIException {
1072 if (fDocumentHandler != null
1073 && getState() == STATE_NORMAL_PROCESSING
1074 && fResultDepth != 0) {
1075 fDocumentHandler.endGeneralEntity(name, augs);
1076 }
1077 }
1078
1079 public void characters(XMLString text, Augmentations augs)
1080 throws XNIException {
1081 if (getState() == STATE_NORMAL_PROCESSING) {
1082 if (fResultDepth == 0) {
1083 checkWhitespace(text);
1084 }
1085 else if (fDocumentHandler != null) {
1086 // we need to change the depth like this so that modifyAugmentations() works
1087 fDepth++;
1088 augs = modifyAugmentations(augs);
1089 fDocumentHandler.characters(text, augs);
1090 fDepth--;
1091 }
1092 }
1093 }
1094
1095 public void ignorableWhitespace(XMLString text, Augmentations augs)
1096 throws XNIException {
1097 if (fDocumentHandler != null
1098 && getState() == STATE_NORMAL_PROCESSING
1099 && fResultDepth != 0) {
1100 fDocumentHandler.ignorableWhitespace(text, augs);
1101 }
1102 }
1103
1104 public void startCDATA(Augmentations augs) throws XNIException {
1105 if (fDocumentHandler != null
1106 && getState() == STATE_NORMAL_PROCESSING
1107 && fResultDepth != 0) {
1108 fDocumentHandler.startCDATA(augs);
1109 }
1110 }
1111
1112 public void endCDATA(Augmentations augs) throws XNIException {
1113 if (fDocumentHandler != null
1114 && getState() == STATE_NORMAL_PROCESSING
1115 && fResultDepth != 0) {
1116 fDocumentHandler.endCDATA(augs);
1117 }
1118 }
1119
1120 public void endDocument(Augmentations augs) throws XNIException {
1121 if (isRootDocument()) {
1122 if (!fSeenRootElement) {
1123 reportFatalError("RootElementRequired");
1124 }
1125 if (fDocumentHandler != null) {
1126 fDocumentHandler.endDocument(augs);
1127 }
1128 }
1129 }
1130
1131 public void setDocumentSource(XMLDocumentSource source) {
1132 fDocumentSource = source;
1133 }
1134
1135 public XMLDocumentSource getDocumentSource() {
1136 return fDocumentSource;
1137 }
1138
1139 // DTDHandler methods
1140 // We are only interested in the notation and unparsed entity declarations,
1141 // the rest we just pass on
1142
1143 /* (non-Javadoc)
1144 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1145 */
1146 public void attributeDecl(
1147 String elementName,
1148 String attributeName,
1149 String type,
1150 String[] enumeration,
1151 String defaultType,
1152 XMLString defaultValue,
1153 XMLString nonNormalizedDefaultValue,
1154 Augmentations augmentations)
1155 throws XNIException {
1156 if (fDTDHandler != null) {
1157 fDTDHandler.attributeDecl(
1158 elementName,
1159 attributeName,
1160 type,
1161 enumeration,
1162 defaultType,
1163 defaultValue,
1164 nonNormalizedDefaultValue,
1165 augmentations);
1166 }
1167 }
1168
1169 /* (non-Javadoc)
1170 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#elementDecl(java.lang.String, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1171 */
1172 public void elementDecl(
1173 String name,
1174 String contentModel,
1175 Augmentations augmentations)
1176 throws XNIException {
1177 if (fDTDHandler != null) {
1178 fDTDHandler.elementDecl(name, contentModel, augmentations);
1179 }
1180 }
1181
1182 /* (non-Javadoc)
1183 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endAttlist(com.sun.org.apache.xerces.internal.xni.Augmentations)
1184 */
1185 public void endAttlist(Augmentations augmentations) throws XNIException {
1186 if (fDTDHandler != null) {
1187 fDTDHandler.endAttlist(augmentations);
1188 }
1189 }
1190
1191 /* (non-Javadoc)
1192 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endConditional(com.sun.org.apache.xerces.internal.xni.Augmentations)
1193 */
1194 public void endConditional(Augmentations augmentations)
1195 throws XNIException {
1196 if (fDTDHandler != null) {
1197 fDTDHandler.endConditional(augmentations);
1198 }
1199 }
1200
1201 /* (non-Javadoc)
1202 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endDTD(com.sun.org.apache.xerces.internal.xni.Augmentations)
1203 */
1204 public void endDTD(Augmentations augmentations) throws XNIException {
1205 if (fDTDHandler != null) {
1206 fDTDHandler.endDTD(augmentations);
1207 }
1208 fInDTD = false;
1209 }
1210
1211 /* (non-Javadoc)
1212 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endExternalSubset(com.sun.org.apache.xerces.internal.xni.Augmentations)
1213 */
1214 public void endExternalSubset(Augmentations augmentations)
1215 throws XNIException {
1216 if (fDTDHandler != null) {
1217 fDTDHandler.endExternalSubset(augmentations);
1218 }
1219 }
1220
1221 /* (non-Javadoc)
1222 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1223 */
1224 public void endParameterEntity(String name, Augmentations augmentations)
1225 throws XNIException {
1226 if (fDTDHandler != null) {
1227 fDTDHandler.endParameterEntity(name, augmentations);
1228 }
1229 }
1230
1231 /* (non-Javadoc)
1232 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#externalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1233 */
1234 public void externalEntityDecl(
1235 String name,
1236 XMLResourceIdentifier identifier,
1237 Augmentations augmentations)
1238 throws XNIException {
1239 if (fDTDHandler != null) {
1240 fDTDHandler.externalEntityDecl(name, identifier, augmentations);
1241 }
1242 }
1243
1244 /* (non-Javadoc)
1245 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#getDTDSource()
1246 */
1247 public XMLDTDSource getDTDSource() {
1248 return fDTDSource;
1249 }
1250
1251 /* (non-Javadoc)
1252 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#ignoredCharacters(com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1253 */
1254 public void ignoredCharacters(XMLString text, Augmentations augmentations)
1255 throws XNIException {
1256 if (fDTDHandler != null) {
1257 fDTDHandler.ignoredCharacters(text, augmentations);
1258 }
1259 }
1260
1261 /* (non-Javadoc)
1262 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#internalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1263 */
1264 public void internalEntityDecl(
1265 String name,
1266 XMLString text,
1267 XMLString nonNormalizedText,
1268 Augmentations augmentations)
1269 throws XNIException {
1270 if (fDTDHandler != null) {
1271 fDTDHandler.internalEntityDecl(
1272 name,
1273 text,
1274 nonNormalizedText,
1275 augmentations);
1276 }
1277 }
1278
1279 /* (non-Javadoc)
1280 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#notationDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1281 */
1282 public void notationDecl(
1283 String name,
1284 XMLResourceIdentifier identifier,
1285 Augmentations augmentations)
1286 throws XNIException {
1287 this.addNotation(name, identifier, augmentations);
1288 if (fDTDHandler != null) {
1289 fDTDHandler.notationDecl(name, identifier, augmentations);
1290 }
1291 }
1292
1293 /* (non-Javadoc)
1294 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#setDTDSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource)
1295 */
1296 public void setDTDSource(XMLDTDSource source) {
1297 fDTDSource = source;
1298 }
1299
1300 /* (non-Javadoc)
1301 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startAttlist(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1302 */
1303 public void startAttlist(String elementName, Augmentations augmentations)
1304 throws XNIException {
1305 if (fDTDHandler != null) {
1306 fDTDHandler.startAttlist(elementName, augmentations);
1307 }
1308 }
1309
1310 /* (non-Javadoc)
1311 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startConditional(short, com.sun.org.apache.xerces.internal.xni.Augmentations)
1312 */
1313 public void startConditional(short type, Augmentations augmentations)
1314 throws XNIException {
1315 if (fDTDHandler != null) {
1316 fDTDHandler.startConditional(type, augmentations);
1317 }
1318 }
1319
1320 /* (non-Javadoc)
1321 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startDTD(com.sun.org.apache.xerces.internal.xni.XMLLocator, com.sun.org.apache.xerces.internal.xni.Augmentations)
1322 */
1323 public void startDTD(XMLLocator locator, Augmentations augmentations)
1324 throws XNIException {
1325 fInDTD = true;
1326 if (fDTDHandler != null) {
1327 fDTDHandler.startDTD(locator, augmentations);
1328 }
1329 }
1330
1331 /* (non-Javadoc)
1332 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startExternalSubset(com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1333 */
1334 public void startExternalSubset(
1335 XMLResourceIdentifier identifier,
1336 Augmentations augmentations)
1337 throws XNIException {
1338 if (fDTDHandler != null) {
1339 fDTDHandler.startExternalSubset(identifier, augmentations);
1340 }
1341 }
1342
1343 /* (non-Javadoc)
1344 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1345 */
1346 public void startParameterEntity(
1347 String name,
1348 XMLResourceIdentifier identifier,
1349 String encoding,
1350 Augmentations augmentations)
1351 throws XNIException {
1352 if (fDTDHandler != null) {
1353 fDTDHandler.startParameterEntity(
1354 name,
1355 identifier,
1356 encoding,
1357 augmentations);
1358 }
1359 }
1360
1361 /* (non-Javadoc)
1362 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#unparsedEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1363 */
1364 public void unparsedEntityDecl(
1365 String name,
1366 XMLResourceIdentifier identifier,
1367 String notation,
1368 Augmentations augmentations)
1369 throws XNIException {
1370 this.addUnparsedEntity(name, identifier, notation, augmentations);
1371 if (fDTDHandler != null) {
1372 fDTDHandler.unparsedEntityDecl(
1373 name,
1374 identifier,
1375 notation,
1376 augmentations);
1377 }
1378 }
1379
1380 /* (non-Javadoc)
1381 * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#getDTDHandler()
1382 */
1383 public XMLDTDHandler getDTDHandler() {
1384 return fDTDHandler;
1385 }
1386
1387 /* (non-Javadoc)
1388 * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#setDTDHandler(com.sun.org.apache.xerces.internal.xni.XMLDTDHandler)
1389 */
1390 public void setDTDHandler(XMLDTDHandler handler) {
1391 fDTDHandler = handler;
1392 }
1393
1394 // XIncludeHandler methods
1395
1396 private void setErrorReporter(XMLErrorReporter reporter) {
1397 fErrorReporter = reporter;
1398 if (fErrorReporter != null) {
1399 fErrorReporter.putMessageFormatter(
1400 XIncludeMessageFormatter.XINCLUDE_DOMAIN, fXIncludeMessageFormatter);
1401 // this ensures the proper location is displayed in error messages
1402 if (fDocLocation != null) {
1403 fErrorReporter.setDocumentLocator(fDocLocation);
1404 }
1405 }
1406 }
1407
1408 protected void handleFallbackElement() {
1409 if (!getSawInclude(fDepth - 1)) {
1598 fFixupLanguage);
1599
1600
1601 // If the xpointer attribute is present
1602 if (xpointer != null ) {
1603
1604 XPointerHandler newHandler =
1605 (XPointerHandler)fChildConfig.getProperty(
1606 Constants.XERCES_PROPERTY_PREFIX
1607 + Constants.XPOINTER_HANDLER_PROPERTY);
1608
1609 fXPtrProcessor = newHandler;
1610
1611 // ???
1612 ((XPointerHandler)fXPtrProcessor).setProperty(
1613 Constants.XERCES_PROPERTY_PREFIX
1614 + Constants.NAMESPACE_CONTEXT_PROPERTY,
1615 fNamespaceContext);
1616
1617 ((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS,
1618 new Boolean(fFixupBaseURIs));
1619
1620 ((XPointerHandler)fXPtrProcessor).setProperty(
1621 XINCLUDE_FIXUP_LANGUAGE,
1622 new Boolean (fFixupLanguage));
1623
1624 if (fErrorReporter != null)
1625 ((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter);
1626 // ???
1627
1628 newHandler.setParent(this);
1629 newHandler.setDocumentHandler(this.getDocumentHandler());
1630 fXPointerChildConfig = fChildConfig;
1631 } else {
1632 XIncludeHandler newHandler =
1633 (XIncludeHandler)fChildConfig.getProperty(
1634 Constants.XERCES_PROPERTY_PREFIX
1635 + Constants.XINCLUDE_HANDLER_PROPERTY);
1636
1637 newHandler.setParent(this);
1638 newHandler.setDocumentHandler(this.getDocumentHandler());
1639 fXIncludeChildConfig = fChildConfig;
1640 }
1641 }
1642
2076 else {
2077 if (relativeURI.equals("")) {
2078 relativeURI = fCurrentBaseURI.getLiteralSystemId();
2079 }
2080
2081 if (includeParentDepth == 0) {
2082 if (fParentRelativeURI == null) {
2083 fParentRelativeURI =
2084 fParentXIncludeHandler.getRelativeBaseURI();
2085 }
2086 if (fParentRelativeURI.equals("")) {
2087 return relativeURI;
2088 }
2089
2090 URI base = new URI(fParentRelativeURI, true);
2091 URI uri = new URI(base, relativeURI);
2092
2093 /** Check whether the scheme components are equal. */
2094 final String baseScheme = base.getScheme();
2095 final String literalScheme = uri.getScheme();
2096 if (!isEqual(baseScheme, literalScheme)) {
2097 return relativeURI;
2098 }
2099
2100 /** Check whether the authority components are equal. */
2101 final String baseAuthority = base.getAuthority();
2102 final String literalAuthority = uri.getAuthority();
2103 if (!isEqual(baseAuthority, literalAuthority)) {
2104 return uri.getSchemeSpecificPart();
2105 }
2106
2107 /**
2108 * The scheme and authority components are equal,
2109 * return the path and the possible query and/or
2110 * fragment which follow.
2111 */
2112 final String literalPath = uri.getPath();
2113 final String literalQuery = uri.getQueryString();
2114 final String literalFragment = uri.getFragment();
2115 if (literalQuery != null || literalFragment != null) {
2116 StringBuffer buffer = new StringBuffer();
2117 if (literalPath != null) {
2118 buffer.append(literalPath);
2119 }
2120 if (literalQuery != null) {
2121 buffer.append('?');
2122 buffer.append(literalQuery);
2123 }
2124 if (literalFragment != null) {
2125 buffer.append('#');
2126 buffer.append(literalFragment);
2127 }
2128 return buffer.toString();
2129 }
2130 return literalPath;
2131 }
2132 else {
2133 return relativeURI;
2134 }
2135 }
2136 }
2607 }
2608 catch (XMLConfigurationException e) {
2609 // componentManager doesn't support this feature,
2610 // so we won't worry about it
2611 }
2612 }
2613 }
2614
2615 // This is a storage class to hold information about the notations.
2616 // We're not using XMLNotationDecl because we don't want to lose the augmentations.
2617 protected static class Notation {
2618 public String name;
2619 public String systemId;
2620 public String baseURI;
2621 public String publicId;
2622 public String expandedSystemId;
2623 public Augmentations augmentations;
2624
2625 // equals() returns true if two Notations have the same name.
2626 // Useful for searching Vectors for notations with the same name
2627 public boolean equals(Object obj) {
2628 if (obj == null) {
2629 return false;
2630 }
2631 if (obj instanceof Notation) {
2632 Notation other = (Notation)obj;
2633 return name.equals(other.name);
2634 }
2635 return false;
2636 }
2637
2638 // from 4.5.2
2639 // Notation items with the same [name], [system identifier],
2640 // [public identifier], and [declaration base URI] are considered
2641 // to be duplicate. An application may also be able to detect that
2642 // notations are duplicate through other means. For instance, the URI
2643 // resulting from combining the system identifier and the declaration
2644 // base URI is the same.
2645 public boolean isDuplicate(Object obj) {
2646 if (obj != null && obj instanceof Notation) {
2647 Notation other = (Notation)obj;
2648 return name.equals(other.name)
2649 && isEqual(publicId, other.publicId)
2650 && isEqual(expandedSystemId, other.expandedSystemId);
2651 }
2652 return false;
2653 }
2654
2655 private boolean isEqual(String one, String two) {
2656 return (one == two || (one != null && one.equals(two)));
2657 }
2658 }
2659
2660 // This is a storage class to hold information about the unparsed entities.
2661 // We're not using XMLEntityDecl because we don't want to lose the augmentations.
2662 protected static class UnparsedEntity {
2663 public String name;
2664 public String systemId;
2665 public String baseURI;
2666 public String publicId;
2667 public String expandedSystemId;
2668 public String notation;
2669 public Augmentations augmentations;
2670
2671 // equals() returns true if two UnparsedEntities have the same name.
2672 // Useful for searching Vectors for entities with the same name
2673 public boolean equals(Object obj) {
2674 if (obj == null) {
2675 return false;
2676 }
2677 if (obj instanceof UnparsedEntity) {
2678 UnparsedEntity other = (UnparsedEntity)obj;
2679 return name.equals(other.name);
2680 }
2681 return false;
2682 }
2683
2684 // from 4.5.1:
2685 // Unparsed entity items with the same [name], [system identifier],
2686 // [public identifier], [declaration base URI], [notation name], and
2687 // [notation] are considered to be duplicate. An application may also
2688 // be able to detect that unparsed entities are duplicate through other
2689 // means. For instance, the URI resulting from combining the system
2690 // identifier and the declaration base URI is the same.
2691 public boolean isDuplicate(Object obj) {
2692 if (obj != null && obj instanceof UnparsedEntity) {
2693 UnparsedEntity other = (UnparsedEntity)obj;
2694 return name.equals(other.name)
2695 && isEqual(publicId, other.publicId)
2696 && isEqual(expandedSystemId, other.expandedSystemId)
2697 && isEqual(notation, other.notation);
2698 }
2699 return false;
2700 }
2701
2702 private boolean isEqual(String one, String two) {
2703 return (one == two || (one != null && one.equals(two)));
2704 }
2705 }
2706
2707 // The following methods are used for XML Base processing
2708
2709 /**
2710 * Saves the current base URI to the top of the stack.
2711 */
2712 protected void saveBaseURI() {
2713 fBaseURIScope.push(fDepth);
2714 fBaseURI.push(fCurrentBaseURI.getBaseSystemId());
2715 fLiteralSystemID.push(fCurrentBaseURI.getLiteralSystemId());
2716 fExpandedSystemID.push(fCurrentBaseURI.getExpandedSystemId());
2717 }
2718
2719 /**
2720 * Discards the URIs at the top of the stack, and restores the ones beneath it.
2721 */
2722 protected void restoreBaseURI() {
2723 fBaseURI.pop();
2724 fLiteralSystemID.pop();
2874 return true;
2875 }
2876
2877 /**
2878 * Returns a new <code>XMLInputSource</code> from the given parameters.
2879 */
2880 private XMLInputSource createInputSource(String publicId,
2881 String systemId, String baseSystemId,
2882 String accept, String acceptLanguage) {
2883
2884 HTTPInputSource httpSource = new HTTPInputSource(publicId, systemId, baseSystemId);
2885 if (accept != null && accept.length() > 0) {
2886 httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT, accept);
2887 }
2888 if (acceptLanguage != null && acceptLanguage.length() > 0) {
2889 httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE, acceptLanguage);
2890 }
2891 return httpSource;
2892 }
2893
2894 private boolean isEqual(String one, String two) {
2895 return (one == two || (one != null && one.equals(two)));
2896 }
2897
2898 // which ASCII characters need to be escaped
2899 private static boolean gNeedEscaping[] = new boolean[128];
2900 // the first hex character if a character needs to be escaped
2901 private static char gAfterEscaping1[] = new char[128];
2902 // the second hex character if a character needs to be escaped
2903 private static char gAfterEscaping2[] = new char[128];
2904 private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
2905 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
2906 // initialize the above 3 arrays
2907 static {
2908 char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
2909 int len = escChs.length;
2910 char ch;
2911 for (int i = 0; i < len; i++) {
2912 ch = escChs[i];
2913 gNeedEscaping[ch] = true;
2914 gAfterEscaping1[ch] = gHexChs[ch >> 4];
2915 gAfterEscaping2[ch] = gHexChs[ch & 0xf];
2916 }
2917 }
2918
2919 //
2920 // Escape an href value according to (4.1.1):
2921 //
2922 // To convert the value of the href attribute to an IRI reference, the following characters must be escaped:
2923 // space #x20
2924 // the delimiters < #x3C, > #x3E and " #x22
2925 // the unwise characters { #x7B, } #x7D, | #x7C, \ #x5C, ^ #x5E and ` #x60
2926 //
2927 // To convert an IRI reference to a URI reference, the following characters must also be escaped:
2928 // the Unicode plane 0 characters #xA0 - #xD7FF, #xF900-#xFDCF, #xFDF0-#xFFEF
2929 // the Unicode plane 1-14 characters #x10000-#x1FFFD ... #xE0000-#xEFFFD
2930 //
2931 private String escapeHref(String href) {
2932 int len = href.length();
2933 int ch;
2934 StringBuffer buffer = new StringBuffer(len*3);
2935
2936 // for each character in the href
2937 int i = 0;
2938 for (; i < len; i++) {
2939 ch = href.charAt(i);
2940 // if it's not an ASCII character (excluding 0x7F), break here, and use UTF-8 encoding
2941 if (ch > 0x7E) {
2942 break;
2943 }
2944 // abort: href does not allow this character
2945 if (ch < 0x20) {
2946 return href;
2947 }
2948 if (gNeedEscaping[ch]) {
2949 buffer.append('%');
2950 buffer.append(gAfterEscaping1[ch]);
2951 buffer.append(gAfterEscaping2[ch]);
2952 }
2953 else {
2954 buffer.append((char)ch);
|
50 import com.sun.org.apache.xerces.internal.xni.XMLAttributes;
51 import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler;
52 import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler;
53 import com.sun.org.apache.xerces.internal.xni.XMLLocator;
54 import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier;
55 import com.sun.org.apache.xerces.internal.xni.XMLString;
56 import com.sun.org.apache.xerces.internal.xni.XNIException;
57 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent;
58 import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager;
59 import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException;
60 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDFilter;
61 import com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource;
62 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentFilter;
63 import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentSource;
64 import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver;
65 import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource;
66 import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration;
67 import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler;
68 import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor;
69 import com.sun.org.apache.xerces.internal.utils.ObjectFactory;
70 import java.util.Objects;
71
72 /**
73 * <p>
74 * This is a pipeline component which performs XInclude handling, according to the
75 * W3C specification for XML Inclusions.
76 * </p>
77 * <p>
78 * This component analyzes each event in the pipeline, looking for <include>
79 * elements. An <include> element is one which has a namespace of
80 * <code>http://www.w3.org/2001/XInclude</code> and a localname of <code>include</code>.
81 * When it finds an <include> element, it attempts to include the file specified
82 * in the <code>href</code> attribute of the element. If inclusion succeeds, all
83 * children of the <include> element are ignored (with the exception of
84 * checking for invalid children as outlined in the specification). If the inclusion
85 * fails, the <fallback> child of the <include> element is processed.
86 * </p>
87 * <p>
88 * See the <a href="http://www.w3.org/TR/xinclude/">XInclude specification</a> for
89 * more information on how XInclude is to be used.
90 * </p>
359
360 fSawFallback[fDepth] = false;
361 fSawInclude[fDepth] = false;
362 fState[fDepth] = STATE_NORMAL_PROCESSING;
363 fNotations = new ArrayList();
364 fUnparsedEntities = new ArrayList();
365
366 fBaseURIScope = new IntStack();
367 fBaseURI = new Stack();
368 fLiteralSystemID = new Stack();
369 fExpandedSystemID = new Stack();
370 fCurrentBaseURI = new XMLResourceIdentifierImpl();
371
372 fLanguageScope = new IntStack();
373 fLanguageStack = new Stack();
374 fCurrentLanguage = null;
375 }
376
377 // XMLComponent methods
378
379 @Override
380 public void reset(XMLComponentManager componentManager)
381 throws XNIException {
382 fNamespaceContext = null;
383 fDepth = 0;
384 fResultDepth = isRootDocument() ? 0 : fParentXIncludeHandler.getResultDepth();
385 fNotations.clear();
386 fUnparsedEntities.clear();
387 fParentRelativeURI = null;
388 fIsXML11 = false;
389 fInDTD = false;
390 fSeenRootElement = false;
391
392 fBaseURIScope.clear();
393 fBaseURI.clear();
394 fLiteralSystemID.clear();
395 fExpandedSystemID.clear();
396 fLanguageScope.clear();
397 fLanguageStack.clear();
398
399 // REVISIT: Find a better method for maintaining
565 // This is consistent with the behaviour on the main pipeline.
566 try {
567 if (componentManager.getFeature(SCHEMA_VALIDATION)) {
568 fSettings.setFeature(SCHEMA_VALIDATION, false);
569 if (componentManager.getFeature(VALIDATION)) {
570 fSettings.setFeature(DYNAMIC_VALIDATION, true);
571 }
572 }
573 }
574 catch (XMLConfigurationException e) {}
575
576 // Don't reset fChildConfig -- we don't want it to share the same components.
577 // It will be reset when it is actually used to parse something.
578 } // reset(XMLComponentManager)
579
580 /**
581 * Returns a list of feature identifiers that are recognized by
582 * this component. This method may return null if no features
583 * are recognized by this component.
584 */
585 @Override
586 public String[] getRecognizedFeatures() {
587 return (String[])(RECOGNIZED_FEATURES.clone());
588 } // getRecognizedFeatures():String[]
589
590 /**
591 * Sets the state of a feature. This method is called by the component
592 * manager any time after reset when a feature changes state.
593 * <p>
594 * <strong>Note:</strong> Components should silently ignore features
595 * that do not affect the operation of the component.
596 *
597 * @param featureId The feature identifier.
598 * @param state The state of the feature.
599 *
600 * @throws SAXNotRecognizedException The component should not throw
601 * this exception.
602 * @throws SAXNotSupportedException The component should not throw
603 * this exception.
604 */
605 @Override
606 public void setFeature(String featureId, boolean state)
607 throws XMLConfigurationException {
608 if (featureId.equals(ALLOW_UE_AND_NOTATION_EVENTS)) {
609 fSendUEAndNotationEvents = state;
610 }
611 if (fSettings != null) {
612 fNeedCopyFeatures = true;
613 fSettings.setFeature(featureId, state);
614 }
615 } // setFeature(String,boolean)
616
617 /**
618 * Returns a list of property identifiers that are recognized by
619 * this component. This method may return null if no properties
620 * are recognized by this component.
621 */
622 @Override
623 public String[] getRecognizedProperties() {
624 return (String[])(RECOGNIZED_PROPERTIES.clone());
625 } // getRecognizedProperties():String[]
626
627 /**
628 * Sets the value of a property. This method is called by the component
629 * manager any time after reset when a property changes value.
630 * <p>
631 * <strong>Note:</strong> Components should silently ignore properties
632 * that do not affect the operation of the component.
633 *
634 * @param propertyId The property identifier.
635 * @param value The value of the property.
636 *
637 * @throws SAXNotRecognizedException The component should not throw
638 * this exception.
639 * @throws SAXNotSupportedException The component should not throw
640 * this exception.
641 */
642 @Override
643 public void setProperty(String propertyId, Object value)
644 throws XMLConfigurationException {
645 if (propertyId.equals(SYMBOL_TABLE)) {
646 fSymbolTable = (SymbolTable)value;
647 if (fChildConfig != null) {
648 fChildConfig.setProperty(propertyId, value);
649 }
650 return;
651 }
652 if (propertyId.equals(ERROR_REPORTER)) {
653 setErrorReporter((XMLErrorReporter)value);
654 if (fChildConfig != null) {
655 fChildConfig.setProperty(propertyId, value);
656 }
657 return;
658 }
659 if (propertyId.equals(ENTITY_RESOLVER)) {
660 fEntityResolver = (XMLEntityResolver)value;
661 if (fChildConfig != null) {
662 fChildConfig.setProperty(propertyId, value);
683 }
684 // Reset XML 1.1 text reader.
685 if (fXInclude11TextReader != null) {
686 fXInclude11TextReader.setBufferSize(fBufferSize);
687 }
688 }
689 return;
690 }
691
692 } // setProperty(String,Object)
693
694 /**
695 * Returns the default state for a feature, or null if this
696 * component does not want to report a default value for this
697 * feature.
698 *
699 * @param featureId The feature identifier.
700 *
701 * @since Xerces 2.2.0
702 */
703 @Override
704 public Boolean getFeatureDefault(String featureId) {
705 for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) {
706 if (RECOGNIZED_FEATURES[i].equals(featureId)) {
707 return FEATURE_DEFAULTS[i];
708 }
709 }
710 return null;
711 } // getFeatureDefault(String):Boolean
712
713 /**
714 * Returns the default state for a property, or null if this
715 * component does not want to report a default value for this
716 * property.
717 *
718 * @param propertyId The property identifier.
719 *
720 * @since Xerces 2.2.0
721 */
722 @Override
723 public Object getPropertyDefault(String propertyId) {
724 for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) {
725 if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) {
726 return PROPERTY_DEFAULTS[i];
727 }
728 }
729 return null;
730 } // getPropertyDefault(String):Object
731
732 @Override
733 public void setDocumentHandler(XMLDocumentHandler handler) {
734 fDocumentHandler = handler;
735 }
736
737 @Override
738 public XMLDocumentHandler getDocumentHandler() {
739 return fDocumentHandler;
740 }
741
742 // XMLDocumentHandler methods
743
744 /**
745 * Event sent at the start of the document.
746 *
747 * A fatal error will occur here, if it is detected that this document has been processed
748 * before.
749 *
750 * This event is only passed on to the document handler if this is the root document.
751 */
752 @Override
753 public void startDocument(
754 XMLLocator locator,
755 String encoding,
756 NamespaceContext namespaceContext,
757 Augmentations augs)
758 throws XNIException {
759
760 // we do this to ensure that the proper location is reported in errors
761 // otherwise, the locator from the root document would always be used
762 fErrorReporter.setDocumentLocator(locator);
763
764 if (!isRootDocument()
765 && fParentXIncludeHandler.searchForRecursiveIncludes(locator)) {
766 reportFatalError(
767 "RecursiveInclude",
768 new Object[] { locator.getExpandedSystemId()});
769 }
770
771 if (!(namespaceContext instanceof XIncludeNamespaceSupport)) {
772 reportFatalError("IncompatibleNamespaceContext");
780 fCurrentBaseURI.setLiteralSystemId(locator.getLiteralSystemId());
781 saveBaseURI();
782 if (augs == null) {
783 augs = new AugmentationsImpl();
784 }
785 augs.putItem(CURRENT_BASE_URI, fCurrentBaseURI);
786
787 // initialize the current language
788 fCurrentLanguage = XMLSymbols.EMPTY_STRING;
789 saveLanguage(fCurrentLanguage);
790
791 if (isRootDocument() && fDocumentHandler != null) {
792 fDocumentHandler.startDocument(
793 locator,
794 encoding,
795 namespaceContext,
796 augs);
797 }
798 }
799
800 @Override
801 public void xmlDecl(
802 String version,
803 String encoding,
804 String standalone,
805 Augmentations augs)
806 throws XNIException {
807 fIsXML11 = "1.1".equals(version);
808 if (isRootDocument() && fDocumentHandler != null) {
809 fDocumentHandler.xmlDecl(version, encoding, standalone, augs);
810 }
811 }
812
813 @Override
814 public void doctypeDecl(
815 String rootElement,
816 String publicId,
817 String systemId,
818 Augmentations augs)
819 throws XNIException {
820 if (isRootDocument() && fDocumentHandler != null) {
821 fDocumentHandler.doctypeDecl(rootElement, publicId, systemId, augs);
822 }
823 }
824
825 @Override
826 public void comment(XMLString text, Augmentations augs)
827 throws XNIException {
828 if (!fInDTD) {
829 if (fDocumentHandler != null
830 && getState() == STATE_NORMAL_PROCESSING) {
831 fDepth++;
832 augs = modifyAugmentations(augs);
833 fDocumentHandler.comment(text, augs);
834 fDepth--;
835 }
836 }
837 else if (fDTDHandler != null) {
838 fDTDHandler.comment(text, augs);
839 }
840 }
841
842 @Override
843 public void processingInstruction(
844 String target,
845 XMLString data,
846 Augmentations augs)
847 throws XNIException {
848 if (!fInDTD) {
849 if (fDocumentHandler != null
850 && getState() == STATE_NORMAL_PROCESSING) {
851 // we need to change the depth like this so that modifyAugmentations() works
852 fDepth++;
853 augs = modifyAugmentations(augs);
854 fDocumentHandler.processingInstruction(target, data, augs);
855 fDepth--;
856 }
857 }
858 else if (fDTDHandler != null) {
859 fDTDHandler.processingInstruction(target, data, augs);
860 }
861 }
862
863 @Override
864 public void startElement(
865 QName element,
866 XMLAttributes attributes,
867 Augmentations augs)
868 throws XNIException {
869 fDepth++;
870 int lastState = getState(fDepth - 1);
871 // If the last two states were fallback then this must be a descendant of an include
872 // child which isn't a fallback. The specification says we should ignore such elements
873 // and their children.
874 if (lastState == STATE_EXPECT_FALLBACK && getState(fDepth - 2) == STATE_EXPECT_FALLBACK) {
875 setState(STATE_IGNORE);
876 }
877 else {
878 setState(lastState);
879 }
880
881 // we process the xml:base and xml:lang attributes regardless
882 // of what type of element it is.
883 processXMLBaseAttributes(attributes);
914 }
915 if (fDocumentHandler != null) {
916 augs = modifyAugmentations(augs);
917 attributes = processAttributes(attributes);
918 fDocumentHandler.startElement(element, attributes, augs);
919 }
920 }
921 }
922 else if (getState() == STATE_NORMAL_PROCESSING) {
923 if (fResultDepth++ == 0) {
924 checkMultipleRootElements();
925 }
926 if (fDocumentHandler != null) {
927 augs = modifyAugmentations(augs);
928 attributes = processAttributes(attributes);
929 fDocumentHandler.startElement(element, attributes, augs);
930 }
931 }
932 }
933
934 @Override
935 public void emptyElement(
936 QName element,
937 XMLAttributes attributes,
938 Augmentations augs)
939 throws XNIException {
940 fDepth++;
941 int lastState = getState(fDepth - 1);
942 // If the last two states were fallback then this must be a descendant of an include
943 // child which isn't a fallback. The specification says we should ignore such elements
944 // and their children.
945 if (lastState == STATE_EXPECT_FALLBACK && getState(fDepth - 2) == STATE_EXPECT_FALLBACK) {
946 setState(STATE_IGNORE);
947 }
948 else {
949 setState(lastState);
950 }
951
952 // we process the xml:base and xml:lang attributes regardless
953 // of what type of element it is.
954 processXMLBaseAttributes(attributes);
996 checkMultipleRootElements();
997 }
998 if (fDocumentHandler != null) {
999 augs = modifyAugmentations(augs);
1000 attributes = processAttributes(attributes);
1001 fDocumentHandler.emptyElement(element, attributes, augs);
1002 }
1003 }
1004 // reset the out of scope stack elements
1005 setSawFallback(fDepth + 1, false);
1006 setSawInclude(fDepth, false);
1007
1008 // check if an xml:base has gone out of scope
1009 if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
1010 // pop the values from the stack
1011 restoreBaseURI();
1012 }
1013 fDepth--;
1014 }
1015
1016 @Override
1017 public void endElement(QName element, Augmentations augs)
1018 throws XNIException {
1019
1020 if (isIncludeElement(element)) {
1021 // if we're ending an include element, and we were expecting a fallback
1022 // we check to see if the children of this include element contained a fallback
1023 if (getState() == STATE_EXPECT_FALLBACK
1024 && !getSawFallback(fDepth + 1)) {
1025 reportFatalError("NoFallback",
1026 new Object[] { "unknown" });
1027 }
1028 }
1029 if (isFallbackElement(element)) {
1030 // the state would have been set to normal processing if we were expecting the fallback element
1031 // now that we're done processing it, we should ignore all the other children of the include element
1032 if (getState() == STATE_NORMAL_PROCESSING) {
1033 setState(STATE_IGNORE);
1034 }
1035 }
1036 else if (getState() == STATE_NORMAL_PROCESSING) {
1042
1043 // reset the out of scope stack elements
1044 setSawFallback(fDepth + 1, false);
1045 setSawInclude(fDepth, false);
1046
1047 // check if an xml:base has gone out of scope
1048 if (fBaseURIScope.size() > 0 && fDepth == fBaseURIScope.peek()) {
1049 // pop the values from the stack
1050 restoreBaseURI();
1051 }
1052
1053 // check if an xml:lang has gone out of scope
1054 if (fLanguageScope.size() > 0 && fDepth == fLanguageScope.peek()) {
1055 // pop the language from the stack
1056 fCurrentLanguage = restoreLanguage();
1057 }
1058
1059 fDepth--;
1060 }
1061
1062 @Override
1063 public void startGeneralEntity(
1064 String name,
1065 XMLResourceIdentifier resId,
1066 String encoding,
1067 Augmentations augs)
1068 throws XNIException {
1069 if (getState() == STATE_NORMAL_PROCESSING) {
1070 if (fResultDepth == 0) {
1071 if (augs != null && Boolean.TRUE.equals(augs.getItem(Constants.ENTITY_SKIPPED))) {
1072 reportFatalError("UnexpandedEntityReferenceIllegal");
1073 }
1074 }
1075 else if (fDocumentHandler != null) {
1076 fDocumentHandler.startGeneralEntity(name, resId, encoding, augs);
1077 }
1078 }
1079 }
1080
1081 @Override
1082 public void textDecl(String version, String encoding, Augmentations augs)
1083 throws XNIException {
1084 if (fDocumentHandler != null
1085 && getState() == STATE_NORMAL_PROCESSING) {
1086 fDocumentHandler.textDecl(version, encoding, augs);
1087 }
1088 }
1089
1090 @Override
1091 public void endGeneralEntity(String name, Augmentations augs)
1092 throws XNIException {
1093 if (fDocumentHandler != null
1094 && getState() == STATE_NORMAL_PROCESSING
1095 && fResultDepth != 0) {
1096 fDocumentHandler.endGeneralEntity(name, augs);
1097 }
1098 }
1099
1100 @Override
1101 public void characters(XMLString text, Augmentations augs)
1102 throws XNIException {
1103 if (getState() == STATE_NORMAL_PROCESSING) {
1104 if (fResultDepth == 0) {
1105 checkWhitespace(text);
1106 }
1107 else if (fDocumentHandler != null) {
1108 // we need to change the depth like this so that modifyAugmentations() works
1109 fDepth++;
1110 augs = modifyAugmentations(augs);
1111 fDocumentHandler.characters(text, augs);
1112 fDepth--;
1113 }
1114 }
1115 }
1116
1117 @Override
1118 public void ignorableWhitespace(XMLString text, Augmentations augs)
1119 throws XNIException {
1120 if (fDocumentHandler != null
1121 && getState() == STATE_NORMAL_PROCESSING
1122 && fResultDepth != 0) {
1123 fDocumentHandler.ignorableWhitespace(text, augs);
1124 }
1125 }
1126
1127 @Override
1128 public void startCDATA(Augmentations augs) throws XNIException {
1129 if (fDocumentHandler != null
1130 && getState() == STATE_NORMAL_PROCESSING
1131 && fResultDepth != 0) {
1132 fDocumentHandler.startCDATA(augs);
1133 }
1134 }
1135
1136 @Override
1137 public void endCDATA(Augmentations augs) throws XNIException {
1138 if (fDocumentHandler != null
1139 && getState() == STATE_NORMAL_PROCESSING
1140 && fResultDepth != 0) {
1141 fDocumentHandler.endCDATA(augs);
1142 }
1143 }
1144
1145 @Override
1146 public void endDocument(Augmentations augs) throws XNIException {
1147 if (isRootDocument()) {
1148 if (!fSeenRootElement) {
1149 reportFatalError("RootElementRequired");
1150 }
1151 if (fDocumentHandler != null) {
1152 fDocumentHandler.endDocument(augs);
1153 }
1154 }
1155 }
1156
1157 @Override
1158 public void setDocumentSource(XMLDocumentSource source) {
1159 fDocumentSource = source;
1160 }
1161
1162 @Override
1163 public XMLDocumentSource getDocumentSource() {
1164 return fDocumentSource;
1165 }
1166
1167 // DTDHandler methods
1168 // We are only interested in the notation and unparsed entity declarations,
1169 // the rest we just pass on
1170
1171 /* (non-Javadoc)
1172 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1173 */
1174 @Override
1175 public void attributeDecl(
1176 String elementName,
1177 String attributeName,
1178 String type,
1179 String[] enumeration,
1180 String defaultType,
1181 XMLString defaultValue,
1182 XMLString nonNormalizedDefaultValue,
1183 Augmentations augmentations)
1184 throws XNIException {
1185 if (fDTDHandler != null) {
1186 fDTDHandler.attributeDecl(
1187 elementName,
1188 attributeName,
1189 type,
1190 enumeration,
1191 defaultType,
1192 defaultValue,
1193 nonNormalizedDefaultValue,
1194 augmentations);
1195 }
1196 }
1197
1198 /* (non-Javadoc)
1199 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#elementDecl(java.lang.String, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1200 */
1201 @Override
1202 public void elementDecl(
1203 String name,
1204 String contentModel,
1205 Augmentations augmentations)
1206 throws XNIException {
1207 if (fDTDHandler != null) {
1208 fDTDHandler.elementDecl(name, contentModel, augmentations);
1209 }
1210 }
1211
1212 /* (non-Javadoc)
1213 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endAttlist(com.sun.org.apache.xerces.internal.xni.Augmentations)
1214 */
1215 @Override
1216 public void endAttlist(Augmentations augmentations) throws XNIException {
1217 if (fDTDHandler != null) {
1218 fDTDHandler.endAttlist(augmentations);
1219 }
1220 }
1221
1222 /* (non-Javadoc)
1223 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endConditional(com.sun.org.apache.xerces.internal.xni.Augmentations)
1224 */
1225 @Override
1226 public void endConditional(Augmentations augmentations)
1227 throws XNIException {
1228 if (fDTDHandler != null) {
1229 fDTDHandler.endConditional(augmentations);
1230 }
1231 }
1232
1233 /* (non-Javadoc)
1234 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endDTD(com.sun.org.apache.xerces.internal.xni.Augmentations)
1235 */
1236 @Override
1237 public void endDTD(Augmentations augmentations) throws XNIException {
1238 if (fDTDHandler != null) {
1239 fDTDHandler.endDTD(augmentations);
1240 }
1241 fInDTD = false;
1242 }
1243
1244 /* (non-Javadoc)
1245 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endExternalSubset(com.sun.org.apache.xerces.internal.xni.Augmentations)
1246 */
1247 @Override
1248 public void endExternalSubset(Augmentations augmentations)
1249 throws XNIException {
1250 if (fDTDHandler != null) {
1251 fDTDHandler.endExternalSubset(augmentations);
1252 }
1253 }
1254
1255 /* (non-Javadoc)
1256 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1257 */
1258 @Override
1259 public void endParameterEntity(String name, Augmentations augmentations)
1260 throws XNIException {
1261 if (fDTDHandler != null) {
1262 fDTDHandler.endParameterEntity(name, augmentations);
1263 }
1264 }
1265
1266 /* (non-Javadoc)
1267 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#externalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1268 */
1269 @Override
1270 public void externalEntityDecl(
1271 String name,
1272 XMLResourceIdentifier identifier,
1273 Augmentations augmentations)
1274 throws XNIException {
1275 if (fDTDHandler != null) {
1276 fDTDHandler.externalEntityDecl(name, identifier, augmentations);
1277 }
1278 }
1279
1280 /* (non-Javadoc)
1281 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#getDTDSource()
1282 */
1283 @Override
1284 public XMLDTDSource getDTDSource() {
1285 return fDTDSource;
1286 }
1287
1288 /* (non-Javadoc)
1289 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#ignoredCharacters(com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1290 */
1291 @Override
1292 public void ignoredCharacters(XMLString text, Augmentations augmentations)
1293 throws XNIException {
1294 if (fDTDHandler != null) {
1295 fDTDHandler.ignoredCharacters(text, augmentations);
1296 }
1297 }
1298
1299 /* (non-Javadoc)
1300 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#internalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations)
1301 */
1302 @Override
1303 public void internalEntityDecl(
1304 String name,
1305 XMLString text,
1306 XMLString nonNormalizedText,
1307 Augmentations augmentations)
1308 throws XNIException {
1309 if (fDTDHandler != null) {
1310 fDTDHandler.internalEntityDecl(
1311 name,
1312 text,
1313 nonNormalizedText,
1314 augmentations);
1315 }
1316 }
1317
1318 /* (non-Javadoc)
1319 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#notationDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1320 */
1321 @Override
1322 public void notationDecl(
1323 String name,
1324 XMLResourceIdentifier identifier,
1325 Augmentations augmentations)
1326 throws XNIException {
1327 this.addNotation(name, identifier, augmentations);
1328 if (fDTDHandler != null) {
1329 fDTDHandler.notationDecl(name, identifier, augmentations);
1330 }
1331 }
1332
1333 /* (non-Javadoc)
1334 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#setDTDSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource)
1335 */
1336 @Override
1337 public void setDTDSource(XMLDTDSource source) {
1338 fDTDSource = source;
1339 }
1340
1341 /* (non-Javadoc)
1342 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startAttlist(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1343 */
1344 @Override
1345 public void startAttlist(String elementName, Augmentations augmentations)
1346 throws XNIException {
1347 if (fDTDHandler != null) {
1348 fDTDHandler.startAttlist(elementName, augmentations);
1349 }
1350 }
1351
1352 /* (non-Javadoc)
1353 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startConditional(short, com.sun.org.apache.xerces.internal.xni.Augmentations)
1354 */
1355 @Override
1356 public void startConditional(short type, Augmentations augmentations)
1357 throws XNIException {
1358 if (fDTDHandler != null) {
1359 fDTDHandler.startConditional(type, augmentations);
1360 }
1361 }
1362
1363 /* (non-Javadoc)
1364 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startDTD(com.sun.org.apache.xerces.internal.xni.XMLLocator, com.sun.org.apache.xerces.internal.xni.Augmentations)
1365 */
1366 @Override
1367 public void startDTD(XMLLocator locator, Augmentations augmentations)
1368 throws XNIException {
1369 fInDTD = true;
1370 if (fDTDHandler != null) {
1371 fDTDHandler.startDTD(locator, augmentations);
1372 }
1373 }
1374
1375 /* (non-Javadoc)
1376 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startExternalSubset(com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations)
1377 */
1378 @Override
1379 public void startExternalSubset(
1380 XMLResourceIdentifier identifier,
1381 Augmentations augmentations)
1382 throws XNIException {
1383 if (fDTDHandler != null) {
1384 fDTDHandler.startExternalSubset(identifier, augmentations);
1385 }
1386 }
1387
1388 /* (non-Javadoc)
1389 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1390 */
1391 @Override
1392 public void startParameterEntity(
1393 String name,
1394 XMLResourceIdentifier identifier,
1395 String encoding,
1396 Augmentations augmentations)
1397 throws XNIException {
1398 if (fDTDHandler != null) {
1399 fDTDHandler.startParameterEntity(
1400 name,
1401 identifier,
1402 encoding,
1403 augmentations);
1404 }
1405 }
1406
1407 /* (non-Javadoc)
1408 * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#unparsedEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations)
1409 */
1410 @Override
1411 public void unparsedEntityDecl(
1412 String name,
1413 XMLResourceIdentifier identifier,
1414 String notation,
1415 Augmentations augmentations)
1416 throws XNIException {
1417 this.addUnparsedEntity(name, identifier, notation, augmentations);
1418 if (fDTDHandler != null) {
1419 fDTDHandler.unparsedEntityDecl(
1420 name,
1421 identifier,
1422 notation,
1423 augmentations);
1424 }
1425 }
1426
1427 /* (non-Javadoc)
1428 * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#getDTDHandler()
1429 */
1430 @Override
1431 public XMLDTDHandler getDTDHandler() {
1432 return fDTDHandler;
1433 }
1434
1435 /* (non-Javadoc)
1436 * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#setDTDHandler(com.sun.org.apache.xerces.internal.xni.XMLDTDHandler)
1437 */
1438 @Override
1439 public void setDTDHandler(XMLDTDHandler handler) {
1440 fDTDHandler = handler;
1441 }
1442
1443 // XIncludeHandler methods
1444
1445 private void setErrorReporter(XMLErrorReporter reporter) {
1446 fErrorReporter = reporter;
1447 if (fErrorReporter != null) {
1448 fErrorReporter.putMessageFormatter(
1449 XIncludeMessageFormatter.XINCLUDE_DOMAIN, fXIncludeMessageFormatter);
1450 // this ensures the proper location is displayed in error messages
1451 if (fDocLocation != null) {
1452 fErrorReporter.setDocumentLocator(fDocLocation);
1453 }
1454 }
1455 }
1456
1457 protected void handleFallbackElement() {
1458 if (!getSawInclude(fDepth - 1)) {
1647 fFixupLanguage);
1648
1649
1650 // If the xpointer attribute is present
1651 if (xpointer != null ) {
1652
1653 XPointerHandler newHandler =
1654 (XPointerHandler)fChildConfig.getProperty(
1655 Constants.XERCES_PROPERTY_PREFIX
1656 + Constants.XPOINTER_HANDLER_PROPERTY);
1657
1658 fXPtrProcessor = newHandler;
1659
1660 // ???
1661 ((XPointerHandler)fXPtrProcessor).setProperty(
1662 Constants.XERCES_PROPERTY_PREFIX
1663 + Constants.NAMESPACE_CONTEXT_PROPERTY,
1664 fNamespaceContext);
1665
1666 ((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS,
1667 fFixupBaseURIs);
1668
1669 ((XPointerHandler)fXPtrProcessor).setProperty(
1670 XINCLUDE_FIXUP_LANGUAGE, fFixupLanguage);
1671
1672 if (fErrorReporter != null)
1673 ((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter);
1674 // ???
1675
1676 newHandler.setParent(this);
1677 newHandler.setDocumentHandler(this.getDocumentHandler());
1678 fXPointerChildConfig = fChildConfig;
1679 } else {
1680 XIncludeHandler newHandler =
1681 (XIncludeHandler)fChildConfig.getProperty(
1682 Constants.XERCES_PROPERTY_PREFIX
1683 + Constants.XINCLUDE_HANDLER_PROPERTY);
1684
1685 newHandler.setParent(this);
1686 newHandler.setDocumentHandler(this.getDocumentHandler());
1687 fXIncludeChildConfig = fChildConfig;
1688 }
1689 }
1690
2124 else {
2125 if (relativeURI.equals("")) {
2126 relativeURI = fCurrentBaseURI.getLiteralSystemId();
2127 }
2128
2129 if (includeParentDepth == 0) {
2130 if (fParentRelativeURI == null) {
2131 fParentRelativeURI =
2132 fParentXIncludeHandler.getRelativeBaseURI();
2133 }
2134 if (fParentRelativeURI.equals("")) {
2135 return relativeURI;
2136 }
2137
2138 URI base = new URI(fParentRelativeURI, true);
2139 URI uri = new URI(base, relativeURI);
2140
2141 /** Check whether the scheme components are equal. */
2142 final String baseScheme = base.getScheme();
2143 final String literalScheme = uri.getScheme();
2144 if (!Objects.equals(baseScheme, literalScheme)) {
2145 return relativeURI;
2146 }
2147
2148 /** Check whether the authority components are equal. */
2149 final String baseAuthority = base.getAuthority();
2150 final String literalAuthority = uri.getAuthority();
2151 if (!Objects.equals(baseAuthority, literalAuthority)) {
2152 return uri.getSchemeSpecificPart();
2153 }
2154
2155 /**
2156 * The scheme and authority components are equal,
2157 * return the path and the possible query and/or
2158 * fragment which follow.
2159 */
2160 final String literalPath = uri.getPath();
2161 final String literalQuery = uri.getQueryString();
2162 final String literalFragment = uri.getFragment();
2163 if (literalQuery != null || literalFragment != null) {
2164 final StringBuilder buffer = new StringBuilder();
2165 if (literalPath != null) {
2166 buffer.append(literalPath);
2167 }
2168 if (literalQuery != null) {
2169 buffer.append('?');
2170 buffer.append(literalQuery);
2171 }
2172 if (literalFragment != null) {
2173 buffer.append('#');
2174 buffer.append(literalFragment);
2175 }
2176 return buffer.toString();
2177 }
2178 return literalPath;
2179 }
2180 else {
2181 return relativeURI;
2182 }
2183 }
2184 }
2655 }
2656 catch (XMLConfigurationException e) {
2657 // componentManager doesn't support this feature,
2658 // so we won't worry about it
2659 }
2660 }
2661 }
2662
2663 // This is a storage class to hold information about the notations.
2664 // We're not using XMLNotationDecl because we don't want to lose the augmentations.
2665 protected static class Notation {
2666 public String name;
2667 public String systemId;
2668 public String baseURI;
2669 public String publicId;
2670 public String expandedSystemId;
2671 public Augmentations augmentations;
2672
2673 // equals() returns true if two Notations have the same name.
2674 // Useful for searching Vectors for notations with the same name
2675 @Override
2676 public boolean equals(Object obj) {
2677 return obj == this || obj instanceof Notation
2678 && Objects.equals(name, ((Notation)obj).name);
2679 }
2680
2681 @Override
2682 public int hashCode() {
2683 return Objects.hashCode(name);
2684 }
2685
2686 // from 4.5.2
2687 // Notation items with the same [name], [system identifier],
2688 // [public identifier], and [declaration base URI] are considered
2689 // to be duplicate. An application may also be able to detect that
2690 // notations are duplicate through other means. For instance, the URI
2691 // resulting from combining the system identifier and the declaration
2692 // base URI is the same.
2693 public boolean isDuplicate(Object obj) {
2694 if (obj != null && obj instanceof Notation) {
2695 Notation other = (Notation)obj;
2696 return Objects.equals(name, other.name)
2697 && Objects.equals(publicId, other.publicId)
2698 && Objects.equals(expandedSystemId, other.expandedSystemId);
2699 }
2700 return false;
2701 }
2702 }
2703
2704 // This is a storage class to hold information about the unparsed entities.
2705 // We're not using XMLEntityDecl because we don't want to lose the augmentations.
2706 protected static class UnparsedEntity {
2707 public String name;
2708 public String systemId;
2709 public String baseURI;
2710 public String publicId;
2711 public String expandedSystemId;
2712 public String notation;
2713 public Augmentations augmentations;
2714
2715 // equals() returns true if two UnparsedEntities have the same name.
2716 // Useful for searching Vectors for entities with the same name
2717 @Override
2718 public boolean equals(Object obj) {
2719 return obj == this || obj instanceof UnparsedEntity
2720 && Objects.equals(name, ((UnparsedEntity)obj).name);
2721 }
2722
2723 @Override
2724 public int hashCode() {
2725 return Objects.hashCode(name);
2726 }
2727
2728 // from 4.5.1:
2729 // Unparsed entity items with the same [name], [system identifier],
2730 // [public identifier], [declaration base URI], [notation name], and
2731 // [notation] are considered to be duplicate. An application may also
2732 // be able to detect that unparsed entities are duplicate through other
2733 // means. For instance, the URI resulting from combining the system
2734 // identifier and the declaration base URI is the same.
2735 public boolean isDuplicate(Object obj) {
2736 if (obj != null && obj instanceof UnparsedEntity) {
2737 UnparsedEntity other = (UnparsedEntity)obj;
2738 return Objects.equals(name, other.name)
2739 && Objects.equals(publicId, other.publicId)
2740 && Objects.equals(expandedSystemId, other.expandedSystemId)
2741 && Objects.equals(notation, other.notation);
2742 }
2743 return false;
2744 }
2745 }
2746
2747 // The following methods are used for XML Base processing
2748
2749 /**
2750 * Saves the current base URI to the top of the stack.
2751 */
2752 protected void saveBaseURI() {
2753 fBaseURIScope.push(fDepth);
2754 fBaseURI.push(fCurrentBaseURI.getBaseSystemId());
2755 fLiteralSystemID.push(fCurrentBaseURI.getLiteralSystemId());
2756 fExpandedSystemID.push(fCurrentBaseURI.getExpandedSystemId());
2757 }
2758
2759 /**
2760 * Discards the URIs at the top of the stack, and restores the ones beneath it.
2761 */
2762 protected void restoreBaseURI() {
2763 fBaseURI.pop();
2764 fLiteralSystemID.pop();
2914 return true;
2915 }
2916
2917 /**
2918 * Returns a new <code>XMLInputSource</code> from the given parameters.
2919 */
2920 private XMLInputSource createInputSource(String publicId,
2921 String systemId, String baseSystemId,
2922 String accept, String acceptLanguage) {
2923
2924 HTTPInputSource httpSource = new HTTPInputSource(publicId, systemId, baseSystemId);
2925 if (accept != null && accept.length() > 0) {
2926 httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT, accept);
2927 }
2928 if (acceptLanguage != null && acceptLanguage.length() > 0) {
2929 httpSource.setHTTPRequestProperty(XIncludeHandler.HTTP_ACCEPT_LANGUAGE, acceptLanguage);
2930 }
2931 return httpSource;
2932 }
2933
2934 // which ASCII characters need to be escaped
2935 private static final boolean gNeedEscaping[] = new boolean[128];
2936 // the first hex character if a character needs to be escaped
2937 private static final char gAfterEscaping1[] = new char[128];
2938 // the second hex character if a character needs to be escaped
2939 private static final char gAfterEscaping2[] = new char[128];
2940 private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7',
2941 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
2942 // initialize the above 3 arrays
2943 static {
2944 char[] escChs = {' ', '<', '>', '"', '{', '}', '|', '\\', '^', '`'};
2945 int len = escChs.length;
2946 char ch;
2947 for (int i = 0; i < len; i++) {
2948 ch = escChs[i];
2949 gNeedEscaping[ch] = true;
2950 gAfterEscaping1[ch] = gHexChs[ch >> 4];
2951 gAfterEscaping2[ch] = gHexChs[ch & 0xf];
2952 }
2953 }
2954
2955 //
2956 // Escape an href value according to (4.1.1):
2957 //
2958 // To convert the value of the href attribute to an IRI reference, the following characters must be escaped:
2959 // space #x20
2960 // the delimiters < #x3C, > #x3E and " #x22
2961 // the unwise characters { #x7B, } #x7D, | #x7C, \ #x5C, ^ #x5E and ` #x60
2962 //
2963 // To convert an IRI reference to a URI reference, the following characters must also be escaped:
2964 // the Unicode plane 0 characters #xA0 - #xD7FF, #xF900-#xFDCF, #xFDF0-#xFFEF
2965 // the Unicode plane 1-14 characters #x10000-#x1FFFD ... #xE0000-#xEFFFD
2966 //
2967 private String escapeHref(String href) {
2968 int len = href.length();
2969 int ch;
2970 final StringBuilder buffer = new StringBuilder(len*3);
2971
2972 // for each character in the href
2973 int i = 0;
2974 for (; i < len; i++) {
2975 ch = href.charAt(i);
2976 // if it's not an ASCII character (excluding 0x7F), break here, and use UTF-8 encoding
2977 if (ch > 0x7E) {
2978 break;
2979 }
2980 // abort: href does not allow this character
2981 if (ch < 0x20) {
2982 return href;
2983 }
2984 if (gNeedEscaping[ch]) {
2985 buffer.append('%');
2986 buffer.append(gAfterEscaping1[ch]);
2987 buffer.append(gAfterEscaping2[ch]);
2988 }
2989 else {
2990 buffer.append((char)ch);
|