org.beangle.template.freemarker.FreemarkerConfigurer.scala Maven / Gradle / Ivy
package org.beangle.template.freemarker
import java.io.{ File, IOException }
import org.beangle.commons.bean.Initializing
import org.beangle.commons.io.IOs
import org.beangle.commons.lang.ClassLoaders
import org.beangle.commons.lang.Strings.{ split, substringAfter }
import org.beangle.commons.lang.annotation.description
import freemarker.cache.{ FileTemplateLoader, MultiTemplateLoader, TemplateLoader }
import freemarker.template.{ Configuration, ObjectWrapper, TemplateExceptionHandler }
@description("Freemarker配置提供者")
class FreemarkerConfigurer extends Initializing {
//must before configuration init
disableFreemarkerLogger()
val config = new Configuration()
var contentType: String = _
var enableCache = true
var templatePath: String = _
override def init(): Unit = {
config.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER)
config.setDefaultEncoding("UTF-8")
config.setLocalizedLookup(false)
config.setWhitespaceStripping(true)
val props = properties
for ((key, value) <- props) {
if (null != key && null != value) config.setSetting(key, value)
}
config.setObjectWrapper(createObjectWrapper(props))
config.setTemplateLoader(createTemplateLoader(props))
var content_type = config.getCustomAttribute("content_type").asInstanceOf[String]
if (null == content_type) content_type = "text/html"
if (!content_type.contains("charset"))
content_type += "; charset=" + config.getDefaultEncoding
contentType = content_type
}
/**
* The default template loader is a MultiTemplateLoader which includes
* BeangleClassTemplateLoader(classpath:) and a WebappTemplateLoader
* (webapp:) and FileTemplateLoader(file:) . All template path described
* in init parameter templatePath or TemplatePlath
*
* The ClassTemplateLoader will resolve fully qualified template includes that begin with a slash.
* for example /com/company/template/common.ftl
*
*/
def createTemplateLoader(props: Map[String, String]): TemplateLoader = {
templatePath = props.getOrElse("template_path", "class://")
val paths: Array[String] = split(templatePath, ",")
val loaders = new collection.mutable.ListBuffer[TemplateLoader]
for (path <- paths) {
if (path.startsWith("class://")) {
loaders += new BeangleClassTemplateLoader(substringAfter(path, "class://"))
} else if (path.startsWith("file://")) {
try {
loaders += new FileTemplateLoader(new File(substringAfter(path, "file://")))
} catch {
case e: IOException =>
throw new RuntimeException("templatePath: " + path + " cannot be accessed", e)
}
} else {
throw new RuntimeException("templatePath: " + path
+ " is not well-formed. Use [class://|file://] seperated with ,")
}
}
if (loaders.size == 1) loaders.head else new MultiTemplateLoader(loaders.toArray[TemplateLoader])
}
def createObjectWrapper(props: Map[String, String]): ObjectWrapper = {
val wrapper = new BeangleObjectWrapper(true)
wrapper.setUseCache(false)
wrapper
}
/**
* Load the multi settings from the /META-INF/freemarker.properties and
* /freemarker.properties file on the classpath
*
* @see freemarker.template.Configuration#setSettings for the definition of valid settings
*/
def properties: Map[String, String] = {
val properties = new collection.mutable.HashMap[String, String]
// 1. first META-INF/freemarker.properties
for (url <- ClassLoaders.getResources("META-INF/freemarker.properties"))
properties ++= IOs.readJavaProperties(url)
// 2. second global freemarker.properties
for (url <- ClassLoaders.getResources("freemarker.properties"))
properties ++= IOs.readJavaProperties(url)
// 3. system properties
val sysProps = System.getProperties
val sysKeys = sysProps.propertyNames
while (sysKeys.hasMoreElements) {
val key = sysKeys.nextElement.asInstanceOf[String]
val value: String = sysProps.getProperty(key)
if (key.startsWith("freemarker.")) properties.put(substringAfter(key, "freemarker."), value)
}
if (!enableCache) properties.put(Configuration.TEMPLATE_UPDATE_DELAY_KEY, "0")
properties.toMap
}
def disableFreemarkerLogger(): Unit = {
try {
freemarker.log.Logger.selectLoggerLibrary(freemarker.log.Logger.LIBRARY_NONE)
} catch {
case t: Exception => t.printStackTrace()
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy