Skip to content

Commit

Permalink
Make AbstractTemplateEngine#init method final, use lazy instantiation (
Browse files Browse the repository at this point in the history
  • Loading branch information
decebals authored Dec 1, 2021
1 parent c0ab004 commit 5906228
Show file tree
Hide file tree
Showing 7 changed files with 264 additions and 304 deletions.
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

0 comments on commit 5906228

Please sign in to comment.