use of org.thymeleaf.templateresolver.TemplateResolution in project thymeleaf-tests by thymeleaf.
the class SpringResourceTemplateResolverSpring4Test method testResolveTemplate.
@Test
public void testResolveTemplate() throws Exception {
final SpringTemplateEngine templateEngine = new SpringTemplateEngine();
final IEngineConfiguration configuration = templateEngine.getConfiguration();
final String templateLocation = "spring5/templateresolver/test.html";
final ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring5/templateresolver/applicationContext.xml");
final SpringResourceTemplateResolver resolver = (SpringResourceTemplateResolver) context.getBean("springResourceTemplateResolver");
final TemplateMode templateMode = resolver.getTemplateMode();
Assert.assertEquals(TemplateMode.HTML, templateMode);
final TemplateResolution resolution = resolver.resolveTemplate(configuration, null, "classpath:" + templateLocation, null);
final ITemplateResource templateResource = resolution.getTemplateResource();
final String templateResourceStr = IOUtils.toString(templateResource.reader());
final String testResource = templateResourceStr.replace("\r", "");
final String expected = ResourceUtils.read(ClassLoaderUtils.getClassLoader(SpringResourceTemplateResolverSpring4Test.class).getResourceAsStream(templateLocation), "US-ASCII", true).replace("\r", "");
Assert.assertEquals(expected, testResource);
}
use of org.thymeleaf.templateresolver.TemplateResolution in project thymeleaf-tests by thymeleaf.
the class TestTemplateResolver method resolveTemplate.
public TemplateResolution resolveTemplate(final IEngineConfiguration configuration, final String ownerTemplate, final String template, final Map<String, Object> templateResolutionAttributes) {
final int placeholderPos = this.template.indexOf("{%%}");
final String resource = this.template.substring(0, placeholderPos) + template + this.template.substring(placeholderPos + 4);
final ITemplateResource templateResource = new StringTemplateResource(resource);
final TemplateResolution templateResolution = new TemplateResolution(templateResource, // For the sake of these tests, considering resource existence verified is fine
true, TemplateMode.HTML, false, new NonCacheableCacheEntryValidity());
return templateResolution;
}
use of org.thymeleaf.templateresolver.TemplateResolution in project thymeleaf by thymeleaf.
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, including the throttled writer, which might be only for
*/
final TemplateFlowController flowController = new TemplateFlowController();
final ThrottledTemplateWriter throttledTemplateWriter;
if (templateSpec.isOutputSSE()) {
throttledTemplateWriter = new SSEThrottledTemplateWriter(template, flowController);
} else {
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, 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);
}
use of org.thymeleaf.templateresolver.TemplateResolution in project thymeleaf by thymeleaf.
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, 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.templateresolver.TemplateResolution in project thymeleaf by thymeleaf.
the class TemplateManager method parseStandalone.
/*
* -------------
* PARSE methods
* -------------
*
* Parse methods will create 'template models' that are basically collections of events in the form of an
* immutable IModel implementation.
*/
public TemplateModel parseStandalone(final ITemplateContext context, final String template, final Set<String> templateSelectors, final TemplateMode templateMode, final boolean useCache, final boolean failIfNotExists) {
Validate.notNull(context, "Context cannot be null");
Validate.notNull(template, "Template cannot be null");
// templateSelectors CAN be null if we are going to render the entire template
// templateMode CAN be null if we are going to use the mode specified by the template resolver
// templateResolutionAttributes CAN be null
final String ownerTemplate = context.getTemplateData().getTemplate();
final Map<String, Object> templateResolutionAttributes = context.getTemplateResolutionAttributes();
final Set<String> cleanTemplateSelectors;
if (templateSelectors != null && !templateSelectors.isEmpty()) {
Validate.containsNoEmpties(templateSelectors, "If specified, the Template Selector set cannot contain any nulls or empties");
if (templateSelectors.size() == 1) {
cleanTemplateSelectors = Collections.singleton(templateSelectors.iterator().next());
} else {
// We will be using a TreeSet because we want the selectors to be ORDERED, so that comparison at the
// equals(...) method works alright
cleanTemplateSelectors = Collections.unmodifiableSet(new TreeSet<String>(templateSelectors));
}
} else {
cleanTemplateSelectors = null;
}
final TemplateCacheKey cacheKey = useCache ? new TemplateCacheKey(ownerTemplate, template, cleanTemplateSelectors, 0, 0, templateMode, templateResolutionAttributes) : null;
/*
* First look at the cache - it might be already cached
*/
if (useCache && this.templateCache != null) {
final TemplateModel cached = this.templateCache.get(cacheKey);
if (cached != null) {
/*
* Just at the end, and importantly AFTER CACHING, check if we need to apply any pre-processors
* to this model before returning and letting the engine insert the model in any way it needs.
*/
return applyPreProcessorsIfNeeded(context, cached);
}
}
/*
* Resolve the template
*/
final TemplateResolution templateResolution = resolveTemplate(this.configuration, ownerTemplate, template, templateResolutionAttributes, failIfNotExists);
/*
* Once the template has been resolved (or tried to), and depending on the value of our 'failIfNotExists'
* flag, we will check two conditions in which we will be returning null:
*
* 1. No template resolver has been able to resolve the template (this can happen if resolvers are
* configured with the 'checkExistence' flag to true).
* 2. If the template was resolved, its existence should be checked in order to avoid exceptions during
* the reading phase.
*
* NOTE we will not cache this "null" result because the fact that a template is cacheable or not is
* determined by template resolvers. And in this case there is no template resolver being applied
* (actually, we are here because no resolver had success).
*/
if (!failIfNotExists) {
if (templateResolution == null) {
// No resolver could resolve this
return null;
}
if (!templateResolution.isTemplateResourceExistenceVerified()) {
final ITemplateResource resource = templateResolution.getTemplateResource();
if (resource == null || !resource.exists()) {
// has not been cached (e.g. when it does not exist)
return null;
}
}
}
/*
* Build the TemplateData object
*/
final TemplateData templateData = buildTemplateData(templateResolution, template, cleanTemplateSelectors, templateMode, useCache);
/*
* Create the Template Handler that will be in charge of building the TemplateModel
*/
final ModelBuilderTemplateHandler builderHandler = new ModelBuilderTemplateHandler(this.configuration, templateData);
/*
* PROCESS THE TEMPLATE
*/
final ITemplateParser parser = getParserForTemplateMode(templateData.getTemplateMode());
parser.parseStandalone(this.configuration, ownerTemplate, template, cleanTemplateSelectors, templateData.getTemplateResource(), templateData.getTemplateMode(), templateResolution.getUseDecoupledLogic(), builderHandler);
final TemplateModel templateModel = builderHandler.getModel();
/*
* Cache the template if it is cacheable
*/
if (useCache && this.templateCache != null) {
if (templateResolution.getValidity().isCacheable()) {
this.templateCache.put(cacheKey, templateModel);
}
}
/*
* Last step: just at the end, and importantly AFTER CACHING, check if we need to apply any pre-processors
* to this model before returning and letting the engine insert the model in any way it needs.
*/
return applyPreProcessorsIfNeeded(context, templateModel);
}
Aggregations