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