Search in sources :

Example 1 with IEngineContext

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();
}
Also used : IEngineContext(org.thymeleaf.context.IEngineContext)

Example 2 with IEngineContext

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);
}
Also used : IEngineContext(org.thymeleaf.context.IEngineContext)

Example 3 with IEngineContext

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);
}
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 IEngineContext

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);
}
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)

Aggregations

IEngineContext (org.thymeleaf.context.IEngineContext)4 TemplateCacheKey (org.thymeleaf.cache.TemplateCacheKey)2 TemplateMode (org.thymeleaf.templatemode.TemplateMode)2 ITemplateParser (org.thymeleaf.templateparser.ITemplateParser)2 TemplateResolution (org.thymeleaf.templateresolver.TemplateResolution)2