mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
!1202 增加jte模板引擎
* feat(jte): add jte: Java Template Engine * feat(jte): add jte: Java Template Engine * feat(jte): add jte: Java Template Engine * feat(jte): add jte: Java Template Engine
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -31,3 +31,4 @@ build/
|
||||
# system ignore
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
jte-classes/
|
||||
|
@@ -37,6 +37,7 @@
|
||||
<freemarker.version>2.3.32</freemarker.version>
|
||||
<enjoy.version>5.1.3</enjoy.version>
|
||||
<thymeleaf.version>3.1.2.RELEASE</thymeleaf.version>
|
||||
<jte.version>3.1.9</jte.version>
|
||||
<mail.version>1.6.2</mail.version>
|
||||
<jsch.version>0.1.55</jsch.version>
|
||||
<sshj.version>0.38.0</sshj.version>
|
||||
@@ -144,6 +145,13 @@
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gg.jte</groupId>
|
||||
<artifactId>jte</artifactId>
|
||||
<version>${jte.version}</version>
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.febit.wit</groupId>
|
||||
<artifactId>wit-core</artifactId>
|
||||
|
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.extra.template.engine.jte;
|
||||
|
||||
import gg.jte.CodeResolver;
|
||||
import gg.jte.ContentType;
|
||||
import gg.jte.resolve.DirectoryCodeResolver;
|
||||
import gg.jte.resolve.ResourceCodeResolver;
|
||||
import org.dromara.hutool.core.map.MapUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.extra.template.Template;
|
||||
import org.dromara.hutool.extra.template.TemplateConfig;
|
||||
import org.dromara.hutool.extra.template.engine.TemplateEngine;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
|
||||
/**
|
||||
* jte实现<br>
|
||||
* 见:<a href="https://jte.gg/">https://jte.gg/</a>
|
||||
*
|
||||
* @author dy
|
||||
*/
|
||||
public class JteEngine implements TemplateEngine {
|
||||
|
||||
private TemplateConfig config = TemplateConfig.DEFAULT;
|
||||
private gg.jte.TemplateEngine engine;
|
||||
private final ContentType contentType = ContentType.Plain;
|
||||
|
||||
// --------------------------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 默认构造
|
||||
*/
|
||||
public JteEngine() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 模板配置
|
||||
*/
|
||||
public JteEngine(final TemplateConfig config) {
|
||||
this.config = config;
|
||||
createEngine();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param codeResolver {@link CodeResolver}
|
||||
*/
|
||||
public JteEngine(final CodeResolver codeResolver) {
|
||||
createEngine(codeResolver, contentType);
|
||||
}
|
||||
// --------------------------------------------------------------------------------- Constructor end
|
||||
|
||||
@Override
|
||||
public TemplateEngine init(TemplateConfig config) {
|
||||
if (config != null) {
|
||||
this.config = config;
|
||||
}
|
||||
createEngine();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Template getTemplate(String resource) {
|
||||
if (TemplateConfig.ResourceMode.STRING.equals(config.getResourceMode())) {
|
||||
if (!StrUtil.endWithAny(config.getPath(), ".jte", ".kte")) {
|
||||
throw new RuntimeException("路径path需以.jte/.kte结尾");
|
||||
}
|
||||
createEngine(new SimpleStringCodeResolver(MapUtil.of(config.getPath(), resource)), contentType);
|
||||
return new JteTemplate(engine, config.getPath());
|
||||
} else {
|
||||
return new JteTemplate(engine, resource);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public gg.jte.TemplateEngine getRaw() {
|
||||
return this.engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建引擎 {@link gg.jte.TemplateEngine }
|
||||
*/
|
||||
private void createEngine() {
|
||||
switch (config.getResourceMode()) {
|
||||
case CLASSPATH:
|
||||
createEngine(new ResourceCodeResolver(config.getPath(), JteEngine.class.getClassLoader()), contentType);
|
||||
break;
|
||||
case FILE:
|
||||
createEngine(new DirectoryCodeResolver(Paths.get(config.getPath())), contentType);
|
||||
break;
|
||||
case STRING:
|
||||
// 这里无法直接创建引擎
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建引擎 {@link gg.jte.TemplateEngine }
|
||||
*
|
||||
* @param codeResolver CodeResolver
|
||||
* @param contentType ContentType
|
||||
*/
|
||||
private void createEngine(CodeResolver codeResolver, ContentType contentType) {
|
||||
this.engine = gg.jte.TemplateEngine.create(codeResolver, contentType);
|
||||
}
|
||||
}
|
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.extra.template.engine.jte;
|
||||
|
||||
import gg.jte.TemplateEngine;
|
||||
import gg.jte.output.WriterOutput;
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.io.file.FileUtil;
|
||||
import org.dromara.hutool.extra.template.Template;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Jte模板实现
|
||||
*
|
||||
* @author dy
|
||||
*/
|
||||
public class JteTemplate implements Template, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -2739915422007257186L;
|
||||
|
||||
private final TemplateEngine templateEngine;
|
||||
private final String template;
|
||||
|
||||
public JteTemplate(TemplateEngine engine, String template) {
|
||||
this.templateEngine = engine;
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Map<?, ?> bindingMap, Writer writer) {
|
||||
templateEngine.render(template, bindingMap, new WriterOutput(writer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(Map<?, ?> bindingMap, OutputStream out) {
|
||||
this.render(bindingMap, IoUtil.toWriter(out, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模板与绑定参数融合后输出到Writer
|
||||
*
|
||||
* @param model 实体类
|
||||
* @param writer 输出
|
||||
*/
|
||||
public void render(Object model, Writer writer) {
|
||||
templateEngine.render(template, model, new WriterOutput(writer));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模板与绑定参数融合后输出到流
|
||||
*
|
||||
* @param model 实体类
|
||||
* @param out 输出
|
||||
*/
|
||||
public void render(Object model, OutputStream out) {
|
||||
render(model, IoUtil.toWriter(out, StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
/**
|
||||
* 写出到文件
|
||||
*
|
||||
* @param model 实体类
|
||||
* @param file 输出到的文件
|
||||
*/
|
||||
public void render(final Object model, final File file) {
|
||||
BufferedOutputStream out = null;
|
||||
try {
|
||||
out = FileUtil.getOutputStream(file);
|
||||
this.render(model, out);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模板与绑定参数融合后返回为字符串
|
||||
*
|
||||
* @param model 实体类
|
||||
* @return 融合后的内容
|
||||
*/
|
||||
public String render(final Object model) {
|
||||
final StringWriter writer = new StringWriter();
|
||||
this.render(model, writer);
|
||||
return writer.toString();
|
||||
}
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package org.dromara.hutool.extra.template.engine.jte;
|
||||
|
||||
import gg.jte.CodeResolver;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* {@link CodeResolver} 字符串实现形式<br>
|
||||
* 用于直接获取字符串模板
|
||||
*
|
||||
* @author cdy
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class SimpleStringCodeResolver implements CodeResolver {
|
||||
|
||||
private final Map<String, String> templates;
|
||||
|
||||
public SimpleStringCodeResolver(Map<String, String> templates) {
|
||||
this.templates = templates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String resolve(String name) {
|
||||
return templates.get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLastModified(String name) {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> resolveAllTemplateNames() {
|
||||
return new ArrayList<>(templates.keySet());
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* jte实现<br>
|
||||
* 见:<a href="https://jte.gg/">https://jte.gg/</a>
|
||||
*
|
||||
* @author dy
|
||||
*/
|
||||
package org.dromara.hutool.extra.template.engine.jte;
|
@@ -20,6 +20,7 @@ import org.dromara.hutool.extra.template.engine.TemplateEngineFactory;
|
||||
import org.dromara.hutool.extra.template.engine.beetl.BeetlEngine;
|
||||
import org.dromara.hutool.extra.template.engine.enjoy.EnjoyEngine;
|
||||
import org.dromara.hutool.extra.template.engine.freemarker.FreemarkerEngine;
|
||||
import org.dromara.hutool.extra.template.engine.jte.JteEngine;
|
||||
import org.dromara.hutool.extra.template.engine.pebble.PebbleTemplateEngine;
|
||||
import org.dromara.hutool.extra.template.engine.rythm.RythmEngine;
|
||||
import org.dromara.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
|
||||
@@ -30,8 +31,7 @@ import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 模板引擎单元测试
|
||||
@@ -158,6 +158,26 @@ public class TemplateFactoryTest {
|
||||
Assertions.assertEquals("<h3>Hutool</h3>", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jteEngineTest() {
|
||||
// 字符串模板
|
||||
TemplateEngine engine = TemplateEngineFactory.createEngine(
|
||||
new TemplateConfig("templates.jte").setCustomEngine(JteEngine.class));
|
||||
Template template = engine.getTemplate("@param java.util.HashMap<String, String> map\n" +
|
||||
"<h3>${map.get(\"message\")}</h3>");
|
||||
Map<String, String> model = new HashMap<>();
|
||||
model.put("message", "Hutool");
|
||||
String result = template.render(model);
|
||||
Assertions.assertEquals("<h3>Hutool</h3>", result);
|
||||
|
||||
//ClassPath模板
|
||||
engine = TemplateEngineFactory.createEngine(
|
||||
new TemplateConfig("templates", ResourceMode.CLASSPATH).setCustomEngine(JteEngine.class));
|
||||
template = engine.getTemplate("jte_test.jte");
|
||||
result = template.render(model);
|
||||
Assertions.assertEquals("<h3>Hutool</h3>", result);
|
||||
}
|
||||
|
||||
/**
|
||||
* pebble template engine test
|
||||
*/
|
||||
|
2
hutool-extra/src/test/resources/templates/jte_test.jte
Normal file
2
hutool-extra/src/test/resources/templates/jte_test.jte
Normal file
@@ -0,0 +1,2 @@
|
||||
@param java.util.HashMap<String, String> map
|
||||
<h3>${map.get("message")}</h3>
|
Reference in New Issue
Block a user