Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make AbstractTemplateEngine#init method final, use lazy instantiation #591

Merged
merged 3 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 39 additions & 24 deletions pippo-core/src/main/java/ro/pippo/core/AbstractTemplateEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,7 @@
import java.util.Locale;

/**
* Convenience abstract implementation of {@link TemplateEngine}
*
* To use the convenience methods in this class, implementations must override {@link #init(Application)}
* and call this class' implementation before performing any of their initialization.
*
* @see TemplateEngine
* Convenience abstract implementation of {@link TemplateEngine}.
*
* @author Ranganath Kini
*/
Expand All @@ -37,28 +32,20 @@ public abstract class AbstractTemplateEngine implements TemplateEngine {
private Router router;
private PippoSettings pippoSettings;

private Application application;

private String fileExtension;
private String templatePathPrefix;

/**
* Performs common initialization for template engines.
*
* Implementations must override this method to do their own template engine specific initialization.
* To use the convenience of this class, implementations must invoke this class's implementation before
* performing their own initialization.
* This method is called by {@link Application#setTemplateEngine(TemplateEngine)}.
*
* @param application reference to the Pippo {@link Application} that can be used to retrieve settings
* and other settings for the initialization
*/
@Override
public void init(Application application) {
languages = application.getLanguages();
messages = application.getMessages();
router = application.getRouter();
pippoSettings = application.getPippoSettings();

fileExtension = pippoSettings.getString(PippoConstants.SETTING_TEMPLATE_EXTENSION, getDefaultFileExtension());
templatePathPrefix = pippoSettings.getString(PippoConstants.SETTING_TEMPLATE_PATH_PREFIX, TemplateEngine.DEFAULT_PATH_PREFIX);
public final void init(Application application) {
this.application = application;
}

/**
Expand All @@ -85,62 +72,82 @@ public final void setFileExtension(String extension) {
* @return String the configured file extension for template resources
*/
protected final String getFileExtension() {
if (fileExtension == null) {
fileExtension = getPippoSettings().getString(PippoConstants.SETTING_TEMPLATE_EXTENSION, getDefaultFileExtension());
}

return fileExtension;
}

/**
* @see Application#getLanguages()
*/
protected final Languages getLanguages() {
if (languages == null) {
languages = getApplication().getLanguages();
}

return languages;
}

/**
* @see Application#getMessages()
*/
protected final Messages getMessages() {
return this.messages;
if (messages == null) {
messages = getApplication().getMessages();
}

return messages;
}

/**
* @see Application#getPippoSettings()
*/
protected final PippoSettings getPippoSettings() {
if (pippoSettings == null) {
pippoSettings = getApplication().getPippoSettings();
}

return pippoSettings;
}

/**
* @see Languages#getLocaleOrDefault(String)
*/
protected final Locale getLocaleOrDefault(String language) {
return languages.getLocaleOrDefault(language);
return getLanguages().getLocaleOrDefault(language);
}

/**
* @see Languages#getLocaleOrDefault(RouteContext)
*/
protected final Locale getLocaleOrDefault(RouteContext routeContext) {
return languages.getLocaleOrDefault(routeContext);
return getLanguages().getLocaleOrDefault(routeContext);
}

/**
* @see Languages#getLanguageOrDefault(String)
*/
protected final String getLanguageOrDefault(String language) {
return languages.getLanguageOrDefault(language);
return getLanguages().getLanguageOrDefault(language);
}

/**
* @see Languages#getLanguageOrDefault(RouteContext)
*/
protected final String getLanguageOrDefault(RouteContext routeContext) {
return languages.getLanguageOrDefault(routeContext);
return getLanguages().getLanguageOrDefault(routeContext);
}

/**
* @see Application#getRouter()
*/
protected final Router getRouter() {
if (router == null) {
router = getApplication().getRouter();
}

return router;
}

Expand All @@ -150,7 +157,15 @@ protected final Router getRouter() {
* @return String the template path prefix for loading template resources
*/
protected final String getTemplatePathPrefix() {
if (templatePathPrefix == null) {
templatePathPrefix = getPippoSettings().getString(PippoConstants.SETTING_TEMPLATE_PATH_PREFIX, TemplateEngine.DEFAULT_PATH_PREFIX);
}

return templatePathPrefix;
}

protected final Application getApplication() {
return application;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,6 @@ public void shouldReturnTemplatePathPrefixConfiguredInSettings() {

private static class TestTemplateEngine extends AbstractTemplateEngine {

@Override
public void init(Application application) {
super.init(application);
}

@Override
public void renderString(String templateContent, Map<String, Object> model, Writer writer) {
// do nothing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,9 @@
import freemarker.template.Template;
import org.kohsuke.MetaInfServices;
import ro.pippo.core.AbstractTemplateEngine;
import ro.pippo.core.Application;
import ro.pippo.core.PippoConstants;
import ro.pippo.core.PippoRuntimeException;
import ro.pippo.core.PippoSettings;
import ro.pippo.core.TemplateEngine;
import ro.pippo.core.route.Router;
import ro.pippo.core.util.StringUtils;

import java.io.Writer;
Expand All @@ -41,9 +38,10 @@ public class FreemarkerTemplateEngine extends AbstractTemplateEngine {

public static final String FTL = "ftl";

private Configuration configuration;

private WebjarsAtMethod webjarResourcesMethod;
private PublicAtMethod publicResourcesMethod;
private Configuration configuration;

static {
try {
Expand All @@ -54,26 +52,53 @@ public class FreemarkerTemplateEngine extends AbstractTemplateEngine {
}

@Override
public void init(Application application) {
super.init(application);
public void renderString(String templateContent, Map<String, Object> model, Writer writer) {
Map <String, Object> enhancedModel = enhancesTemplateModel(model);

try {
Template template = new Template("StringTemplate", templateContent, getConfiguration());
template.process(enhancedModel, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
}
}

Router router = getRouter();
PippoSettings pippoSettings = getPippoSettings();
@Override
public void renderResource(String templateName, Map<String, Object> model, Writer writer) {
Map <String, Object> enhancedModel = enhancesTemplateModel(model);
Locale locale = (Locale) enhancedModel.get("locale");

configuration = new Configuration(Configuration.VERSION_2_3_21);
try {
if (templateName.indexOf('.') == -1) {
templateName += "." + getFileExtension();
}
Template template = getConfiguration().getTemplate(templateName, locale);
template.process(enhancedModel, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
}
}

@Override
protected String getDefaultFileExtension() {
return FTL;
}

protected Configuration createConfiguration() {
Configuration configuration = new Configuration(Configuration.VERSION_2_3_21);
configuration.setDefaultEncoding(PippoConstants.UTF8);
configuration.setOutputEncoding(PippoConstants.UTF8);
configuration.setLocalizedLookup(true);
configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, getTemplatePathPrefix());

// We also do not want Freemarker to chose a platform dependent
// We also do not want Freemarker to choose a platform dependent
// number formatting. Eg "1000" could be printed out by FTL as "1,000"
// on some platforms.
// See also:
// http://freemarker.sourceforge.net/docs/app_faq.html#faq_number_grouping
configuration.setNumberFormat("0.######"); // now it will print 1000000

if (pippoSettings.isDev()) {
if (getPippoSettings().isDev()) {
configuration.setTemplateUpdateDelayMilliseconds(0); // disable cache
} else {
// never update the templates in production or while testing...
Expand All @@ -85,85 +110,57 @@ public void init(Application application) {
}

// set global template variables
configuration.setSharedVariable("contextPath", new SimpleScalar(router.getContextPath()));
configuration.setSharedVariable("appPath", new SimpleScalar(router.getApplicationPath()));
configuration.setSharedVariable("contextPath", new SimpleScalar(getRouter().getContextPath()));
configuration.setSharedVariable("appPath", new SimpleScalar(getRouter().getApplicationPath()));

webjarResourcesMethod = new WebjarsAtMethod(router);
publicResourcesMethod = new PublicAtMethod(router);

// allow custom initialization
init(application, configuration);
}

@Override
protected String getDefaultFileExtension() {
return FTL;
return configuration;
}

@Override
public void renderString(String templateContent, Map<String, Object> model, Writer writer) {
protected Map<String, Object> enhancesTemplateModel(Map<String, Object> model) {
// prepare the locale-aware i18n method
String language = (String) model.get(PippoConstants.REQUEST_PARAMETER_LANG);
if (StringUtils.isNullOrEmpty(language)) {
language = getLanguageOrDefault(language);
}
model.put("lang", language);
model.put("i18n", new I18nMethod(getMessages(), language));

// prepare the locale-aware prettyTime method
Locale locale = (Locale) model.get(PippoConstants.REQUEST_PARAMETER_LOCALE);
if (locale == null) {
locale = getLocaleOrDefault(language);
}
model.put("locale", locale);
model.put("prettyTime", new PrettyTimeMethod(locale));
model.put("formatTime", new FormatTimeMethod(locale));
model.put("webjarsAt", webjarResourcesMethod);
model.put("publicAt", publicResourcesMethod);
model.put("webjarsAt", getWebjarResourcesMethod());
model.put("publicAt", getPublicResourcesMethod());

try {
Template template = new Template("StringTemplate", templateContent, configuration);
template.process(model, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
}
return model;
}

@Override
public void renderResource(String templateName, Map<String, Object> model, Writer writer) {
// prepare the locale-aware i18n method
String language = (String) model.get(PippoConstants.REQUEST_PARAMETER_LANG);
if (StringUtils.isNullOrEmpty(language)) {
language = getLanguageOrDefault(language);
protected final WebjarsAtMethod getWebjarResourcesMethod() {
if (webjarResourcesMethod == null) {
webjarResourcesMethod = new WebjarsAtMethod(getRouter());
}
model.put("i18n", new I18nMethod(getMessages(), language));

// prepare the locale-aware prettyTime method
Locale locale = (Locale) model.get(PippoConstants.REQUEST_PARAMETER_LOCALE);
if (locale == null) {
locale = getLocaleOrDefault(language);
}
model.put("prettyTime", new PrettyTimeMethod(locale));
model.put("formatTime", new FormatTimeMethod(locale));
model.put("webjarsAt", webjarResourcesMethod);
model.put("publicAt", publicResourcesMethod);
return webjarResourcesMethod;
}

try {
if (templateName.indexOf('.') == -1) {
templateName += "." + getFileExtension();
}
Template template = configuration.getTemplate(templateName, locale);
template.process(model, writer);
} catch (Exception e) {
throw new PippoRuntimeException(e);
protected final PublicAtMethod getPublicResourcesMethod() {
if (publicResourcesMethod == null) {
publicResourcesMethod = new PublicAtMethod(getRouter());
}

return publicResourcesMethod;
}

/**
* Override this method if you want to modify the template configuration.
*
* @param application
* @param configuration
*/
protected void init(Application application, Configuration configuration) {
private Configuration getConfiguration() {
if (configuration == null) {
configuration = createConfiguration();
}

return configuration;
}

}
Loading