ParseContext context,
String sourceName,
Class<?> expectedType) throws IOException, SAXException
{
// Step 1. Find the name resolver.
NameResolver resolver = getResolver(context);
if (resolver == null)
{
_log(context, "Internal error: couldn't find NameResolver");
return null;
}
// Step 2. Find an InputStreamProvider. Mark a dependency on the base
// provider (if necessary)
InputStreamProvider provider = resolver.getProvider(sourceName);
InputStreamProvider baseProvider = getInputStreamProvider(context);
if (baseProvider instanceof CachingInputStreamProvider)
{
((CachingInputStreamProvider) baseProvider).addCacheDependency(provider);
}
// Step 3. Detect if this will be a circular include.
ArrayList<Object> list =
(ArrayList<Object>) context.getProperty(_SHARE_NAMESPACE, "_includeStack");
Object identifier = provider.getIdentifier();
if ((list != null) && (list.contains(identifier)))
{
// =-=AEW Just logging an error isn't really enough - the include
// will fail, but parsing continues. So, instead, we throw
// an exception...
throw new SAXParseException(_LOG.getMessage(
"CIRCULAR_INCLUDE_DETECTED", sourceName), context.getLocator());
}
// Step 4. Try to get a cached version
Object cached = provider.getCachedResult();
if ((cached != null) && expectedType.isInstance(cached))
return cached;
// Step 5. Set up the new context; first, clone the original
ParseContext newContext = (ParseContext) context.clone();
// Add the current identifer to the stack (used for detecting
// circular includes) placed on the ParseContext
if (list == null)
list = new ArrayList<Object>();
else
list = (ArrayList<Object>) list.clone();
list.add(identifier);
newContext.setProperty(_SHARE_NAMESPACE, "_includeStack", list);
ParserManager parserManager =context.getParserManager();
TreeBuilder builder = new TreeBuilder(parserManager,
expectedType);
InputStream stream = provider.openInputStream();
try
{
InputSource source = new InputSource(stream);
source.setSystemId(sourceName);
setResolver(newContext, resolver.getResolver(sourceName));
setInputStreamProvider(newContext, provider);
// Step 6. Parse!
Object value = builder.parse(context.getXMLProvider(),
source,