in src/org/apache/xerces/xinclude/XIncludeHandler.java [1459:1824]
protected boolean handleIncludeElement(XMLAttributes attributes)
throws XNIException {
if (getSawInclude(fDepth - 1)) {
reportFatalError("IncludeChild", new Object[] { XINCLUDE_INCLUDE });
}
if (getState() == STATE_IGNORE) {
return true;
}
setSawInclude(fDepth, true);
fNamespaceContext.setContextInvalid();
// TODO: does Java use IURIs by default?
// [Definition: An internationalized URI reference, or IURI, is a URI reference that directly uses [Unicode] characters.]
// TODO: figure out what section 4.1.1 of the XInclude spec is talking about
// has to do with disallowed ASCII character escaping
// this ties in with the above IURI section, but I suspect Java already does it
String href = attributes.getValue(XINCLUDE_ATTR_HREF);
String parse = attributes.getValue(XINCLUDE_ATTR_PARSE);
String xpointer = attributes.getValue(XPOINTER);
String accept = attributes.getValue(XINCLUDE_ATTR_ACCEPT);
String acceptLanguage = attributes.getValue(XINCLUDE_ATTR_ACCEPT_LANGUAGE);
if (parse == null) {
parse = XINCLUDE_PARSE_XML;
}
if (href == null) {
href = XMLSymbols.EMPTY_STRING;
}
if (href.length() == 0 && XINCLUDE_PARSE_XML.equals(parse)) {
if (xpointer == null) {
reportFatalError("XpointerMissing");
}
else {
// When parse="xml" and an xpointer is specified treat
// all absences of the href attribute as a resource error.
Locale locale = (fErrorReporter != null) ? fErrorReporter.getLocale() : null;
String reason = fXIncludeMessageFormatter.formatMessage(locale, "XPointerStreamability", null);
reportResourceError("XMLResourceError", new Object[] { href, reason });
return false;
}
}
URI hrefURI = null;
// Check whether href is correct and perform escaping as per section 4.1.1 of the XInclude spec.
// Report fatal error if the href value contains a fragment identifier or if the value after
// escaping is a syntactically invalid URI or IRI.
try {
hrefURI = new URI(href, true);
if (hrefURI.getFragment() != null) {
reportFatalError("HrefFragmentIdentifierIllegal", new Object[] {href});
}
}
catch (URI.MalformedURIException exc) {
String newHref = escapeHref(href);
if (href != newHref) {
href = newHref;
try {
hrefURI = new URI(href, true);
if (hrefURI.getFragment() != null) {
reportFatalError("HrefFragmentIdentifierIllegal", new Object[] {href});
}
}
catch (URI.MalformedURIException exc2) {
reportFatalError("HrefSyntacticallyInvalid", new Object[] {href});
}
}
else {
reportFatalError("HrefSyntacticallyInvalid", new Object[] {href});
}
}
// Verify that if an accept and/or an accept-language attribute exist
// that the value(s) don't contain disallowed characters.
if (accept != null && !isValidInHTTPHeader(accept)) {
reportFatalError("AcceptMalformed", null);
accept = null;
}
if (acceptLanguage != null && !isValidInHTTPHeader(acceptLanguage)) {
reportFatalError("AcceptLanguageMalformed", null);
acceptLanguage = null;
}
XMLInputSource includedSource = null;
if (fEntityResolver != null) {
try {
XMLResourceIdentifier resourceIdentifier =
new XMLResourceIdentifierImpl(
null,
href,
fCurrentBaseURI.getExpandedSystemId(),
XMLEntityManager.expandSystemId(
href,
fCurrentBaseURI.getExpandedSystemId(),
false));
includedSource =
fEntityResolver.resolveEntity(resourceIdentifier);
if (includedSource != null &&
!(includedSource instanceof HTTPInputSource) &&
(accept != null || acceptLanguage != null) &&
includedSource.getCharacterStream() == null &&
includedSource.getByteStream() == null) {
includedSource = createInputSource(includedSource.getPublicId(), includedSource.getSystemId(),
includedSource.getBaseSystemId(), accept, acceptLanguage);
}
}
catch (IOException e) {
reportResourceError(
"XMLResourceError",
new Object[] { href, e.getMessage()}, e);
return false;
}
}
if (includedSource == null) {
// setup an HTTPInputSource if either of the content negotation attributes were specified.
if (accept != null || acceptLanguage != null) {
includedSource = createInputSource(null, href, fCurrentBaseURI.getExpandedSystemId(), accept, acceptLanguage);
}
else {
includedSource = new XMLInputSource(null, href, fCurrentBaseURI.getExpandedSystemId());
}
}
if (parse.equals(XINCLUDE_PARSE_XML)) {
// Instead of always creating a new configuration, the first one can be reused
if ((xpointer != null && fXPointerChildConfig == null)
|| (xpointer == null && fXIncludeChildConfig == null) ) {
String parserName = XINCLUDE_DEFAULT_CONFIGURATION;
if (xpointer != null)
parserName = "org.apache.xerces.parsers.XPointerParserConfiguration";
fChildConfig =
(XMLParserConfiguration)ObjectFactory.newInstance(
parserName,
ObjectFactory.findClassLoader(),
true);
// use the same symbol table, error reporter, entity resolver, security manager and buffer size.
if (fSymbolTable != null) fChildConfig.setProperty(SYMBOL_TABLE, fSymbolTable);
if (fErrorReporter != null) fChildConfig.setProperty(ERROR_REPORTER, fErrorReporter);
if (fEntityResolver != null) fChildConfig.setProperty(ENTITY_RESOLVER, fEntityResolver);
fChildConfig.setProperty(SECURITY_MANAGER, fSecurityManager);
fChildConfig.setProperty(BUFFER_SIZE, new Integer(fBufferSize));
// features must be copied to child configuration
fNeedCopyFeatures = true;
// use the same namespace context
fChildConfig.setProperty(
Constants.XERCES_PROPERTY_PREFIX
+ Constants.NAMESPACE_CONTEXT_PROPERTY,
fNamespaceContext);
fChildConfig.setFeature(
XINCLUDE_FIXUP_BASE_URIS,
fFixupBaseURIs);
fChildConfig.setFeature(
XINCLUDE_FIXUP_LANGUAGE,
fFixupLanguage);
// If the xpointer attribute is present
if (xpointer != null ) {
XPointerHandler newHandler =
(XPointerHandler)fChildConfig.getProperty(
Constants.XERCES_PROPERTY_PREFIX
+ Constants.XPOINTER_HANDLER_PROPERTY);
fXPtrProcessor = newHandler;
// ???
((XPointerHandler)fXPtrProcessor).setProperty(
Constants.XERCES_PROPERTY_PREFIX
+ Constants.NAMESPACE_CONTEXT_PROPERTY,
fNamespaceContext);
((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS,
fFixupBaseURIs ? Boolean.TRUE : Boolean.FALSE);
((XPointerHandler)fXPtrProcessor).setProperty(
XINCLUDE_FIXUP_LANGUAGE,
fFixupLanguage ? Boolean.TRUE : Boolean.FALSE);
if (fErrorReporter != null)
((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter);
// ???
newHandler.setParent(this);
newHandler.setHref(href);
newHandler.setXIncludeLocator(fXIncludeLocator);
newHandler.setDocumentHandler(this.getDocumentHandler());
fXPointerChildConfig = fChildConfig;
} else {
XIncludeHandler newHandler =
(XIncludeHandler)fChildConfig.getProperty(
Constants.XERCES_PROPERTY_PREFIX
+ Constants.XINCLUDE_HANDLER_PROPERTY);
newHandler.setParent(this);
newHandler.setHref(href);
newHandler.setXIncludeLocator(fXIncludeLocator);
newHandler.setDocumentHandler(this.getDocumentHandler());
fXIncludeChildConfig = fChildConfig;
}
}
// If an xpointer attribute is present
if (xpointer != null ) {
fChildConfig = fXPointerChildConfig;
// Parse the XPointer expression
try {
((XPointerProcessor)fXPtrProcessor).parseXPointer(xpointer);
} catch (XNIException ex) {
// report the XPointer error as a resource error
reportResourceError(
"XMLResourceError",
new Object[] { href, ex.getMessage()});
return false;
}
} else {
fChildConfig = fXIncludeChildConfig;
}
// set all features on parserConfig to match this parser configuration
if (fNeedCopyFeatures) {
copyFeatures(fSettings, fChildConfig);
}
fNeedCopyFeatures = false;
try {
fHasIncludeReportedContent = false;
fNamespaceContext.pushScope();
fChildConfig.parse(includedSource);
// necessary to make sure proper location is reported to the application and in errors
fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
// If the xpointer attribute is present
if (xpointer != null ) {
// and it was not resolved
if (!((XPointerProcessor)fXPtrProcessor).isXPointerResolved()) {
Locale locale = (fErrorReporter != null) ? fErrorReporter.getLocale() : null;
String reason = fXIncludeMessageFormatter.formatMessage(locale, "XPointerResolutionUnsuccessful", null);
reportResourceError("XMLResourceError", new Object[] {href, reason});
// use the fallback
return false;
}
}
}
catch (XNIException e) {
// necessary to make sure proper location is reported to the application and in errors
fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
reportFatalError("XMLParseError", new Object[] { href });
}
catch (IOException e) {
// necessary to make sure proper location is reported to the application and in errors
fXIncludeLocator.setLocator(fDocLocation);
if (fErrorReporter != null) {
fErrorReporter.setDocumentLocator(fDocLocation);
}
// If the start document event has been seen on the child pipeline it
// means the resource was successfully opened and we started reporting
// document events. If an IOException is thrown after the start document
// event we had a failure midstream and cannot recover.
if (fHasIncludeReportedContent) {
throw new XNIException(e);
}
// In other circumstances an IOException indicates that we had trouble
// accessing or opening the file, not that it was an invalid XML file. So we
// send a resource error, not a fatal error.
reportResourceError(
"XMLResourceError",
new Object[] { href, e.getMessage()}, e);
return false;
}
finally {
fNamespaceContext.popScope();
}
}
else if (parse.equals(XINCLUDE_PARSE_TEXT)) {
// we only care about encoding for parse="text"
String encoding = attributes.getValue(XINCLUDE_ATTR_ENCODING);
includedSource.setEncoding(encoding);
XIncludeTextReader textReader = null;
try {
fHasIncludeReportedContent = false;
// Setup the appropriate text reader.
if (!fIsXML11) {
if (fXInclude10TextReader == null) {
fXInclude10TextReader = new XIncludeTextReader(includedSource, this, fBufferSize);
}
else {
fXInclude10TextReader.setInputSource(includedSource);
}
textReader = fXInclude10TextReader;
}
else {
if (fXInclude11TextReader == null) {
fXInclude11TextReader = new XInclude11TextReader(includedSource, this, fBufferSize);
}
else {
fXInclude11TextReader.setInputSource(includedSource);
}
textReader = fXInclude11TextReader;
}
textReader.setErrorReporter(fErrorReporter);
textReader.parse();
}
// encoding errors
catch (MalformedByteSequenceException ex) {
fErrorReporter.reportError(ex.getDomain(), ex.getKey(),
ex.getArguments(), XMLErrorReporter.SEVERITY_FATAL_ERROR, ex);
}
catch (CharConversionException e) {
fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,
"CharConversionFailure", null, XMLErrorReporter.SEVERITY_FATAL_ERROR, e);
}
catch (IOException e) {
// If a characters event has already been sent down the pipeline it
// means the resource was successfully opened and that this IOException
// is from a failure midstream from which we cannot recover.
if (fHasIncludeReportedContent) {
throw new XNIException(e);
}
reportResourceError(
"TextResourceError",
new Object[] { href, e.getMessage()}, e);
return false;
}
finally {
if (textReader != null) {
try {
textReader.close();
}
catch (IOException e) {
reportResourceError(
"TextResourceError",
new Object[] { href, e.getMessage()}, e);
return false;
}
}
}
}
else {
reportFatalError("InvalidParseValue", new Object[] { parse });
}
return true;
}