com.gitee.qdbp.staticize.publish.TemplateTools Maven / Gradle / Ivy
package com.gitee.qdbp.staticize.publish;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import com.gitee.qdbp.able.exception.ServiceException;
import com.gitee.qdbp.able.i18n.LocaleTools;
import com.gitee.qdbp.able.result.IResultMessage;
import com.gitee.qdbp.staticize.common.IMetaData;
import com.gitee.qdbp.staticize.exception.TagException;
import com.gitee.qdbp.staticize.exception.TemplateException;
import com.gitee.qdbp.staticize.io.IReaderCreator;
import com.gitee.qdbp.staticize.io.StreamWriter;
import com.gitee.qdbp.staticize.io.TemporaryReaderCreator;
import com.gitee.qdbp.staticize.io.UrlReaderCreator;
import com.gitee.qdbp.staticize.parse.TagParser;
import com.gitee.qdbp.staticize.tags.base.Taglib;
import com.gitee.qdbp.tools.files.PathTools;
/**
* 模板工具类
*
* @author zhaohuihua
* @version 20210421
*/
public class TemplateTools {
/** 全局JSTL实例 **/
private static TemplateTools JSTL;
/** 获取全局JSTL实例 **/
public static TemplateTools jstl() {
if (JSTL == null) {
JSTL = JstlInstance.INSTANCE;
}
return JSTL;
}
/** 全局默认实例 **/
private static TemplateTools DEFAULTS;
/** 获取全局默认实例 **/
public static TemplateTools defaults() {
if (DEFAULTS == null) {
DEFAULTS = DefaultInstance.INSTANCE;
}
return DEFAULTS;
}
/**
* 静态内部类单例模式, 同时解决延迟加载和并发问题(缺点是无法传参)
* 加载外部类时, 不会加载内部类, 也就不会创建实例对象;
* 只有DEFAULTS==null调用DefaultInstance.INSTANCE时才会加载静态内部类;
* 加载类是线程安全的, 虚拟机保证只会装载一次内部类, 不会出现并发问题
*
* @author zhaohuihua
* @version 20210421
*/
public static class DefaultInstance {
public static final TemplateTools INSTANCE = new TemplateTools(Taglib.defaults());
}
/**
* 静态内部类单例模式, 同时解决延迟加载和并发问题(缺点是无法传参)
* 加载外部类时, 不会加载内部类, 也就不会创建实例对象;
* 只有JSTL==null调用JstlInstance.INSTANCE时才会加载静态内部类;
* 加载类是线程安全的, 虚拟机保证只会装载一次内部类, 不会出现并发问题
*
* @author zhaohuihua
* @version 20210421
*/
public static class JstlInstance {
public static final TemplateTools INSTANCE = new TemplateTools(Taglib.jstl());
}
/** 标签库 **/
private final Taglib taglib;
/** 模板读取接口 **/
private final IReaderCreator input;
/** 标签解析的选项 **/
private final TagParser.Options options;
private TemplateTools(Taglib taglib) {
this(taglib, new UrlReaderCreator(), newDefaultOptions());
}
public TemplateTools(String taglibPath) {
this(new Taglib(taglibPath), new UrlReaderCreator(), newDefaultOptions());
}
public TemplateTools(String taglibPath, TagParser.Options options) {
this(new Taglib(taglibPath), new UrlReaderCreator(), options);
}
public TemplateTools(Taglib taglib, IReaderCreator input) {
this(taglib, input, newDefaultOptions());
}
public TemplateTools(Taglib taglib, TagParser.Options options) {
this(taglib, new UrlReaderCreator(), options);
}
public TemplateTools(Taglib taglib, IReaderCreator input, TagParser.Options options) {
this.taglib = taglib;
this.input = input;
this.options = options;
}
private static TagParser.Options newDefaultOptions() {
return new TagParser.Options().setClearXmlComment(true).setParseJspScript(false);
}
/**
* 根据文件路径获取模板, 并将模板渲染为字符串
*
* @param filePath 文件路径
* @param data 参数
* @return 字符串内容
*/
public String generate(String filePath, Map data) {
URL url = PathTools.findResource(filePath);
return generate(url, data);
}
/**
* 根据文件路径获取模板, 并将模板渲染为字符串
*
* @param url 文件路径
* @param data 参数
* @return 字符串内容
*/
public String generate(URL url, Map data) {
TagParser parser = new TagParser(taglib, input);
IMetaData tags;
try {
tags = parser.parse(url.toString(), options);
} catch (TagException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_PARSE_ERROR, e);
} catch (TemplateException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_PARSE_ERROR, e);
}
return render(tags, data);
}
/** 根据参数渲染模板内容 **/
public String render(String templateContent, Map data) {
return render(templateContent, Taglib.jstl(), data);
}
/** 解析模板内容 **/
public static IMetaData parse(String templateContent) {
return parse(templateContent, Taglib.jstl(), newDefaultOptions());
}
/** 解析模板内容 **/
public static IMetaData parse(String templateContent, Taglib taglib) {
return parse(templateContent, taglib, newDefaultOptions());
}
/** 解析模板内容 **/
public static IMetaData parse(String templateContent, TagParser.Options options) {
return parse(templateContent, Taglib.jstl(), options);
}
/** 解析模板内容 **/
public static IMetaData parse(String templateContent, Taglib taglib, TagParser.Options options) {
TemporaryReaderCreator input = new TemporaryReaderCreator(templateContent);
TagParser parser = new TagParser(taglib, input);
try {
return parser.parse(input.getFilePath(), options);
} catch (TagException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_PARSE_ERROR, e);
} catch (TemplateException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_PARSE_ERROR, e);
}
}
/** 根据参数渲染模板 **/
public static String render(IMetaData tags, Map data) {
OutputPublisher publisher = new OutputPublisher(tags);
try (ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
StreamWriter streamWriter = new StreamWriter(byteArrayOutputStream)) {
publisher.publish(data, streamWriter);
byte[] bytes = byteArrayOutputStream.toByteArray();
return new String(bytes, StandardCharsets.UTF_8);
} catch (TagException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_RENDER_ERROR, e);
} catch (IOException e) {
throw new ServiceException(TmplErrorCode.TEMPLATE_RENDER_ERROR, e);
}
}
/** 根据参数渲染模板 **/
public static String render(String templateContent, Taglib taglib, Map data) {
return render(templateContent, taglib, newDefaultOptions(), data);
}
/** 根据参数渲染模板 **/
public static String render(String templateContent, TagParser.Options options, Map data) {
return render(templateContent, Taglib.jstl(), options, data);
}
/** 根据参数渲染模板 **/
public static String render(String templateContent, Taglib taglib, TagParser.Options options,
Map data) {
IMetaData tags = parse(templateContent, taglib, options);
return render(tags, data);
}
/**
* 模板错误码
*
* @author zhaohuihua
* @version 20210421
*/
private enum TmplErrorCode implements IResultMessage {
/** 模板解析失败 **/
TEMPLATE_PARSE_ERROR,
/** 模板渲染失败 **/
TEMPLATE_RENDER_ERROR;
/** {@inheritDoc} **/
@Override
public String getCode() {
return this.name();
}
/** {@inheritDoc} **/
@Override
public String getMessage() {
return LocaleTools.getMessage(this);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy