From 22b04c0ca72d50255716e4e7ef2f368fd2008f65 Mon Sep 17 00:00:00 2001 From: mymx2 <1818106+mymx2@user.noreply.gitee.com> Date: Thu, 11 Apr 2024 15:31:03 +0000 Subject: [PATCH] =?UTF-8?q?!1202=20=E5=A2=9E=E5=8A=A0jte=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=BC=95=E6=93=8E=20*=20feat(jte):=20add=20jte:=20Java=20Templ?= =?UTF-8?q?ate=20Engine=20*=20feat(jte):=20add=20jte:=20Java=20Template=20?= =?UTF-8?q?Engine=20*=20feat(jte):=20add=20jte:=20Java=20Template=20Engine?= =?UTF-8?q?=20*=20feat(jte):=20add=20jte:=20Java=20Template=20Engine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + hutool-extra/pom.xml | 8 ++ .../extra/template/engine/jte/JteEngine.java | 122 ++++++++++++++++++ .../template/engine/jte/JteTemplate.java | 99 ++++++++++++++ .../engine/jte/SimpleStringCodeResolver.java | 39 ++++++ .../template/engine/jte/package-info.java | 19 +++ .../extra/template/TemplateFactoryTest.java | 24 +++- .../src/test/resources/templates/jte_test.jte | 2 + 8 files changed, 312 insertions(+), 2 deletions(-) create mode 100644 hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteEngine.java create mode 100644 hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteTemplate.java create mode 100644 hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/SimpleStringCodeResolver.java create mode 100644 hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/package-info.java create mode 100644 hutool-extra/src/test/resources/templates/jte_test.jte diff --git a/.gitignore b/.gitignore index 2a93184c8..d90ef8d15 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ build/ # system ignore .DS_Store Thumbs.db +jte-classes/ diff --git a/hutool-extra/pom.xml b/hutool-extra/pom.xml index 4d48008f9..ae520360c 100755 --- a/hutool-extra/pom.xml +++ b/hutool-extra/pom.xml @@ -37,6 +37,7 @@ 2.3.32 5.1.3 3.1.2.RELEASE + 3.1.9 1.6.2 0.1.55 0.38.0 @@ -144,6 +145,13 @@ true + + gg.jte + jte + ${jte.version} + compile + true + org.febit.wit wit-core diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteEngine.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteEngine.java new file mode 100644 index 000000000..ad7f4a702 --- /dev/null +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteEngine.java @@ -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实现
+ * 见:https://jte.gg/ + * + * @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); + } +} diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteTemplate.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteTemplate.java new file mode 100644 index 000000000..cb250a494 --- /dev/null +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/JteTemplate.java @@ -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(); + } +} diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/SimpleStringCodeResolver.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/SimpleStringCodeResolver.java new file mode 100644 index 000000000..b9a6b9563 --- /dev/null +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/SimpleStringCodeResolver.java @@ -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} 字符串实现形式
+ * 用于直接获取字符串模板 + * + * @author cdy + * @since 6.0.0 + */ +public class SimpleStringCodeResolver implements CodeResolver { + + private final Map templates; + + public SimpleStringCodeResolver(Map 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 resolveAllTemplateNames() { + return new ArrayList<>(templates.keySet()); + } + +} diff --git a/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/package-info.java b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/package-info.java new file mode 100644 index 000000000..3581ff77a --- /dev/null +++ b/hutool-extra/src/main/java/org/dromara/hutool/extra/template/engine/jte/package-info.java @@ -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实现
+ * 见:https://jte.gg/ + * + * @author dy + */ +package org.dromara.hutool.extra.template.engine.jte; diff --git a/hutool-extra/src/test/java/org/dromara/hutool/extra/template/TemplateFactoryTest.java b/hutool-extra/src/test/java/org/dromara/hutool/extra/template/TemplateFactoryTest.java index f97111dfb..dbfb09ffb 100644 --- a/hutool-extra/src/test/java/org/dromara/hutool/extra/template/TemplateFactoryTest.java +++ b/hutool-extra/src/test/java/org/dromara/hutool/extra/template/TemplateFactoryTest.java @@ -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("

Hutool

", result); } + @Test + public void jteEngineTest() { + // 字符串模板 + TemplateEngine engine = TemplateEngineFactory.createEngine( + new TemplateConfig("templates.jte").setCustomEngine(JteEngine.class)); + Template template = engine.getTemplate("@param java.util.HashMap map\n" + + "

${map.get(\"message\")}

"); + Map model = new HashMap<>(); + model.put("message", "Hutool"); + String result = template.render(model); + Assertions.assertEquals("

Hutool

", 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("

Hutool

", result); + } + /** * pebble template engine test */ diff --git a/hutool-extra/src/test/resources/templates/jte_test.jte b/hutool-extra/src/test/resources/templates/jte_test.jte new file mode 100644 index 000000000..2538b6ec0 --- /dev/null +++ b/hutool-extra/src/test/resources/templates/jte_test.jte @@ -0,0 +1,2 @@ +@param java.util.HashMap map +

${map.get("message")}

\ No newline at end of file