org.beetl.core.Configuration Maven / Gradle / Ivy
The newest version!
/*
[The "BSD license"]
Copyright (c) 2011-2024 闲大赋 (李家智)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.beetl.core;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
import org.beetl.core.util.TextUtils;
import org.beetl.core.text.HtmlTagConfig;
import org.beetl.core.text.PlaceHolderDelimeter;
import org.beetl.core.text.ScriptDelimeter;
import org.intellij.lang.annotations.MagicConstant;
import org.jetbrains.annotations.NotNull;
/**
* 模板配置,核心文件之一
*
* @author xiandafu
*/
public class Configuration {
/** 模板字符集 */
String charset = "UTF-8";
/** 模板占位起始符号 */
String placeholderStart = "${";
/** 模板占位结束符号 */
String placeholderEnd = "}";
String placeholderStart2 = null;
/** 模板占位结束符号 */
String placeholderEnd2 = null;
/** 控制语句起始符号 */
String statementStart = "<%";
/** 控制语句结束符号 */
String statementEnd = "%>";
/** 控制语句起始符号 */
String statementStart2 = null;
/** 控制语句结束符号 */
String statementEnd2 = null;
/** html tag 标示符号 */
String htmlTagFlag = "#";
/** 是否允许html tag,在web编程中,有可能用到html tag,最好允许 */
boolean isHtmlTagSupport = false;
/** HTML标签开始符号 */
String htmlTagStart;
/** HTML标签结束符号 */
String htmlTagEnd;
/** 是否允许直接调用class */
boolean nativeCall = false;
/** 输出模式,默认是字符集输出,改成byte输出提高性能 */
boolean directByteOutput = false;
/** 严格mvc应用,只有变态的的人才打开此选项 */
boolean isStrict = false;
/** 是否忽略客户端的网络异常 */
boolean isIgnoreClientIOError = true;
/** 错误处理类 */
String errorHandlerClass = "org.beetl.core.ConsoleErrorHandler";
/** html 绑定的属性,如<aa var="customer"> */
String htmlTagBindingAttribute = "var";
/** {@link org.beetl.core.text.DefaultAttributeNameConvert} */
String htmlTagAttributeConvert = "org.beetl.core.text.DefaultAttributeNameConvert";
/** 类搜索的包名列表 */
Set pkgList = new HashSet<>();
/** 渲染web 前执行的代码,需要实现WebRenderExt接口,如果为空,则不做操作 */
String webAppExt = null;
/** html方法和html标签是否使用特殊的定界符,如模板使用简介的@和回车,html 标签和html tag使用<%%> */
boolean hasFunctionLimiter = false;
String functionLimiterStart = null;
String functionLimiterEnd = null;
// 关于引擎的设置
/** {@code String engine = "org.beetl.core.DefaultTemplateEngine";} */
String engine = "org.beetl.core.FastRuntimeEngine";
String nativeSecurity = "org.beetl.core.DefaultNativeSecurityManager";
String resourceLoader = "org.beetl.core.resource.ClasspathResourceLoader";
// 扩展资源
Map fnMap = new HashMap<>();
Map fnPkgMap = new HashMap<>();
Map formatMap = new HashMap<>();
Map defaultFormatMap = new HashMap<>(0);
Set generalVirtualAttributeSet = new HashSet<>();
Map virtualClass = new HashMap<>();
Map tagFactoryMap = new HashMap<>();
Map tagMap = new HashMap<>();
/** 资源loader配置 */
Map resourceMap = new HashMap<>();
/** 缓冲数组长度不能小于 256 */
private static final int BUFFER_MIN_SIZE = 256;
/** 缓冲数组 */
int bufferSize = 4096;
int bufferNum = 64;
int cacheOutPutBuffer = 0;
boolean isBigDecimal = false;
/** 模板是否整体使用安全输出功能,如果是,则不存在的值返回空,而不是报错 */
boolean safeOutput = false;
/** 使用类来动态决定定界符,而不是通过配置『DELIMITER_PLACEHOLDER_START』*/
String delimeterClass = null;
/*保存模板编译结果的缓存*/
String cacheClass = "org.beetl.core.impl.cache.DefaultBeetlCache";
public static final String DELIMITER_PLACEHOLDER_START = "DELIMITER_PLACEHOLDER_START";
public static final String DELIMITER_PLACEHOLDER_END = "DELIMITER_PLACEHOLDER_END";
public static final String DELIMITER_STATEMENT_START = "DELIMITER_STATEMENT_START";
public static final String DELIMITER_STATEMENT_END = "DELIMITER_STATEMENT_END";
public static final String DELIMITER_PLACEHOLDER_START2 = "DELIMITER_PLACEHOLDER_START2";
public static final String DELIMITER_PLACEHOLDER_END2 = "DELIMITER_PLACEHOLDER_END2";
public static final String DELIMITER_STATEMENT_START2 = "DELIMITER_STATEMENT_START2";
public static final String DELIMITER_STATEMENT_END2 = "DELIMITER_STATEMENT_END2";
public static final String NATIVE_CALL = "NATIVE_CALL";
public static final String IGNORE_CLIENT_IO_ERROR = "IGNORE_CLIENT_IO_ERROR";
public static final String DIRECT_BYTE_OUTPUT = "DIRECT_BYTE_OUTPUT";
public static final String TEMPLATE_ROOT = "TEMPLATE_ROOT";
public static final String TEMPLATE_CHARSET = "TEMPLATE_CHARSET";
public static final String ERROR_HANDLER = "ERROR_HANDLER";
public static final String MVC_STRICT = "MVC_STRICT";
public static final String WEBAPP_EXT = "WEBAPP_EXT";
public static final String HTML_TAG_SUPPORT = "HTML_TAG_SUPPORT";
public static final String HTML_TAG_FLAG = "HTML_TAG_FLAG";
public static final String HTML_TAG_ATTR_CONVERT = "HTML_TAG_ATTR_CONVERT";
public static final String IMPORT_PACKAGE = "IMPORT_PACKAGE";
public static final String ENGINE = "ENGINE";
public static final String NATIVE_SECUARTY_MANAGER = "NATIVE_SECUARTY_MANAGER";
public static final String RESOURCE_LOADER = "RESOURCE_LOADER";
public static final String HTML_TAG_BINDING_ATTRIBUTE = "HTML_TAG_BINDING_ATTRIBUTE";
public static final String BUFFER_SIZE = "buffer.maxSize";
public static final String BUFFER_NUM = "buffer.num";
public static final String SAFE_OUTPUT = "SAFE_OUTPUT";
public static final String DELIMETER_CONFIG = "DELIMETER_CONFIG";
public static final String CACHE = "CACHE";
public static final String CACHE_OUTPUT_BUFFER = "CACHE_OUTPUT_BUFFER";
public static final String BIGDECIMAL = "BIGDECIMAL";
/** 配置文件的key */
@MagicConstant(stringValues = {
DELIMITER_PLACEHOLDER_START, DELIMITER_PLACEHOLDER_END,
DELIMITER_STATEMENT_START, DELIMITER_STATEMENT_END,
DELIMITER_PLACEHOLDER_START2, DELIMITER_PLACEHOLDER_END2,
DELIMITER_STATEMENT_START2, DELIMITER_STATEMENT_END2,
NATIVE_CALL, IGNORE_CLIENT_IO_ERROR, DIRECT_BYTE_OUTPUT,
TEMPLATE_ROOT, TEMPLATE_CHARSET,
ERROR_HANDLER, MVC_STRICT, WEBAPP_EXT,
HTML_TAG_SUPPORT, HTML_TAG_FLAG, HTML_TAG_ATTR_CONVERT, HTML_TAG_BINDING_ATTRIBUTE,
IMPORT_PACKAGE, ENGINE, NATIVE_SECUARTY_MANAGER, RESOURCE_LOADER,
BUFFER_SIZE, BUFFER_NUM, SAFE_OUTPUT,DELIMETER_CONFIG,CACHE,CACHE_OUTPUT_BUFFER,BIGDECIMAL
})
@Retention(RetentionPolicy.SOURCE)
public @interface PropertiesKey {
}
/** 配置文件 */
Properties ps = null;
DelimeterHolder pd = null;
DelimeterHolder sd = null;
HtmlTagHolder tagConf = null;
ClassLoader classLoader = Thread.currentThread().getContextClassLoader() != null
? Thread.currentThread().getContextClassLoader()
: Configuration.class.getClassLoader();
/**
* 创建一个新的 Configuration 实例
*
* @return 一个新的 Configuration 实例
* @throws IOException 配置文件不存在等情况
*/
public static Configuration defaultConfiguration() throws IOException {
return new Configuration();
}
/**
* 构造方法
*
* @throws IOException 文件不存在等情况
*/
public Configuration() throws IOException {
initDefault();
}
/**
* 构造方法
* @see "issue: https://gitee.com/xiandafu/beetl/issues/I2AQXA"
*
* @param classLoader 使用指定的ClassLoader
* @throws IOException 文件不存在等情况
*/
public Configuration(ClassLoader classLoader) throws IOException {
this.classLoader = classLoader;
initDefault();
}
/**
* 构造方法
*
* @param ps 配置文件
* @throws IOException 文件不存在等情况
*/
public Configuration(Properties ps) throws IOException {
initDefault();
parseProperties(ps);
}
public void build() {
buildDelimeter();
}
private void buildDelimeter() {
if (TextUtils.isBlank(placeholderStart) || TextUtils.isBlank(placeholderEnd)) {
throw new IllegalArgumentException("占位符不能为空");
}
if (this.placeholderStart2 != null) {
if (TextUtils.isBlank(placeholderStart2) || TextUtils.isBlank(placeholderEnd2)) {
throw new IllegalArgumentException("定义了2对占位符配置,但占位符2不能为空");
}
pd = new DelimeterHolder(placeholderStart.toCharArray(), placeholderEnd.toCharArray(),
placeholderStart2.toCharArray(), placeholderEnd2.toCharArray());
} else {
pd = new DelimeterHolder(placeholderStart.toCharArray(), placeholderEnd.toCharArray());
}
if (TextUtils.isBlank(statementStart)) {
throw new IllegalArgumentException("定界符起始符号不能为空");
}
if (this.statementStart2 != null) {
if (TextUtils.isBlank(statementStart2)) {
throw new IllegalArgumentException("定义了2对定界符配置,但定界符起始符号不能为空");
}
sd = new DelimeterHolder(statementStart.toCharArray(),
statementEnd != null ? statementEnd.toCharArray() : null,
statementStart2.toCharArray(),
statementEnd2 != null ? statementEnd2.toCharArray() : null);
} else {
sd = new DelimeterHolder(statementStart.toCharArray(),
statementEnd != null ? statementEnd.toCharArray() : null);
}
tagConf = new HtmlTagHolder(htmlTagStart, htmlTagEnd, htmlTagBindingAttribute, isHtmlTagSupport);
}
private void initDefault() throws IOException {
resetHtmlTag();
// 总是添加这俩个
pkgList.add("java.util.");
pkgList.add("java.lang.");
// beetl默认
ps = new Properties();
ps.load(Configuration.class.getResourceAsStream("/org/beetl/core/beetl-default.properties"));
parseProperties(ps);
// 应用默认
// 有问题,在eclipse环境下
InputStream ins = Configuration.class.getResourceAsStream("/beetl.properties");
if (ins != null) {
ps.clear();
ps.load(ins);
parseProperties(ps);
}
}
private void resetHtmlTag() {
htmlTagStart = "<" + htmlTagFlag;
htmlTagEnd = "" + htmlTagFlag;
}
public void add(File file) throws IOException {
Properties ps = new Properties();
ps.load(new FileReader(file));
parseProperties(ps);
}
public void add(String resourceAsStreamPath) throws IOException {
Properties ps = new Properties();
ps.load(Configuration.class.getResourceAsStream(resourceAsStreamPath));
parseProperties(ps);
}
/**
* 解析配置文件到类字段中
*
* @param ps 配置文件的内容
*/
protected void parseProperties(Properties ps) {
Set> set = ps.entrySet();
for (Map.Entry