Search in sources :

Example 6 with ITemplateResource

use of org.thymeleaf.templateresource.ITemplateResource in project thymeleaf by thymeleaf.

the class StandardMessageResolver method resolveMessage.

public final String resolveMessage(final ITemplateContext context, final Class<?> origin, final String key, final Object[] messageParameters, final boolean performTemplateBasedResolution, final boolean performOriginBasedResolution, final boolean performDefaultBasedResolution) {
    Validate.notNull(context, "Context cannot be null");
    Validate.notNull(context.getLocale(), "Locale in context cannot be null");
    Validate.notNull(key, "Message key cannot be null");
    final Locale locale = context.getLocale();
    /*
         * FIRST STEP: Look for the message using template-based resolution
         *
         * Note that resolution is top-down, this is, starts at the first-level template (the one being executed)
         * and only if a key is not found will try resolving for nested templates in the order they have been nested.
         *
         * This allows container templates to override the messages defined in fragments, which will act as defaults.
         */
    if (performTemplateBasedResolution) {
        for (final TemplateData templateData : context.getTemplateStack()) {
            final String template = templateData.getTemplate();
            final ITemplateResource templateResource = templateData.getTemplateResource();
            final boolean templateCacheable = templateData.getValidity().isCacheable();
            Map<String, String> messagesForLocaleForTemplate;
            // We will ONLY cache messages for cacheable templates. This should adequately control cache growth
            if (templateCacheable) {
                ConcurrentHashMap<Locale, Map<String, String>> messagesByLocaleForTemplate = this.messagesByLocaleByTemplate.get(template);
                if (messagesByLocaleForTemplate == null) {
                    this.messagesByLocaleByTemplate.putIfAbsent(template, new ConcurrentHashMap<Locale, Map<String, String>>(4));
                    messagesByLocaleForTemplate = this.messagesByLocaleByTemplate.get(template);
                }
                messagesForLocaleForTemplate = messagesByLocaleForTemplate.get(locale);
                if (messagesForLocaleForTemplate == null) {
                    messagesForLocaleForTemplate = resolveMessagesForTemplate(template, templateResource, locale);
                    if (messagesForLocaleForTemplate == null) {
                        messagesForLocaleForTemplate = Collections.emptyMap();
                    }
                    messagesByLocaleForTemplate.putIfAbsent(locale, messagesForLocaleForTemplate);
                    // We retrieve it again in order to be sure its the stored map (because of the 'putIfAbsent')
                    messagesForLocaleForTemplate = messagesByLocaleForTemplate.get(locale);
                }
            } else {
                messagesForLocaleForTemplate = resolveMessagesForTemplate(template, templateResource, locale);
                if (messagesForLocaleForTemplate == null) {
                    messagesForLocaleForTemplate = Collections.emptyMap();
                }
            }
            // Once the messages map has been retrieved, just use it
            final String message = messagesForLocaleForTemplate.get(key);
            if (message != null) {
                return formatMessage(locale, message, messageParameters);
            }
        // Will try the next resolver (if any)
        }
    }
    /*
         * SECOND STEP: Look for the message using origin-based resolution
         */
    if (performOriginBasedResolution && origin != null) {
        ConcurrentHashMap<Locale, Map<String, String>> messagesByLocaleForOrigin = this.messagesByLocaleByOrigin.get(origin);
        if (messagesByLocaleForOrigin == null) {
            this.messagesByLocaleByOrigin.putIfAbsent(origin, new ConcurrentHashMap<Locale, Map<String, String>>(4));
            messagesByLocaleForOrigin = this.messagesByLocaleByOrigin.get(origin);
        }
        Map<String, String> messagesForLocaleForOrigin = messagesByLocaleForOrigin.get(locale);
        if (messagesForLocaleForOrigin == null) {
            messagesForLocaleForOrigin = resolveMessagesForOrigin(origin, locale);
            if (messagesForLocaleForOrigin == null) {
                messagesForLocaleForOrigin = Collections.emptyMap();
            }
            messagesByLocaleForOrigin.putIfAbsent(locale, messagesForLocaleForOrigin);
            // We retrieve it again in order to be sure its the stored map (because of the 'putIfAbsent')
            messagesForLocaleForOrigin = messagesByLocaleForOrigin.get(locale);
        }
        // Once the messages map has been retrieved, just use it
        final String message = messagesForLocaleForOrigin.get(key);
        if (message != null) {
            return formatMessage(locale, message, messageParameters);
        }
    }
    /*
         * THIRD STEP: Try default messages.
         */
    if (performDefaultBasedResolution && this.defaultMessages != null) {
        final String message = this.defaultMessages.getProperty(key);
        if (message != null) {
            return formatMessage(locale, message, messageParameters);
        }
    }
    /*
         * NOT FOUND, return null
         */
    return null;
}
Also used : Locale(java.util.Locale) TemplateData(org.thymeleaf.engine.TemplateData) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap)

Example 7 with ITemplateResource

use of org.thymeleaf.templateresource.ITemplateResource in project thymeleaf by thymeleaf.

the class AbstractTemplateResolver method resolveTemplate.

public final TemplateResolution resolveTemplate(final IEngineConfiguration configuration, final String ownerTemplate, final String template, final Map<String, Object> templateResolutionAttributes) {
    Validate.notNull(configuration, "Engine Configuration cannot be null");
    // ownerTemplate CAN be null
    Validate.notNull(template, "Template Name cannot be null");
    if (!computeResolvable(configuration, ownerTemplate, template, templateResolutionAttributes)) {
        return null;
    }
    final ITemplateResource templateResource = computeTemplateResource(configuration, ownerTemplate, template, templateResolutionAttributes);
    if (templateResource == null) {
        return null;
    }
    if (this.checkExistence && !templateResource.exists()) {
        // will only check if flag set to true
        return null;
    }
    return new TemplateResolution(templateResource, this.checkExistence, computeTemplateMode(configuration, ownerTemplate, template, templateResolutionAttributes), this.useDecoupledLogic, computeValidity(configuration, ownerTemplate, template, templateResolutionAttributes));
}
Also used : ITemplateResource(org.thymeleaf.templateresource.ITemplateResource)

Example 8 with ITemplateResource

use of org.thymeleaf.templateresource.ITemplateResource in project sling by apache.

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, context, 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)

Example 9 with ITemplateResource

use of org.thymeleaf.templateresource.ITemplateResource in project sling by apache.

the class AbstractTemplateResolver method resolveTemplate.

public final TemplateResolution resolveTemplate(final IEngineConfiguration configuration, final IContext context, final String ownerTemplate, final String template, final Map<String, Object> templateResolutionAttributes) {
    Validate.notNull(configuration, "Engine Configuration cannot be null");
    // ownerTemplate CAN be null
    Validate.notNull(template, "Template Name cannot be null");
    if (!computeResolvable(configuration, ownerTemplate, template, templateResolutionAttributes)) {
        return null;
    }
    final ITemplateResource templateResource = computeTemplateResource(configuration, ownerTemplate, template, templateResolutionAttributes);
    if (templateResource == null) {
        return null;
    }
    if (this.checkExistence && !templateResource.exists()) {
        // will only check if flag set to true
        return null;
    }
    return new TemplateResolution(templateResource, this.checkExistence, computeTemplateMode(configuration, ownerTemplate, template, templateResolutionAttributes), this.useDecoupledLogic, computeValidity(configuration, ownerTemplate, template, templateResolutionAttributes));
}
Also used : ITemplateResource(org.thymeleaf.templateresource.ITemplateResource)

Example 10 with ITemplateResource

use of org.thymeleaf.templateresource.ITemplateResource in project sling by apache.

the class SlingResourceTemplateResolver method resolveTemplate.

@Override
public TemplateResolution resolveTemplate(final IEngineConfiguration engineConfiguration, final IContext context, final String ownerTemplate, final String template, final Map<String, Object> templateResolutionAttributes) {
    logger.debug("resolving template '{}'", template);
    if (context instanceof SlingContext) {
        final SlingContext slingContext = (SlingContext) context;
        final ResourceResolver resourceResolver = slingContext.getResourceResolver();
        final Resource resource = resourceResolver.getResource(template);
        if (resource == null) {
            logger.warn("resource for template '{}' is null, not resolving template", template);
            return null;
        }
        final ITemplateResource templateResource = new SlingTemplateResource(resource);
        final boolean templateResourceExistenceVerified = false;
        final TemplateMode templateMode = templateModeProvider.provideTemplateMode(resource);
        if (templateMode == null) {
            logger.warn("template mode for template '{}' is null, not resolving template", template);
            return null;
        } else {
            logger.debug("using template mode {} for template '{}'", templateMode, template);
            final boolean useDecoupledLogic = templateMode.isMarkup() && configuration.useDecoupledLogic();
            final ICacheEntryValidity validity = NonCacheableCacheEntryValidity.INSTANCE;
            return new TemplateResolution(templateResource, templateResourceExistenceVerified, templateMode, useDecoupledLogic, validity);
        }
    } else {
        logger.error("context is not an instance of SlingContext");
        return null;
    }
}
Also used : TemplateMode(org.thymeleaf.templatemode.TemplateMode) SlingContext(org.apache.sling.scripting.thymeleaf.SlingContext) TemplateResolution(org.thymeleaf.templateresolver.TemplateResolution) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource) ResourceResolver(org.apache.sling.api.resource.ResourceResolver) ITemplateResource(org.thymeleaf.templateresource.ITemplateResource) Resource(org.apache.sling.api.resource.Resource) ICacheEntryValidity(org.thymeleaf.cache.ICacheEntryValidity)

Aggregations

ITemplateResource (org.thymeleaf.templateresource.ITemplateResource)12 TemplateResolution (org.thymeleaf.templateresolver.TemplateResolution)6 Map (java.util.Map)2 TreeSet (java.util.TreeSet)2 Resource (org.apache.sling.api.resource.Resource)2 ResourceResolver (org.apache.sling.api.resource.ResourceResolver)2 IEngineConfiguration (org.thymeleaf.IEngineConfiguration)2 TemplateCacheKey (org.thymeleaf.cache.TemplateCacheKey)2 TemplateMode (org.thymeleaf.templatemode.TemplateMode)2 ITemplateParser (org.thymeleaf.templateparser.ITemplateParser)2 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 HashMap (java.util.HashMap)1 Locale (java.util.Locale)1 Properties (java.util.Properties)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 PathBuilder (org.apache.sling.api.resource.path.PathBuilder)1 SlingContext (org.apache.sling.scripting.thymeleaf.SlingContext)1 Test (org.junit.Test)1