public final boolean invoke(Environment env,
InvokeContext context) throws Exception {
final Map objectModel = env.getObjectModel();
String resolvedSource = this.source.resolve(context, objectModel);
String resolvedPrefix = this.prefix.resolve(context, objectModel);
if (resolvedSource.length() == 0) {
throw new ProcessingException("Source of mount statement is empty");
}
TreeProcessor processor = getProcessor(resolvedSource);
// Save context
String oldPrefix = env.getURIPrefix();
String oldURI = env.getURI();
String oldContext = env.getContext();
Object oldPassThrough = env.getAttribute(COCOON_PASS_THROUGH);
env.setAttribute(COCOON_PASS_THROUGH, this.passThrough);
boolean pipelineWasBuilt = false;
try {
env.changeContext(resolvedPrefix, resolvedSource);
if (context.isBuildingPipelineOnly()) {
// Propagate pipelines
ProcessingPipeline pp = processor.buildPipeline(env);
if (pp != null) {
context.setProcessingPipeline( pp );
pipelineWasBuilt = true;
}
} else {
// Processor will create its own pipelines
pipelineWasBuilt = processor.process(env);
}
} catch(Exception e) {
// Wrap with our location
throw ProcessingException.throwLocated("Sitemap: error when calling sub-sitemap", e, getLocation());
} finally {
// We restore the context only if no pipeline was built. This allows the pipeline
// environment to be left unchanged when we go back to ancestor processors.
// If no pipeline was built, we restore the context, so that the current processor
// continues executing the sitemap in the correct environment.
if (!pipelineWasBuilt) {
env.setContext(oldPrefix, oldURI, oldContext);
}
if (oldPassThrough != null) {
env.setAttribute(COCOON_PASS_THROUGH, oldPassThrough);
} else {
env.removeAttribute(COCOON_PASS_THROUGH);
}
// Turning recomposing as a test, according to:
// http://marc.theaimsgroup.com/?t=106802211400005&r=1&w=2
// Recompose pipelines which may have been recomposed by subsitemap
// context.recompose(this.manager);
}
return pipelineWasBuilt;
}
|