fix template bug

This commit is contained in:
Looly
2020-03-10 00:51:16 +08:00
parent 30e73d4b5a
commit 0781be4e1c
14 changed files with 308 additions and 132 deletions

View File

@@ -13,6 +13,7 @@
* 【core 】 修复DataUtil.parseLocalDateTime无时间部分报错问题issue#I1B18H@Gitee * 【core 】 修复DataUtil.parseLocalDateTime无时间部分报错问题issue#I1B18H@Gitee
* 【core 】 修复NetUtil.isUsableLocalPort()判断问题issue#765@Github * 【core 】 修复NetUtil.isUsableLocalPort()判断问题issue#765@Github
* 【poi 】 修复ExcelWriter写出多个sheet错误的问题issue#766@Github * 【poi 】 修复ExcelWriter写出多个sheet错误的问题issue#766@Github
* 【extra 】 修复模板引擎自定义配置失效问题issue#767@Github
------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------

View File

@@ -21,7 +21,7 @@ public abstract class AtomicLoader<T> implements Loader<T>, Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 被加载对象的引用 */ /** 被加载对象的引用 */
private final AtomicReference<T> reference = new AtomicReference<T>(); private final AtomicReference<T> reference = new AtomicReference<>();
/** /**
* 获取一个对象,第一次调用此方法时初始化对象然后返回,之后调用此方法直接返回原对象 * 获取一个对象,第一次调用此方法时初始化对象然后返回,之后调用此方法直接返回原对象

View File

@@ -1,6 +1,6 @@
package cn.hutool.core.lang.tree; package cn.hutool.core.lang.tree;
import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.parser.DefaultNodeParser; import cn.hutool.core.lang.tree.parser.DefaultNodeParser;
import cn.hutool.core.lang.tree.parser.NodeParser; import cn.hutool.core.lang.tree.parser.NodeParser;
@@ -8,7 +8,7 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* 树工具类 可参考 cn.hutool.core.lang.TreeTest * 树工具类
* *
* @author liangbaikai * @author liangbaikai
*/ */
@@ -16,6 +16,9 @@ public class TreeUtil {
/** /**
* 树构建 * 树构建
*
* @param list 源数据集合
* @return List
*/ */
public static List<Tree<Integer>> build(List<TreeNode<Integer>> list) { public static List<Tree<Integer>> build(List<TreeNode<Integer>> list) {
return build(list, 0); return build(list, 0);
@@ -23,13 +26,25 @@ public class TreeUtil {
/** /**
* 树构建 * 树构建
*
* @param <E> ID类型
* @param list 源数据集合
* @param parentId 最顶层父id值 一般为 0 之类
* @return List
*/ */
public static <T> List<Tree<T>> build(List<TreeNode<T>> list, T parentId) { public static <E> List<Tree<E>> build(List<TreeNode<E>> list, E parentId) {
return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, new DefaultNodeParser<>()); return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, new DefaultNodeParser<>());
} }
/** /**
* 树构建 * 树构建
*
* @param <T> 转换的实体 为数据源里的对象类型
* @param <E> ID类型
* @param list 源数据集合
* @param parentId 最顶层父id值 一般为 0 之类
* @param nodeParser 转换器
* @return List
*/ */
public static <T, E> List<Tree<E>> build(List<T> list, E parentId, NodeParser<T, E> nodeParser) { public static <T, E> List<Tree<E>> build(List<T> list, E parentId, NodeParser<T, E> nodeParser) {
return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, nodeParser); return build(list, parentId, TreeNodeConfig.DEFAULT_CONFIG, nodeParser);
@@ -38,22 +53,23 @@ public class TreeUtil {
/** /**
* 树构建 * 树构建
* *
* @param <T> 转换的实体 为数据源里的对象类型
* @param <E> ID类型
* @param list 源数据集合 * @param list 源数据集合
* @param parentId 最顶层父id值 一般为 0 之类 * @param parentId 最顶层父id值 一般为 0 之类
* @param treeNodeConfig 配置 * @param treeNodeConfig 配置
* @param nodeParser 转换器 * @param nodeParser 转换器
* @param <T> 转换的实体 为数据源里的对象类型
* @return List * @return List
*/ */
public static <T, E> List<Tree<E>> build(List<T> list, E parentId, TreeNodeConfig treeNodeConfig, NodeParser<T, E> nodeParser) { public static <T, E> List<Tree<E>> build(List<T> list, E parentId, TreeNodeConfig treeNodeConfig, NodeParser<T, E> nodeParser) {
List<Tree<E>> treeNodes = CollectionUtil.newArrayList(); List<Tree<E>> treeNodes = CollUtil.newArrayList();
for (T obj : list) { for (T obj : list) {
Tree<E> treeNode = new Tree<>(treeNodeConfig); Tree<E> treeNode = new Tree<>(treeNodeConfig);
nodeParser.parse(obj, treeNode); nodeParser.parse(obj, treeNode);
treeNodes.add(treeNode); treeNodes.add(treeNode);
} }
List<Tree<E>> finalTreeNodes = CollectionUtil.newArrayList(); List<Tree<E>> finalTreeNodes = CollUtil.newArrayList();
for (Tree<E> treeNode : treeNodes) { for (Tree<E> treeNode : treeNodes) {
if (parentId.equals(treeNode.getParentId())) { if (parentId.equals(treeNode.getParentId())) {
finalTreeNodes.add(treeNode); finalTreeNodes.add(treeNode);
@@ -75,7 +91,7 @@ public class TreeUtil {
*/ */
private static <T> void innerBuild(List<Tree<T>> treeNodes, Tree<T> parentNode, int deep, Integer maxDeep) { private static <T> void innerBuild(List<Tree<T>> treeNodes, Tree<T> parentNode, int deep, Integer maxDeep) {
if (CollectionUtil.isEmpty(treeNodes)) { if (CollUtil.isEmpty(treeNodes)) {
return; return;
} }
//maxDeep 可能为空 //maxDeep 可能为空
@@ -89,7 +105,7 @@ public class TreeUtil {
if (parentNode.getId().equals(childNode.getParentId())) { if (parentNode.getId().equals(childNode.getParentId())) {
List<Tree<T>> children = parentNode.getChildren(); List<Tree<T>> children = parentNode.getChildren();
if (children == null) { if (children == null) {
children = CollectionUtil.newArrayList(); children = CollUtil.newArrayList();
parentNode.setChildren(children); parentNode.setChildren(children);
} }
children.add(childNode); children.add(childNode);

View File

@@ -43,8 +43,8 @@ public class TreeTest {
TreeNodeConfig treeNodeConfig = new TreeNodeConfig(); TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都要默认值的 // 自定义属性名 都要默认值的
treeNodeConfig.setWeightKey("order"); treeNodeConfig.setWeightKey("order");
treeNodeConfig.setDeep(3);
treeNodeConfig.setIdKey("rid"); treeNodeConfig.setIdKey("rid");
treeNodeConfig.setDeep(3);
//转换器 //转换器
List<Tree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig, List<Tree<String>> treeNodes = TreeUtil.build(nodeList, "0", treeNodeConfig,

View File

@@ -2,45 +2,58 @@ package cn.hutool.extra.template;
import java.io.Serializable; import java.io.Serializable;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.util.Objects;
import cn.hutool.core.util.CharsetUtil; import cn.hutool.core.util.CharsetUtil;
/** /**
* 模板配置 * 模板配置
* *
* @author looly * @author looly
* @since 4.1.0 * @since 4.1.0
*/ */
public class TemplateConfig implements Serializable { public class TemplateConfig implements Serializable {
private static final long serialVersionUID = 2933113779920339523L; private static final long serialVersionUID = 2933113779920339523L;
/** 编码 */ public static final TemplateConfig DEFAULT = new TemplateConfig();
/**
* 编码
*/
private Charset charset; private Charset charset;
/** 模板路径如果ClassPath或者WebRoot模式则表示相对路径 */ /**
* 模板路径如果ClassPath或者WebRoot模式则表示相对路径
*/
private String path; private String path;
/** 模板资源加载方式 */ /**
* 模板资源加载方式
*/
private ResourceMode resourceMode; private ResourceMode resourceMode;
/**
* 自定义引擎当多个jar包引入时可以自定使用的默认引擎
*/
private Class<? extends TemplateEngine> customEngine;
/** /**
* 默认构造使用UTF8编码默认从ClassPath获取模板 * 默认构造使用UTF8编码默认从ClassPath获取模板
*/ */
public TemplateConfig() { public TemplateConfig() {
this((String)null); this(null);
} }
/** /**
* 构造默认UTF-8编码 * 构造默认UTF-8编码
* *
* @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径 * @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径
*/ */
public TemplateConfig(String path) { public TemplateConfig(String path) {
this(path, ResourceMode.STRING); this(path, ResourceMode.STRING);
} }
/** /**
* 构造默认UTF-8编码 * 构造默认UTF-8编码
* *
* @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径 * @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径
* @param resourceMode 模板资源加载方式 * @param resourceMode 模板资源加载方式
*/ */
public TemplateConfig(String path, ResourceMode resourceMode) { public TemplateConfig(String path, ResourceMode resourceMode) {
@@ -49,9 +62,9 @@ public class TemplateConfig implements Serializable {
/** /**
* 构造 * 构造
* *
* @param charset 编码 * @param charset 编码
* @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径 * @param path 模板路径如果ClassPath或者WebRoot模式则表示相对路径
* @param resourceMode 模板资源加载方式 * @param resourceMode 模板资源加载方式
*/ */
public TemplateConfig(Charset charset, String path, ResourceMode resourceMode) { public TemplateConfig(Charset charset, String path, ResourceMode resourceMode) {
@@ -62,21 +75,21 @@ public class TemplateConfig implements Serializable {
/** /**
* 获取编码 * 获取编码
* *
* @return 编码 * @return 编码
*/ */
public Charset getCharset() { public Charset getCharset() {
return charset; return charset;
} }
/** /**
* 获取编码 * 获取编码
* *
* @return 编码 * @return 编码
* @since 4.1.11 * @since 4.1.11
*/ */
public String getCharsetStr() { public String getCharsetStr() {
if(null == this.charset) { if (null == this.charset) {
return null; return null;
} }
return this.charset.toString(); return this.charset.toString();
@@ -84,7 +97,7 @@ public class TemplateConfig implements Serializable {
/** /**
* 设置编码 * 设置编码
* *
* @param charset 编码 * @param charset 编码
*/ */
public void setCharset(Charset charset) { public void setCharset(Charset charset) {
@@ -93,7 +106,7 @@ public class TemplateConfig implements Serializable {
/** /**
* 获取模板路径如果ClassPath或者WebRoot模式则表示相对路径 * 获取模板路径如果ClassPath或者WebRoot模式则表示相对路径
* *
* @return 模板路径 * @return 模板路径
*/ */
public String getPath() { public String getPath() {
@@ -102,7 +115,7 @@ public class TemplateConfig implements Serializable {
/** /**
* 设置模板路径如果ClassPath或者WebRoot模式则表示相对路径 * 设置模板路径如果ClassPath或者WebRoot模式则表示相对路径
* *
* @param path 模板路径 * @param path 模板路径
*/ */
public void setPath(String path) { public void setPath(String path) {
@@ -111,7 +124,7 @@ public class TemplateConfig implements Serializable {
/** /**
* 获取模板资源加载方式 * 获取模板资源加载方式
* *
* @return 模板资源加载方式 * @return 模板资源加载方式
*/ */
public ResourceMode getResourceMode() { public ResourceMode getResourceMode() {
@@ -120,67 +133,81 @@ public class TemplateConfig implements Serializable {
/** /**
* 设置模板资源加载方式 * 设置模板资源加载方式
* *
* @param resourceMode 模板资源加载方式 * @param resourceMode 模板资源加载方式
*/ */
public void setResourceMode(ResourceMode resourceMode) { public void setResourceMode(ResourceMode resourceMode) {
this.resourceMode = resourceMode; this.resourceMode = resourceMode;
} }
/**
* 获取自定义引擎null表示系统自动判断
*
* @return 自定义引擎null表示系统自动判断
* @since 5.2.1
*/
public Class<? extends TemplateEngine> getCustomEngine() {
return customEngine;
}
/**
* 设置自定义引擎null表示系统自动判断
*
* @param customEngine 自定义引擎null表示系统自动判断
* @return this
* @since 5.2.1
*/
public TemplateConfig setCustomEngine(Class<? extends TemplateEngine> customEngine) {
this.customEngine = customEngine;
return this;
}
/** /**
* 资源加载方式枚举 * 资源加载方式枚举
* *
* @author looly * @author looly
*/ */
public enum ResourceMode { public enum ResourceMode {
/** 从ClassPath加载模板 */ /**
* 从ClassPath加载模板
*/
CLASSPATH, CLASSPATH,
/** 从File目录加载模板 */ /**
* 从File目录加载模板
*/
FILE, FILE,
/** 从WebRoot目录加载模板 */ /**
* 从WebRoot目录加载模板
*/
WEB_ROOT, WEB_ROOT,
/** 从模板文本加载模板 */ /**
* 从模板文本加载模板
*/
STRING, STRING,
/** 复合加载模板分别从File、ClassPath、Web-root、String方式尝试查找模板 */ /**
* 复合加载模板分别从File、ClassPath、Web-root、String方式尝试查找模板
*/
COMPOSITE COMPOSITE
} }
@Override @Override
public int hashCode() { public boolean equals(Object o) {
final int prime = 31; if (this == o){
int result = 1; return true;
result = prime * result + ((charset == null) ? 0 : charset.hashCode()); }
result = prime * result + ((path == null) ? 0 : path.hashCode()); if (o == null || getClass() != o.getClass()){
result = prime * result + ((resourceMode == null) ? 0 : resourceMode.hashCode()); return false;
return result; }
TemplateConfig that = (TemplateConfig) o;
return Objects.equals(charset, that.charset) &&
Objects.equals(path, that.path) &&
resourceMode == that.resourceMode &&
Objects.equals(customEngine, that.customEngine);
} }
@Override @Override
public boolean equals(Object obj) { public int hashCode() {
if (this == obj) { return Objects.hash(charset, path, resourceMode, customEngine);
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TemplateConfig other = (TemplateConfig) obj;
if (charset == null) {
if (other.charset != null) {
return false;
}
} else if (!charset.equals(other.charset)) {
return false;
}
if (path == null) {
if (other.path != null) {
return false;
}
} else if (!path.equals(other.path)) {
return false;
}
return resourceMode == other.resourceMode;
} }
} }

View File

@@ -2,17 +2,25 @@ package cn.hutool.extra.template;
/** /**
* 引擎接口,通过实现此接口从而使用对应的模板引擎 * 引擎接口,通过实现此接口从而使用对应的模板引擎
* *
* @author looly * @author looly
*/ */
public interface TemplateEngine { public interface TemplateEngine {
/**
* 使用指定配置文件初始化模板引擎
*
* @param config 配置文件
* @return this
*/
TemplateEngine init(TemplateConfig config);
/** /**
* 获取模板 * 获取模板
* *
* @param resource 资源,根据实现不同,此资源可以是模板本身,也可以是模板的相对路径 * @param resource 资源,根据实现不同,此资源可以是模板本身,也可以是模板的相对路径
* @return 模板实现 * @return 模板实现
*/ */
Template getTemplate(String resource); Template getTemplate(String resource);
} }

View File

@@ -1,5 +1,6 @@
package cn.hutool.extra.template.engine; package cn.hutool.extra.template.engine;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.ServiceLoaderUtil; import cn.hutool.core.util.ServiceLoaderUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateConfig;
@@ -35,9 +36,15 @@ public class TemplateFactory {
* @return {@link Engine} * @return {@link Engine}
*/ */
private static TemplateEngine doCreate(TemplateConfig config) { private static TemplateEngine doCreate(TemplateConfig config) {
final TemplateEngine engine = ServiceLoaderUtil.loadFirstAvailable(TemplateEngine.class); final Class<? extends TemplateEngine> customEngineClass = config.getCustomEngine();
final TemplateEngine engine;
if(null != customEngineClass){
engine = ReflectUtil.newInstance(customEngineClass);
}else{
engine = ServiceLoaderUtil.loadFirstAvailable(TemplateEngine.class);
}
if(null != engine){ if(null != engine){
return engine; return engine.init(config);
} }
throw new TemplateException("No template found ! Please add one of template jar to your project !"); throw new TemplateException("No template found ! Please add one of template jar to your project !");

View File

@@ -23,15 +23,13 @@ import cn.hutool.extra.template.TemplateEngine;
*/ */
public class BeetlEngine implements TemplateEngine { public class BeetlEngine implements TemplateEngine {
private final GroupTemplate engine; private GroupTemplate engine;
// --------------------------------------------------------------------------------- Constructor start // --------------------------------------------------------------------------------- Constructor start
/** /**
* 默认构造 * 默认构造
*/ */
public BeetlEngine() { public BeetlEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -39,7 +37,7 @@ public class BeetlEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public BeetlEngine(TemplateConfig config) { public BeetlEngine(TemplateConfig config) {
this(createEngine(config)); init(config);
} }
/** /**
@@ -48,12 +46,30 @@ public class BeetlEngine implements TemplateEngine {
* @param engine {@link GroupTemplate} * @param engine {@link GroupTemplate}
*/ */
public BeetlEngine(GroupTemplate engine) { public BeetlEngine(GroupTemplate engine) {
this.engine = engine; init(engine);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
init(createEngine(config));
return this;
}
/**
* 初始化引擎
* @param engine 引擎
*/
private void init(GroupTemplate engine){
this.engine = engine;
}
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
if(null == this.engine){
init(TemplateConfig.DEFAULT);
}
return BeetlTemplate.wrap(engine.getTemplate(resource)); return BeetlTemplate.wrap(engine.getTemplate(resource));
} }
@@ -65,7 +81,7 @@ public class BeetlEngine implements TemplateEngine {
*/ */
private static GroupTemplate createEngine(TemplateConfig config) { private static GroupTemplate createEngine(TemplateConfig config) {
if (null == config) { if (null == config) {
config = new TemplateConfig(); config = TemplateConfig.DEFAULT;
} }
switch (config.getResourceMode()) { switch (config.getResourceMode()) {

View File

@@ -1,17 +1,14 @@
package cn.hutool.extra.template.engine.enjoy; package cn.hutool.extra.template.engine.enjoy;
import org.beetl.core.GroupTemplate;
import com.jfinal.template.source.FileSourceFactory;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.template.Template; import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig; import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateConfig.ResourceMode; import cn.hutool.extra.template.TemplateConfig.ResourceMode;
import cn.hutool.extra.template.TemplateEngine; import cn.hutool.extra.template.TemplateEngine;
import com.jfinal.template.source.FileSourceFactory;
import org.beetl.core.GroupTemplate;
/** /**
* Enjoy库的引擎包装 * Enjoy库的引擎包装
@@ -29,9 +26,7 @@ public class EnjoyEngine implements TemplateEngine {
/** /**
* 默认构造 * 默认构造
*/ */
public EnjoyEngine() { public EnjoyEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -39,8 +34,7 @@ public class EnjoyEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public EnjoyEngine(TemplateConfig config) { public EnjoyEngine(TemplateConfig config) {
this(createEngine(config)); init(config);
this.resourceMode = config.getResourceMode();
} }
/** /**
@@ -49,12 +43,33 @@ public class EnjoyEngine implements TemplateEngine {
* @param engine {@link com.jfinal.template.Engine} * @param engine {@link com.jfinal.template.Engine}
*/ */
public EnjoyEngine(com.jfinal.template.Engine engine) { public EnjoyEngine(com.jfinal.template.Engine engine) {
this.engine = engine; init(engine);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
if(null == config){
config = TemplateConfig.DEFAULT;
}
this.resourceMode = config.getResourceMode();
init(createEngine(config));
return this;
}
/**
* 初始化引擎
* @param engine 引擎
*/
private void init(com.jfinal.template.Engine engine){
this.engine = engine;
}
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
if(null == this.engine){
init(TemplateConfig.DEFAULT);
}
if (ObjectUtil.equal(ResourceMode.STRING, this.resourceMode)) { if (ObjectUtil.equal(ResourceMode.STRING, this.resourceMode)) {
return EnjoyTemplate.wrap(this.engine.getTemplateByString(resource)); return EnjoyTemplate.wrap(this.engine.getTemplateByString(resource));
} }
@@ -68,7 +83,6 @@ public class EnjoyEngine implements TemplateEngine {
* @return {@link GroupTemplate} * @return {@link GroupTemplate}
*/ */
private static com.jfinal.template.Engine createEngine(TemplateConfig config) { private static com.jfinal.template.Engine createEngine(TemplateConfig config) {
Assert.notNull(config, "Template config is null !");
final com.jfinal.template.Engine engine = com.jfinal.template.Engine.create("Hutool-Enjoy-Engine-" + IdUtil.fastSimpleUUID()); final com.jfinal.template.Engine engine = com.jfinal.template.Engine.create("Hutool-Enjoy-Engine-" + IdUtil.fastSimpleUUID());
engine.setEncoding(config.getCharsetStr()); engine.setEncoding(config.getCharsetStr());

View File

@@ -26,9 +26,7 @@ public class FreemarkerEngine implements TemplateEngine {
/** /**
* 默认构造 * 默认构造
*/ */
public FreemarkerEngine() { public FreemarkerEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -36,7 +34,7 @@ public class FreemarkerEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public FreemarkerEngine(TemplateConfig config) { public FreemarkerEngine(TemplateConfig config) {
this(createCfg(config)); init(config);
} }
/** /**
@@ -45,12 +43,32 @@ public class FreemarkerEngine implements TemplateEngine {
* @param freemarkerCfg {@link Configuration} * @param freemarkerCfg {@link Configuration}
*/ */
public FreemarkerEngine(Configuration freemarkerCfg) { public FreemarkerEngine(Configuration freemarkerCfg) {
this.cfg = freemarkerCfg; init(freemarkerCfg);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
if(null == config){
config = TemplateConfig.DEFAULT;
}
init(createCfg(config));
return this;
}
/**
* 初始化引擎
* @param freemarkerCfg Configuration
*/
private void init(Configuration freemarkerCfg){
this.cfg = freemarkerCfg;
}
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
if(null == this.cfg){
init(TemplateConfig.DEFAULT);
}
try { try {
return FreemarkerTemplate.wrap(this.cfg.getTemplate(resource)); return FreemarkerTemplate.wrap(this.cfg.getTemplate(resource));
} catch(IOException e) { } catch(IOException e) {

View File

@@ -21,9 +21,7 @@ public class RythmEngine implements TemplateEngine {
/** /**
* 默认构造 * 默认构造
*/ */
public RythmEngine() { public RythmEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -31,7 +29,7 @@ public class RythmEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public RythmEngine(TemplateConfig config) { public RythmEngine(TemplateConfig config) {
this(createEngine(config)); init(config);
} }
/** /**
@@ -40,13 +38,33 @@ public class RythmEngine implements TemplateEngine {
* @param engine {@link org.rythmengine.RythmEngine} * @param engine {@link org.rythmengine.RythmEngine}
*/ */
public RythmEngine(org.rythmengine.RythmEngine engine) { public RythmEngine(org.rythmengine.RythmEngine engine) {
this.engine = engine; init(engine);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
if(null == config){
config = TemplateConfig.DEFAULT;
}
init(createEngine(config));
return this;
}
/**
* 初始化引擎
* @param engine 引擎
*/
private void init(org.rythmengine.RythmEngine engine){
this.engine = engine;
}
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
return RythmTemplate.wrap(engine.getTemplate(resource)); if(null == this.engine){
init(TemplateConfig.DEFAULT);
}
return RythmTemplate.wrap(this.engine.getTemplate(resource));
} }
/** /**

View File

@@ -28,9 +28,7 @@ public class ThymeleafEngine implements TemplateEngine {
/** /**
* 默认构造 * 默认构造
*/ */
public ThymeleafEngine() { public ThymeleafEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -38,8 +36,7 @@ public class ThymeleafEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public ThymeleafEngine(TemplateConfig config) { public ThymeleafEngine(TemplateConfig config) {
this(createEngine(config)); init(config);
this.config = config;
} }
/** /**
@@ -48,12 +45,33 @@ public class ThymeleafEngine implements TemplateEngine {
* @param engine {@link org.thymeleaf.TemplateEngine} * @param engine {@link org.thymeleaf.TemplateEngine}
*/ */
public ThymeleafEngine(org.thymeleaf.TemplateEngine engine) { public ThymeleafEngine(org.thymeleaf.TemplateEngine engine) {
this.engine = engine; init(engine);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
if(null == config){
config = TemplateConfig.DEFAULT;
}
this.config = config;
init(createEngine(config));
return this;
}
/**
* 初始化引擎
* @param engine 引擎
*/
private void init(org.thymeleaf.TemplateEngine engine){
this.engine = engine;
}
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
if(null == this.engine){
init(TemplateConfig.DEFAULT);
}
return ThymeleafTemplate.wrap(this.engine, resource, (null == this.config) ? null : this.config.getCharset()); return ThymeleafTemplate.wrap(this.engine, resource, (null == this.config) ? null : this.config.getCharset());
} }

View File

@@ -21,9 +21,7 @@ public class VelocityEngine implements TemplateEngine {
/** /**
* 默认构造 * 默认构造
*/ */
public VelocityEngine() { public VelocityEngine() {}
this(new TemplateConfig());
}
/** /**
* 构造 * 构造
@@ -31,7 +29,7 @@ public class VelocityEngine implements TemplateEngine {
* @param config 模板配置 * @param config 模板配置
*/ */
public VelocityEngine(TemplateConfig config) { public VelocityEngine(TemplateConfig config) {
this(createEngine(config)); init(config);
} }
/** /**
@@ -40,10 +38,27 @@ public class VelocityEngine implements TemplateEngine {
* @param engine {@link org.apache.velocity.app.VelocityEngine} * @param engine {@link org.apache.velocity.app.VelocityEngine}
*/ */
public VelocityEngine(org.apache.velocity.app.VelocityEngine engine) { public VelocityEngine(org.apache.velocity.app.VelocityEngine engine) {
this.engine = engine; init(engine);
} }
// --------------------------------------------------------------------------------- Constructor end // --------------------------------------------------------------------------------- Constructor end
@Override
public TemplateEngine init(TemplateConfig config) {
if(null == config){
config = TemplateConfig.DEFAULT;
}
init(createEngine(config));
return this;
}
/**
* 初始化引擎
* @param engine 引擎
*/
private void init(org.apache.velocity.app.VelocityEngine engine){
this.engine = engine;
}
/** /**
* 获取原始的引擎对象 * 获取原始的引擎对象
* *
@@ -56,6 +71,9 @@ public class VelocityEngine implements TemplateEngine {
@Override @Override
public Template getTemplate(String resource) { public Template getTemplate(String resource) {
if(null == this.engine){
init(TemplateConfig.DEFAULT);
}
return VelocityTemplate.wrap(engine.getTemplate(resource)); return VelocityTemplate.wrap(engine.getTemplate(resource));
} }

View File

@@ -27,11 +27,17 @@ public class TemplateUtilTest {
@Test @Test
public void createEngineTest() { public void createEngineTest() {
// 默认模板引擎此处为Beetl // 字符串模板, 默认模板引擎此处为Beetl
TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig()); TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig());
Template template = engine.getTemplate("hello,${name}"); Template template = engine.getTemplate("hello,${name}");
String result = template.render(Dict.create().set("name", "hutool")); String result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("hello,hutool", result); Assert.assertEquals("hello,hutool", result);
// classpath中获取模板
engine = TemplateUtil.createEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH));
Template template2 = engine.getTemplate("beetl_test.btl");
String result2 = template2.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("hello,hutool", result2);
} }
@Test @Test
@@ -52,7 +58,8 @@ public class TemplateUtilTest {
@Test @Test
public void rythmEngineTest() { public void rythmEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = new RythmEngine(new TemplateConfig("templates")); TemplateEngine engine = TemplateUtil.createEngine(
new TemplateConfig("templates").setCustomEngine(RythmEngine.class));
Template template = engine.getTemplate("hello,@name"); Template template = engine.getTemplate("hello,@name");
String result = template.render(Dict.create().set("name", "hutool")); String result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("hello,hutool", result); Assert.assertEquals("hello,hutool", result);
@@ -66,13 +73,15 @@ public class TemplateUtilTest {
@Test @Test
public void freemarkerEngineTest() { public void freemarkerEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = new FreemarkerEngine(new TemplateConfig("templates", ResourceMode.STRING)); TemplateEngine engine = TemplateUtil.createEngine(
new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(FreemarkerEngine.class));
Template template = engine.getTemplate("hello,${name}"); Template template = engine.getTemplate("hello,${name}");
String result = template.render(Dict.create().set("name", "hutool")); String result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("hello,hutool", result); Assert.assertEquals("hello,hutool", result);
//ClassPath模板 //ClassPath模板
engine = new FreemarkerEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH)); engine = TemplateUtil.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(FreemarkerEngine.class));
template = engine.getTemplate("freemarker_test.ftl"); template = engine.getTemplate("freemarker_test.ftl");
result = template.render(Dict.create().set("name", "hutool")); result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("hello,hutool", result); Assert.assertEquals("hello,hutool", result);
@@ -81,13 +90,15 @@ public class TemplateUtilTest {
@Test @Test
public void velocityEngineTest() { public void velocityEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = new VelocityEngine(new TemplateConfig("templates", ResourceMode.STRING)); TemplateEngine engine = TemplateUtil.createEngine(
new TemplateConfig("templates", ResourceMode.STRING).setCustomEngine(VelocityEngine.class));
Template template = engine.getTemplate("你好,$name"); Template template = engine.getTemplate("你好,$name");
String result = template.render(Dict.create().set("name", "hutool")); String result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("你好,hutool", result); Assert.assertEquals("你好,hutool", result);
//ClassPath模板 //ClassPath模板
engine = new VelocityEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH)); engine = TemplateUtil.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(VelocityEngine.class));
template = engine.getTemplate("templates/velocity_test.vtl"); template = engine.getTemplate("templates/velocity_test.vtl");
result = template.render(Dict.create().set("name", "hutool")); result = template.render(Dict.create().set("name", "hutool"));
Assert.assertEquals("你好,hutool", result); Assert.assertEquals("你好,hutool", result);
@@ -97,13 +108,15 @@ public class TemplateUtilTest {
@Test @Test
public void enjoyEngineTest() { public void enjoyEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = new EnjoyEngine(new TemplateConfig("templates")); TemplateEngine engine = TemplateUtil.createEngine(
new TemplateConfig("templates").setCustomEngine(EnjoyEngine.class));
Template template = engine.getTemplate("#(x + 123)"); Template template = engine.getTemplate("#(x + 123)");
String result = template.render(Dict.create().set("x", 1)); String result = template.render(Dict.create().set("x", 1));
Assert.assertEquals("124", result); Assert.assertEquals("124", result);
//ClassPath模板 //ClassPath模板
engine = new EnjoyEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH)); engine = new EnjoyEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(EnjoyEngine.class));
template = engine.getTemplate("enjoy_test.etl"); template = engine.getTemplate("enjoy_test.etl");
result = template.render(Dict.create().set("x", 1)); result = template.render(Dict.create().set("x", 1));
Assert.assertEquals("124", result); Assert.assertEquals("124", result);
@@ -112,13 +125,15 @@ public class TemplateUtilTest {
@Test @Test
public void thymeleafEngineTest() { public void thymeleafEngineTest() {
// 字符串模板 // 字符串模板
TemplateEngine engine = new ThymeleafEngine(new TemplateConfig("templates")); TemplateEngine engine = TemplateUtil.createEngine(
new TemplateConfig("templates").setCustomEngine(ThymeleafEngine.class));
Template template = engine.getTemplate("<h3 th:text=\"${message}\"></h3>"); Template template = engine.getTemplate("<h3 th:text=\"${message}\"></h3>");
String result = template.render(Dict.create().set("message", "Hutool")); String result = template.render(Dict.create().set("message", "Hutool"));
Assert.assertEquals("<h3>Hutool</h3>", result); Assert.assertEquals("<h3>Hutool</h3>", result);
//ClassPath模板 //ClassPath模板
engine = new ThymeleafEngine(new TemplateConfig("templates", ResourceMode.CLASSPATH)); engine = TemplateUtil.createEngine(
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(ThymeleafEngine.class));
template = engine.getTemplate("thymeleaf_test.ttl"); template = engine.getTemplate("thymeleaf_test.ttl");
result = template.render(Dict.create().set("message", "Hutool")); result = template.render(Dict.create().set("message", "Hutool"));
Assert.assertEquals("<h3>Hutool</h3>", result); Assert.assertEquals("<h3>Hutool</h3>", result);