use of freemarker.cache.TemplateCache.MaybeMissingTemplate in project freemarker by apache.
the class Configuration method getTemplate.
/**
* Retrieves the template with the given name (and according the specified further parameters) from the template
* cache, loading it into the cache first if it's missing/staled.
*
* <p>
* This method is thread-safe.
*
* <p>
* See {@link Configuration} for an example of basic usage.
*
* @param name
* The name or path of the template, which is not a real path, but interpreted inside the current
* {@link TemplateLoader}. Can't be {@code null}. The exact syntax of the name depends on the underlying
* {@link TemplateLoader}, but the cache makes some assumptions. First, the name is expected to be a
* hierarchical path, with path components separated by a slash character (not with backslash!). The path
* (the name) given here must <em>not</em> begin with slash; it's always interpreted relative to the
* "template root directory". Then, the {@code ..} and {@code .} path meta-elements will be resolved. For
* example, if the name is {@code a/../b/./c.ftl}, then it will be simplified to {@code b/c.ftl}. The
* rules regarding this are the same as with conventional UN*X paths. The path must not reach outside the
* template root directory, that is, it can't be something like {@code "../templates/my.ftl"} (not even
* if this path happens to be equivalent with {@code "/my.ftl"}). Furthermore, the path is allowed to
* contain at most one path element whose name is {@code *} (asterisk). This path meta-element triggers
* the <i>acquisition mechanism</i>. If the template is not found in the location described by the
* concatenation of the path left to the asterisk (called base path) and the part to the right of the
* asterisk (called resource path), the cache will attempt to remove the rightmost path component from
* the base path ("go up one directory") and concatenate that with the resource path. The process is
* repeated until either a template is found, or the base path is completely exhausted.
*
* @param locale
* The requested locale of the template. This is what {@link Template#getLocale()} on the resulting
* {@link Template} will return (unless it's overridden via {@link #getTemplateConfigurations()}). This
* parameter can be {@code null} since 2.3.22, in which case it defaults to
* {@link Configuration#getLocale()} (note that {@link Template#getLocale()} will give the default value,
* not {@code null}). This parameter also drives localized template lookup. Assuming that you have
* specified {@code en_US} as the locale and {@code myTemplate.ftl} as the name of the template, and the
* default {@link TemplateLookupStrategy} is used and
* {@code #setLocalizedLookup(boolean) localized_lookup} is {@code true}, FreeMarker will first try to
* retrieve {@code myTemplate_en_US.html}, then {@code myTemplate.en.ftl}, and finally
* {@code myTemplate.ftl}. Note that that the template's locale will be {@code en_US} even if it only
* finds {@code myTemplate.ftl}. Note that when the {@code locale} setting is overridden with a
* {@link TemplateConfiguration} provided by {@link #getTemplateConfigurations()}, that overrides the
* value specified here, but only after the localized lookup, that is, it modifies the template
* found by the localized lookup.
*
* @param customLookupCondition
* This value can be used by a custom {@link TemplateLookupStrategy}; has no effect with the default one.
* Can be {@code null} (though it's up to the custom {@link TemplateLookupStrategy} if it allows that).
* This object will be used as part of the cache key, so it must to have a proper
* {@link Object#equals(Object)} and {@link Object#hashCode()} method. It also should have reasonable
* {@link Object#toString()}, as it's possibly quoted in error messages. The expected type is up to the
* custom {@link TemplateLookupStrategy}. See also:
* {@link TemplateLookupContext#getCustomLookupCondition()}.
*
* @param encoding
* Deprecated mechanism, {@code null} is the recommended; the charset used to interpret the template
* source code bytes (if it's read from a binary source). Can be {@code null} since 2.3.22, in which case
* it will default to {@link Configuration#getEncoding(Locale)} where {@code Locale} is the
* {@code locale} parameter (when {@code locale} was {@code null} too, the its default value is used
* instead). Why is this deprecated: It doesn't make sense to get the <em>same</em> template with
* different encodings, hence, it's error prone to specify the encoding where you get the template.
* Instead, if you have template "files" with different charsets, you should use
* {@link #setTemplateConfigurations(TemplateConfigurationFactory)}, where you can associate encodings to
* individual templates based on their names (like which "directory" are they in, what's their file
* extension, etc.). The encoding associated with the templates that way overrides the encoding that you
* specify here.
*
* @param parseAsFTL
* If {@code true}, the loaded template is parsed and interpreted normally, as a regular FreeMarker
* template. If {@code false}, the loaded template is treated as a static text, so <code>${...}</code>,
* {@code <#...>} etc. will not have special meaning in it.
*
* @param ignoreMissing
* If {@code true}, the method won't throw {@link TemplateNotFoundException} if the template doesn't
* exist, instead it returns {@code null}. Other kind of exceptions won't be suppressed.
*
* @return the requested template; maybe {@code null} when the {@code ignoreMissing} parameter is {@code true}.
*
* @throws TemplateNotFoundException
* If the template could not be found. Note that this exception extends {@link IOException}.
* @throws MalformedTemplateNameException
* If the template name given was in violation with the {@link TemplateNameFormat} in use. Note that
* this exception extends {@link IOException}.
* @throws ParseException
* (extends <code>IOException</code>) if the template is syntactically bad. Note that this exception
* extends {@link IOException}.
* @throws IOException
* If there was some other problem with reading the template "file". Note that the other exceptions
* extend {@link IOException}, so this should be catched the last.
*
* @since 2.3.22
*/
public Template getTemplate(String name, Locale locale, Object customLookupCondition, String encoding, boolean parseAsFTL, boolean ignoreMissing) throws TemplateNotFoundException, MalformedTemplateNameException, ParseException, IOException {
if (locale == null) {
locale = getLocale();
}
if (encoding == null) {
encoding = getEncoding(locale);
}
final MaybeMissingTemplate maybeTemp = cache.getTemplate(name, locale, customLookupCondition, encoding, parseAsFTL);
final Template temp = maybeTemp.getTemplate();
if (temp == null) {
if (ignoreMissing) {
return null;
}
TemplateLoader tl = getTemplateLoader();
String msg;
if (tl == null) {
msg = "Don't know where to load template " + StringUtil.jQuote(name) + " from because the \"template_loader\" FreeMarker " + "setting wasn't set (Configuration.setTemplateLoader), so it's null.";
} else {
final String missingTempNormName = maybeTemp.getMissingTemplateNormalizedName();
final String missingTempReason = maybeTemp.getMissingTemplateReason();
final TemplateLookupStrategy templateLookupStrategy = getTemplateLookupStrategy();
msg = "Template not found for name " + StringUtil.jQuote(name) + (missingTempNormName != null && name != null && !removeInitialSlash(name).equals(missingTempNormName) ? " (normalized: " + StringUtil.jQuote(missingTempNormName) + ")" : "") + (customLookupCondition != null ? " and custom lookup condition " + StringUtil.jQuote(customLookupCondition) : "") + "." + (missingTempReason != null ? "\nReason given: " + ensureSentenceIsClosed(missingTempReason) : "") + "\nThe name was interpreted by this TemplateLoader: " + StringUtil.tryToString(tl) + "." + (!isKnownNonConfusingLookupStrategy(templateLookupStrategy) ? "\n(Before that, the name was possibly changed by this lookup strategy: " + StringUtil.tryToString(templateLookupStrategy) + ".)" : "") + // Suspected reasons or warning:
(!templateLoaderExplicitlySet ? "\nWarning: The \"template_loader\" FreeMarker setting " + "wasn't set (Configuration.setTemplateLoader), and using the default value " + "is most certainly not intended and dangerous, and can be the cause of this error." : "") + (missingTempReason == null && name.indexOf('\\') != -1 ? "\nWarning: The name contains backslash (\"\\\") instead of slash (\"/\"); " + "template names should use slash only." : "");
}
String normName = maybeTemp.getMissingTemplateNormalizedName();
throw new TemplateNotFoundException(normName != null ? normName : name, customLookupCondition, msg);
}
return temp;
}
Aggregations