use of org.thymeleaf.context.IEngineContext in project sling by apache.
the class TemplateManager method applyPreProcessorsIfNeeded.
/*
* This method manually applies preprocessors to template models that have just been parsed or obtained from
* cache. This is needed for fragments, just before these fragments (coming from templates, not simply parsed
* text) are returned to whoever needs them (usually the fragment insertion mechanism).
*
* NOTE that PRE-PROCESSOR INSTANCES ARE NOT SHARED among the different fragments being inserted
* in a template (or between fragments and the main template). The reason for this is that pre-processors are
* implementations of ITemplateHandler and therefore instances are inserted into processing chains that cannot
* be broken (if a pre-processor is used for the main template its "next" step in the chain cannot be
* 'momentarily' changed in order to be a fragment-building handler instead of the ProcessorTemplateHandler)
*
* The only way therefore among pre-processor instances to actually share information is by setting it into
* the context.
*/
private TemplateModel applyPreProcessorsIfNeeded(final ITemplateContext context, final TemplateModel templateModel) {
final TemplateData templateData = templateModel.getTemplateData();
if (this.configuration.getPreProcessors(templateData.getTemplateMode()).isEmpty()) {
return templateModel;
}
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, templateData, context.getTemplateResolutionAttributes(), context);
final ModelBuilderTemplateHandler builderHandler = new ModelBuilderTemplateHandler(this.configuration, templateData);
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, true, false, builderHandler, null);
templateModel.process(processingHandlerChain);
EngineContextManager.disposeEngineContext(engineContext);
return builderHandler.getModel();
}
use of org.thymeleaf.context.IEngineContext in project sling by apache.
the class TemplateManager method process.
/*
* ---------------
* PROCESS methods
* ---------------
*
* Processing means executing a template that has already been parsed into a TemplateModel object
*/
public void process(final TemplateModel template, final ITemplateContext context, final Writer writer) {
Validate.isTrue(this.configuration == template.getConfiguration(), "Specified template was built by a different Template Engine instance");
/*
* Create the context instance that corresponds to this execution of the template engine
*/
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, template.getTemplateData(), context.getTemplateResolutionAttributes(), context);
/*
* Create the handler chain to process the data.
*
* In this case we are only processing an already existing model, which was created after some computation
* at template-processing time. So this does not come directly from a template, and therefore pre-processors
* should not be applied.
*
* As for post-processors, we know the result of this will not be directly written to output in most cases but
* instead used to create a String that is afterwards inserted into the model as a Text node. In the only cases
* in which this is not true is when this is used inside any kind of Lazy-processing CharSequence writer like
* LazyProcessingCharSequence, and in such case we know those CharSequences are only used when there are
* NO post-processors, so we are safe anyway.
*/
final ProcessorTemplateHandler processorTemplateHandler = new ProcessorTemplateHandler();
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, false, false, processorTemplateHandler, writer);
/*
* Process the template
*/
template.process(processingHandlerChain);
/*
* Dispose the engine context now that processing has been done
*/
EngineContextManager.disposeEngineContext(engineContext);
}
use of org.thymeleaf.context.IEngineContext in project sling by apache.
the class TemplateManager method parseAndProcess.
/*
* -------------------------
* PARSE-AND-PROCESS methods
* -------------------------
*
* These methods perform the whole cycle of a template's processing: resolving, parsing and processing.
* This is only meant to be called from the TemplateEngine
*/
public void parseAndProcess(final TemplateSpec templateSpec, final IContext context, final Writer writer) {
Validate.notNull(templateSpec, "Template Specification cannot be null");
Validate.notNull(context, "Context cannot be null");
Validate.notNull(writer, "Writer cannot be null");
// TemplateSpec will already have validated its contents, so need to do it here (template selectors,
// resolution attributes, etc.)
final String template = templateSpec.getTemplate();
final Set<String> templateSelectors = templateSpec.getTemplateSelectors();
final TemplateMode templateMode = templateSpec.getTemplateMode();
final Map<String, Object> templateResolutionAttributes = templateSpec.getTemplateResolutionAttributes();
final TemplateCacheKey cacheKey = new TemplateCacheKey(// ownerTemplate
null, template, templateSelectors, // lineOffset, colOffset
0, // lineOffset, colOffset
0, templateMode, templateResolutionAttributes);
/*
* First look at the cache - it might be already cached
*/
if (this.templateCache != null) {
final TemplateModel cached = this.templateCache.get(cacheKey);
if (cached != null) {
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, cached.getTemplateData(), templateResolutionAttributes, context);
/*
* Create the handler chain to process the data.
* This is PARSE + PROCESS, so its called from the TemplateEngine, and the only case in which we should apply
* both pre-processors and post-processors (besides creating a last output-to-writer step)
*/
final ProcessorTemplateHandler processorTemplateHandler = new ProcessorTemplateHandler();
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, true, true, processorTemplateHandler, writer);
cached.process(processingHandlerChain);
EngineContextManager.disposeEngineContext(engineContext);
return;
}
}
/*
* Resolve the template
*/
final TemplateResolution templateResolution = resolveTemplate(this.configuration, context, null, template, templateResolutionAttributes, true);
/*
* Build the TemplateData object
*/
final TemplateData templateData = buildTemplateData(templateResolution, template, templateSelectors, templateMode, true);
/*
* Prepare the context instance that corresponds to this execution of the template engine
*/
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, templateData, templateResolutionAttributes, context);
/*
* Create the handler chain to process the data.
* This is PARSE + PROCESS, so its called from the TemplateEngine, and the only case in which we should apply
* both pre-processors and post-processors (besides creating a last output-to-writer step)
*/
final ProcessorTemplateHandler processorTemplateHandler = new ProcessorTemplateHandler();
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, true, true, processorTemplateHandler, writer);
/*
* Obtain the parser
*/
final ITemplateParser parser = getParserForTemplateMode(engineContext.getTemplateMode());
/*
* If the resolved template is cacheable, so we will first read it as an object, cache it, and then process it
*/
if (templateResolution.getValidity().isCacheable() && this.templateCache != null) {
// Create the handler chain to create the Template object
final ModelBuilderTemplateHandler builderHandler = new ModelBuilderTemplateHandler(this.configuration, templateData);
// Process the template into a TemplateModel
parser.parseStandalone(this.configuration, null, template, templateSelectors, templateData.getTemplateResource(), engineContext.getTemplateMode(), templateResolution.getUseDecoupledLogic(), builderHandler);
// Obtain the TemplateModel
final TemplateModel templateModel = builderHandler.getModel();
// Put the new template into cache
this.templateCache.put(cacheKey, templateModel);
// Process the read (+cached) template itself
templateModel.process(processingHandlerChain);
} else {
// Process the template, which is not cacheable (so no worry about caching)
parser.parseStandalone(this.configuration, null, template, templateSelectors, templateData.getTemplateResource(), engineContext.getTemplateMode(), templateResolution.getUseDecoupledLogic(), processingHandlerChain);
}
/*
* Dispose the engine context now that processing has been done
*/
EngineContextManager.disposeEngineContext(engineContext);
}
use of org.thymeleaf.context.IEngineContext in project sling by apache.
the class TemplateManager method parseAndProcessThrottled.
public ThrottledTemplateProcessor parseAndProcessThrottled(final TemplateSpec templateSpec, final IContext context) {
Validate.notNull(templateSpec, "Template Specification cannot be null");
Validate.notNull(context, "Context cannot be null");
// TemplateSpec will already have validated its contents, so need to do it here (template selectors,
// resolution attributes, etc.)
final String template = templateSpec.getTemplate();
final Set<String> templateSelectors = templateSpec.getTemplateSelectors();
final TemplateMode templateMode = templateSpec.getTemplateMode();
final Map<String, Object> templateResolutionAttributes = templateSpec.getTemplateResolutionAttributes();
final TemplateCacheKey cacheKey = new TemplateCacheKey(// ownerTemplate
null, template, templateSelectors, // lineOffset, colOffset
0, // lineOffset, colOffset
0, templateMode, templateResolutionAttributes);
/*
* Instantiate the throttling artifacts
*/
final TemplateFlowController flowController = new TemplateFlowController();
final ThrottledTemplateWriter throttledTemplateWriter = new ThrottledTemplateWriter(template, flowController);
/*
* First look at the cache - it might be already cached
*/
if (this.templateCache != null) {
final TemplateModel cached = this.templateCache.get(cacheKey);
if (cached != null) {
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, cached.getTemplateData(), templateResolutionAttributes, context);
/*
* Create the handler chain to process the data.
* This is PARSE + PROCESS, so its called from the TemplateEngine, and the only case in which we should apply
* both pre-processors and post-processors (besides creating a last output-to-writer step)
*/
final ProcessorTemplateHandler processorTemplateHandler = new ProcessorTemplateHandler();
processorTemplateHandler.setFlowController(flowController);
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, true, true, processorTemplateHandler, throttledTemplateWriter);
/*
* Return the throttled template processor
*/
return new ThrottledTemplateProcessor(templateSpec, engineContext, cached, processingHandlerChain, processorTemplateHandler, flowController, throttledTemplateWriter);
}
}
/*
* Resolve the template
*/
final TemplateResolution templateResolution = resolveTemplate(this.configuration, context, null, template, templateResolutionAttributes, true);
/*
* Build the TemplateData object
*/
final TemplateData templateData = buildTemplateData(templateResolution, template, templateSelectors, templateMode, true);
/*
* Prepare the context instance that corresponds to this execution of the template engine
*/
final IEngineContext engineContext = EngineContextManager.prepareEngineContext(this.configuration, templateData, templateResolutionAttributes, context);
/*
* Create the handler chain to process the data.
* This is PARSE + PROCESS, so its called from the TemplateEngine, and the only case in which we should apply
* both pre-processors and post-processors (besides creating a last output-to-writer step)
*/
final ProcessorTemplateHandler processorTemplateHandler = new ProcessorTemplateHandler();
processorTemplateHandler.setFlowController(flowController);
final ITemplateHandler processingHandlerChain = createTemplateProcessingHandlerChain(engineContext, true, true, processorTemplateHandler, throttledTemplateWriter);
/*
* Obtain the parser
*/
final ITemplateParser parser = getParserForTemplateMode(engineContext.getTemplateMode());
/*
* Parse the template into a TemplateModel. Even if we are not using the cache, throttled template processings
* will always be processed first into a TemplateModel, so that throttling can then be applied on an
* already-in-memory sequence of events
*/
final ModelBuilderTemplateHandler builderHandler = new ModelBuilderTemplateHandler(this.configuration, templateData);
parser.parseStandalone(this.configuration, null, template, templateSelectors, templateData.getTemplateResource(), engineContext.getTemplateMode(), templateResolution.getUseDecoupledLogic(), builderHandler);
final TemplateModel templateModel = builderHandler.getModel();
/*
* If cache is active, put the cached TemplateModel into cache
*/
if (templateResolution.getValidity().isCacheable() && this.templateCache != null) {
// Put the new template into cache
this.templateCache.put(cacheKey, templateModel);
}
/*
* Return the throttled template processor
*/
return new ThrottledTemplateProcessor(templateSpec, engineContext, templateModel, processingHandlerChain, processorTemplateHandler, flowController, throttledTemplateWriter);
}
Aggregations