in core/cocoon-pipeline/cocoon-pipeline-components/src/main/java/org/apache/cocoon/transformation/XIncludeTransformer.java [442:579]
protected void processXIncludeElement(String href, String parse, String xpointer)
throws SAXException,ProcessingException,IOException {
if (getLogger().isDebugEnabled()) {
getLogger().debug("Processing XInclude element: href="+href+", parse="+parse+", xpointer="+xpointer);
}
// Default for @parse is "xml"
if (parse == null) {
parse = "xml";
}
Source url = null;
try {
int fragmentIdentifierPos = href.indexOf('#');
if (fragmentIdentifierPos != -1) {
getLogger().warn("Fragment identifer found in 'href' attribute: " + href +
"\nFragment identifiers are forbidden by the XInclude specification. " +
"They are still handled by XIncludeTransformer for backward " +
"compatibility, but their use is deprecated and will be prohibited " +
"in a future release. Use the 'xpointer' attribute instead.");
if (xpointer == null) {
xpointer = href.substring(fragmentIdentifierPos + 1);
}
href = href.substring(0, fragmentIdentifierPos);
}
// An empty or absent href is a reference to the current document -- this can be different than the current base
if (href == null || href.length() == 0) {
if (this.href == null) {
throw new SAXException("XIncludeTransformer: encountered empty href (= href pointing to the current document) but the location of the current document is unknown.");
}
// The following can be simplified once fragment identifiers are prohibited
int fragmentIdentifierPos2 = this.href.indexOf('#');
if (fragmentIdentifierPos2 != -1)
href = this.href.substring(0, fragmentIdentifierPos2);
else
href = this.href;
}
url = xmlBaseSupport.makeAbsolute(href);
if (getLogger().isDebugEnabled()) {
getLogger().debug("URL: " + url.getURI() + "\nXPointer: " + xpointer);
}
// add the source to the SourceValidity
validity.addSource(url);
if (parse.equals("text")) {
getLogger().debug("Parse type is text");
if (xpointer != null) {
throw new SAXException("xpointer attribute must not be present when parse='text': " + getLocation());
}
InputStream is = null;
InputStreamReader isr = null;
Reader reader = null;
try {
is = url.getInputStream();
isr = new InputStreamReader(is);
reader = new BufferedReader(isr);
int read;
char ary[] = new char[1024 * 4];
while ((read = reader.read(ary)) != -1) {
super.characters(ary,0,read);
}
} catch (SourceNotFoundException e) {
useFallbackLevel++;
fallBackException = new CascadingException("Resource not found: " + url.getURI());
getLogger().error("xIncluded resource not found: " + url.getURI(), e);
} finally {
if (reader != null) reader.close();
if (isr != null) isr.close();
if (is != null) is.close();
}
} else if (parse.equals("xml")) {
getLogger().debug("Parse type is XML");
// Check loop inclusion
if (isLoopInclusion(url.getURI(), xpointer)) {
throw new ProcessingException("Detected loop inclusion of href=" + url.getURI() + ", xpointer=" + xpointer);
}
XIncludePipe subPipe = new XIncludePipe();
subPipe.init(url.getURI(), xpointer);
subPipe.setConsumer(xmlConsumer);
subPipe.setParent(this);
try {
if (xpointer != null && xpointer.length() > 0) {
XPointer xptr;
xptr = XPointerFrameworkParser.parse(NetUtils.decodePath(xpointer));
XPointerContext context = new XPointerContext(xpointer, url, subPipe, manager);
for (Iterator iter = namespaces.keySet().iterator(); iter.hasNext();) {
String prefix = (String) iter.next();
context.addPrefix(prefix, (String) namespaces.get(prefix));
}
xptr.process(context);
} else {
SourceUtil.toSAX(manager, url, new IncludeXMLConsumer(subPipe));
}
// restore locator on the consumer
if (locator != null)
xmlConsumer.setDocumentLocator(locator);
} catch (ResourceNotFoundException e) {
useFallbackLevel++;
fallBackException = new CascadingException("Resource not found: " + url.getURI());
getLogger().error("xIncluded resource not found: " + url.getURI(), e);
} catch (ParseException e) {
// this exception is thrown in case of an invalid xpointer expression
useFallbackLevel++;
fallBackException = new CascadingException("Error parsing xPointer expression", e);
fallBackException.fillInStackTrace();
getLogger().error("Error parsing XPointer expression, will try to use fallback.", e);
} catch(SAXException e) {
getLogger().error("Error in processXIncludeElement", e);
throw e;
} catch(ProcessingException e) {
getLogger().error("Error in processXIncludeElement", e);
throw e;
} catch(MalformedURLException e) {
useFallbackLevel++;
fallBackException = e;
getLogger().error("Error processing an xInclude, will try to use fallback.", e);
} catch(IOException e) {
useFallbackLevel++;
fallBackException = e;
getLogger().error("Error processing an xInclude, will try to use fallback.", e);
}
} else {
throw new SAXException("Found 'parse' attribute with unknown value " + parse + " at " + getLocation());
}
} catch (SourceException se) {
throw SourceUtil.handle(se);
} finally {
if (url != null) {
resolver.release(url);
}
}
}