Search in sources :

Example 1 with TemplateResolution

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);
}
Also used : SpringTemplateEngine(org.thymeleaf.spring5.SpringTemplateEngine) TemplateMode(org.thymeleaf.templatemode.TemplateMode) IEngineConfiguration(org.thymeleaf.IEngineConfiguration) ClassPathXmlApplicationContext(org.springframework.context.support.ClassPathXmlApplicationContext) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource) Test(org.junit.Test)

Example 2 with TemplateResolution

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;
}
Also used : StringTemplateResource(org.thymeleaf.templateresource.StringTemplateResource) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource) NonCacheableCacheEntryValidity(org.thymeleaf.cache.NonCacheableCacheEntryValidity)

Example 3 with 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);
}
Also used : TemplateMode(org.thymeleaf.templatemode.TemplateMode) TemplateCacheKey(org.thymeleaf.cache.TemplateCacheKey) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateParser(org.thymeleaf.templateparser.ITemplateParser) IEngineContext(org.thymeleaf.context.IEngineContext)

Example 4 with TemplateResolution

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);
}
Also used : TemplateMode(org.thymeleaf.templatemode.TemplateMode) TemplateCacheKey(org.thymeleaf.cache.TemplateCacheKey) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateParser(org.thymeleaf.templateparser.ITemplateParser) IEngineContext(org.thymeleaf.context.IEngineContext)

Example 5 with TemplateResolution

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);
}
Also used : ITemplateParser(org.thymeleaf.templateparser.ITemplateParser) TemplateCacheKey(org.thymeleaf.cache.TemplateCacheKey) TreeSet(java.util.TreeSet) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource)

Aggregations

TemplateResolution (org.thymeleaf.templateresolver.TemplateResolution)14 TemplateCacheKey (org.thymeleaf.cache.TemplateCacheKey)6 TemplateMode (org.thymeleaf.templatemode.TemplateMode)6 ITemplateParser (org.thymeleaf.templateparser.ITemplateParser)6 ITemplateResource (org.thymeleaf.templateresource.ITemplateResource)6 Context (org.thymeleaf.context.Context)4 IEngineContext (org.thymeleaf.context.IEngineContext)4 Test (org.junit.Test)3 ClassPathXmlApplicationContext (org.springframework.context.support.ClassPathXmlApplicationContext)3 TemplateProcessingParameters (org.thymeleaf.TemplateProcessingParameters)3 NonCacheableCacheEntryValidity (org.thymeleaf.cache.NonCacheableCacheEntryValidity)3 IResourceResolver (org.thymeleaf.resourceresolver.IResourceResolver)3 InputStream (java.io.InputStream)2 TreeSet (java.util.TreeSet)2 Configuration (org.thymeleaf.Configuration)2 IEngineConfiguration (org.thymeleaf.IEngineConfiguration)2 TemplateEngine (org.thymeleaf.TemplateEngine)2 StringWriter (java.io.StringWriter)1 Resource (org.apache.sling.api.resource.Resource)1 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)1