mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
fix code
This commit is contained in:
parent
9c6225dafa
commit
2d068f93fe
@ -80,27 +80,18 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
/**
|
||||
* 附带分组的键值对存储
|
||||
*/
|
||||
private final GroupedMap groupedMap = new GroupedMap();
|
||||
|
||||
/**
|
||||
* 本设置对象的字符集
|
||||
*/
|
||||
protected Charset charset;
|
||||
/**
|
||||
* 是否使用变量
|
||||
*/
|
||||
protected boolean isUseVariable;
|
||||
/**
|
||||
* 设定文件的资源
|
||||
*/
|
||||
protected Resource resource;
|
||||
private GroupedMap groupedMap;
|
||||
|
||||
/**
|
||||
* 当获取key对应值为{@code null}时是否打印debug日志提示用户,默认{@code false}
|
||||
*/
|
||||
private boolean logIfNull;
|
||||
|
||||
private SettingLoader settingLoader;
|
||||
/**
|
||||
* 设定文件的资源
|
||||
*/
|
||||
protected Resource resource;
|
||||
private SettingLoader loader;
|
||||
private WatchMonitor watchMonitor;
|
||||
|
||||
// region ----- Constructor
|
||||
@ -109,7 +100,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* 空构造
|
||||
*/
|
||||
public Setting() {
|
||||
this.charset = DEFAULT_CHARSET;
|
||||
groupedMap = new GroupedMap();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,8 +130,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* @param isUseVariable 是否使用变量
|
||||
*/
|
||||
public Setting(final String path, final Charset charset, final boolean isUseVariable) {
|
||||
Assert.notBlank(path, "Blank setting path !");
|
||||
this.init(ResourceUtil.getResource(path), charset, isUseVariable);
|
||||
this(ResourceUtil.getResource(Assert.notBlank(path)), charset, isUseVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,8 +141,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* @param isUseVariable 是否使用变量
|
||||
*/
|
||||
public Setting(final File configFile, final Charset charset, final boolean isUseVariable) {
|
||||
Assert.notNull(configFile, "Null setting file define!");
|
||||
this.init(ResourceUtil.getResource(configFile), charset, isUseVariable);
|
||||
this(ResourceUtil.getResource(Assert.notNull(configFile)), charset, isUseVariable);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -164,77 +153,74 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* @since 5.4.4
|
||||
*/
|
||||
public Setting(final Resource resource, final Charset charset, final boolean isUseVariable) {
|
||||
this.init(resource, charset, isUseVariable);
|
||||
this(resource, new SettingLoader(charset, isUseVariable));
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param resource Setting的Resource
|
||||
* @param loader 自定义配置文件加载器
|
||||
*/
|
||||
public Setting(final Resource resource, SettingLoader loader) {
|
||||
this.resource = resource;
|
||||
if (null == loader) {
|
||||
loader = new SettingLoader(DEFAULT_CHARSET, false);
|
||||
}
|
||||
this.loader = loader;
|
||||
this.groupedMap = loader.load(resource);
|
||||
}
|
||||
// endregion
|
||||
|
||||
/**
|
||||
* 初始化设定文件
|
||||
*
|
||||
* @param resource {@link Resource}
|
||||
* @param charset 字符集
|
||||
* @param isUseVariable 是否使用变量
|
||||
* @return 成功初始化与否
|
||||
*/
|
||||
public boolean init(final Resource resource, final Charset charset, final boolean isUseVariable) {
|
||||
Assert.notNull(resource, "Setting resource must be not null!");
|
||||
this.resource = resource;
|
||||
this.charset = charset;
|
||||
this.isUseVariable = isUseVariable;
|
||||
|
||||
return load();
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新加载配置文件
|
||||
*
|
||||
* @return 是否加载成功
|
||||
* @return this
|
||||
*/
|
||||
synchronized public boolean load() {
|
||||
if (null == this.settingLoader) {
|
||||
settingLoader = new SettingLoader(this.groupedMap, this.charset, this.isUseVariable);
|
||||
}
|
||||
return settingLoader.load(this.resource);
|
||||
synchronized public Setting load() {
|
||||
Assert.notNull(this.loader, "SettingLoader must be not null!");
|
||||
this.groupedMap = loader.load(this.resource);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在配置文件变更时自动加载
|
||||
*/
|
||||
public void autoLoad() {
|
||||
autoLoad(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在配置文件变更时自动加载
|
||||
*
|
||||
* @param autoReload 是否自动加载
|
||||
* @param callback 加载完成回调
|
||||
*/
|
||||
public void autoLoad(final boolean autoReload) {
|
||||
autoLoad(autoReload, null);
|
||||
}
|
||||
public void autoLoad(final Consumer<Setting> callback) {
|
||||
Assert.notNull(this.resource, "Setting resource must be not null !");
|
||||
// 先关闭之前的监听
|
||||
IoUtil.closeQuietly(this.watchMonitor);
|
||||
this.watchMonitor = WatchUtil.ofModify(resource.getUrl(), new SimpleWatcher() {
|
||||
private static final long serialVersionUID = 5190107321461226190L;
|
||||
|
||||
/**
|
||||
* 在配置文件变更时自动加载
|
||||
*
|
||||
* @param callback 加载完成回调
|
||||
* @param autoReload 是否自动加载
|
||||
*/
|
||||
public void autoLoad(final boolean autoReload, final Consumer<Boolean> callback) {
|
||||
if (autoReload) {
|
||||
Assert.notNull(this.resource, "Setting resource must be not null !");
|
||||
// 先关闭之前的监听
|
||||
IoUtil.closeQuietly(this.watchMonitor);
|
||||
this.watchMonitor = WatchUtil.ofModify(resource.getUrl(), new SimpleWatcher() {
|
||||
private static final long serialVersionUID = 5190107321461226190L;
|
||||
|
||||
@Override
|
||||
public void onModify(final WatchEvent<?> event, final WatchKey key) {
|
||||
final boolean success = load();
|
||||
// 如果有回调,加载完毕则执行回调
|
||||
if (callback != null) {
|
||||
callback.accept(success);
|
||||
}
|
||||
@Override
|
||||
public void onModify(final WatchEvent<?> event, final WatchKey key) {
|
||||
load();
|
||||
// 如果有回调,加载完毕则执行回调
|
||||
if (callback != null) {
|
||||
callback.accept(Setting.this);
|
||||
}
|
||||
});
|
||||
this.watchMonitor.start();
|
||||
LogUtil.debug("Auto load for [{}] listenning...", this.resource.getUrl());
|
||||
} else {
|
||||
IoUtil.closeQuietly(this.watchMonitor);
|
||||
this.watchMonitor = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
this.watchMonitor.start();
|
||||
LogUtil.debug("Auto load for [{}] listenning...", this.resource.getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止自动加载
|
||||
*/
|
||||
public void stopAutoLoad() {
|
||||
IoUtil.closeQuietly(this.watchMonitor);
|
||||
this.watchMonitor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -342,8 +328,6 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
return props;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------- Functions
|
||||
|
||||
/**
|
||||
* 持久化当前设置,会覆盖掉之前的设置<br>
|
||||
* 持久化不会保留之前的分组,注意如果配置文件在jar内部或者在exe中,此方法会报错。
|
||||
@ -374,10 +358,8 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public void store(final File file) {
|
||||
if (null == this.settingLoader) {
|
||||
settingLoader = new SettingLoader(this.groupedMap, this.charset, this.isUseVariable);
|
||||
}
|
||||
settingLoader.store(file);
|
||||
Assert.notNull(this.loader, "SettingLoader must be not null!");
|
||||
this.loader.store(this.groupedMap, file);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -394,7 +376,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
// issue#I9B98C,忽略null的键值对
|
||||
final String key = entry.getKey();
|
||||
final String value = entry.getValue();
|
||||
if(null != key && null != value){
|
||||
if (null != key && null != value) {
|
||||
props.setProperty(StrUtil.isEmpty(group) ? key : group + CharUtil.DOT + key, value);
|
||||
}
|
||||
}
|
||||
@ -429,31 +411,20 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
* @return this
|
||||
*/
|
||||
public Setting setVarRegex(final String regex) {
|
||||
if (null == this.settingLoader) {
|
||||
if (null == this.loader) {
|
||||
throw new NullPointerException("SettingLoader is null !");
|
||||
}
|
||||
this.settingLoader.setVarRegex(regex);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义字符编码
|
||||
*
|
||||
* @param charset 字符编码
|
||||
* @return this
|
||||
* @since 4.6.2
|
||||
*/
|
||||
public Setting setCharset(final Charset charset) {
|
||||
this.charset = charset;
|
||||
this.loader.setVarRegex(regex);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当获取key对应值为{@code null}时是否打印debug日志提示用户
|
||||
*
|
||||
* @param logIfNull 当获取key对应值为{@code null}时是否打印debug日志提示用户
|
||||
* @return this
|
||||
*/
|
||||
public Setting setLogIfNull(final boolean logIfNull){
|
||||
public Setting setLogIfNull(final boolean logIfNull) {
|
||||
this.logIfNull = logIfNull;
|
||||
return this;
|
||||
}
|
||||
@ -663,7 +634,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
*/
|
||||
@Override
|
||||
public String get(final Object key) {
|
||||
return getStr((String)key);
|
||||
return getStr((String) key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -742,9 +713,7 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((charset == null) ? 0 : charset.hashCode());
|
||||
result = prime * result + groupedMap.hashCode();
|
||||
result = prime * result + (isUseVariable ? 1231 : 1237);
|
||||
result = prime * result + ((this.resource == null) ? 0 : this.resource.hashCode());
|
||||
return result;
|
||||
}
|
||||
@ -761,19 +730,9 @@ public class Setting extends AbsSetting implements Map<String, String> {
|
||||
return false;
|
||||
}
|
||||
final Setting other = (Setting) obj;
|
||||
if (charset == null) {
|
||||
if (other.charset != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!charset.equals(other.charset)) {
|
||||
return false;
|
||||
}
|
||||
if (!groupedMap.equals(other.groupedMap)) {
|
||||
return false;
|
||||
}
|
||||
if (isUseVariable != other.isUseVariable) {
|
||||
return false;
|
||||
}
|
||||
if (this.resource == null) {
|
||||
return other.resource == null;
|
||||
} else {
|
||||
|
@ -25,7 +25,6 @@ import org.dromara.hutool.core.regex.ReUtil;
|
||||
import org.dromara.hutool.core.text.CharUtil;
|
||||
import org.dromara.hutool.core.text.StrUtil;
|
||||
import org.dromara.hutool.core.text.split.SplitUtil;
|
||||
import org.dromara.hutool.core.util.CharsetUtil;
|
||||
import org.dromara.hutool.core.util.SystemUtil;
|
||||
import org.dromara.hutool.log.Log;
|
||||
|
||||
@ -62,11 +61,6 @@ public class SettingLoader {
|
||||
* 是否使用变量
|
||||
*/
|
||||
private final boolean isUseVariable;
|
||||
/**
|
||||
* GroupedMap
|
||||
*/
|
||||
private final GroupedMap groupedMap;
|
||||
|
||||
/**
|
||||
* 赋值分隔符(用于分隔键值对)
|
||||
*/
|
||||
@ -83,103 +77,15 @@ public class SettingLoader {
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param groupedMap GroupedMap
|
||||
*/
|
||||
public SettingLoader(final GroupedMap groupedMap) {
|
||||
this(groupedMap, CharsetUtil.UTF_8, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param groupedMap GroupedMap
|
||||
* @param charset 编码
|
||||
* @param isUseVariable 是否使用变量
|
||||
*/
|
||||
public SettingLoader(final GroupedMap groupedMap, final Charset charset, final boolean isUseVariable) {
|
||||
this.groupedMap = groupedMap;
|
||||
public SettingLoader(final Charset charset, final boolean isUseVariable) {
|
||||
this.charset = charset;
|
||||
this.isUseVariable = isUseVariable;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载设置文件
|
||||
*
|
||||
* @param resource 配置文件URL
|
||||
* @return 加载是否成功
|
||||
*/
|
||||
public boolean load(final Resource resource) {
|
||||
if (resource == null) {
|
||||
throw new NullPointerException("Null setting url define!");
|
||||
}
|
||||
log.debug("Load setting file [{}]", resource);
|
||||
InputStream settingStream = null;
|
||||
try {
|
||||
settingStream = resource.getStream();
|
||||
load(settingStream);
|
||||
} catch (final Exception e) {
|
||||
log.error(e, "Load setting error!");
|
||||
return false;
|
||||
} finally {
|
||||
IoUtil.closeQuietly(settingStream);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载设置文件。 此方法不会关闭流对象
|
||||
*
|
||||
* @param settingStream 文件流
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
synchronized public void load(final InputStream settingStream) throws IOException {
|
||||
this.groupedMap.clear();
|
||||
LineReader reader = null;
|
||||
try {
|
||||
reader = new LineReader(settingStream, this.charset);
|
||||
// 分组
|
||||
String group = null;
|
||||
|
||||
String line;
|
||||
while (true) {
|
||||
line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
line = StrUtil.trim(line);
|
||||
// 跳过注释行和空行
|
||||
if (StrUtil.isBlank(line) || StrUtil.startWith(line, COMMENT_FLAG_PRE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 记录分组名
|
||||
if (StrUtil.isWrap(line, CharUtil.BRACKET_START, CharUtil.BRACKET_END)) {
|
||||
group = StrUtil.trim(line.substring(1, line.length() - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] keyValue = SplitUtil.split(line, String.valueOf(this.assignFlag), 2, true, false)
|
||||
.toArray(new String[0]);
|
||||
// 跳过不符合键值规范的行
|
||||
if (keyValue.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = keyValue[1];
|
||||
if (null != this.valueEditor) {
|
||||
value = this.valueEditor.apply(value);
|
||||
}
|
||||
|
||||
// 替换值中的所有变量变量(变量必须是此行之前定义的变量,否则无法找到)
|
||||
if (this.isUseVariable) {
|
||||
value = replaceVar(group, value);
|
||||
}
|
||||
this.groupedMap.put(group, StrUtil.trim(keyValue[0]), value);
|
||||
}
|
||||
} finally {
|
||||
IoUtil.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
// region ----- setXXX
|
||||
|
||||
/**
|
||||
* 设置变量的正则<br>
|
||||
@ -218,31 +124,120 @@ public class SettingLoader {
|
||||
this.valueEditor = valueEditor;
|
||||
return this;
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region ----- load
|
||||
|
||||
/**
|
||||
* 加载设置文件
|
||||
*
|
||||
* @param resource 配置文件URL
|
||||
* @return 加载是否成功
|
||||
*/
|
||||
public GroupedMap load(final Resource resource) {
|
||||
if (resource == null) {
|
||||
throw new NullPointerException("Null setting url define!");
|
||||
}
|
||||
log.debug("Load setting file [{}]", resource);
|
||||
InputStream settingStream = null;
|
||||
try {
|
||||
settingStream = resource.getStream();
|
||||
return load(settingStream);
|
||||
} catch (final Exception e) {
|
||||
log.error(e, "Load setting error!");
|
||||
// 加载错误跳过,返回空的map
|
||||
return new GroupedMap();
|
||||
} finally {
|
||||
IoUtil.closeQuietly(settingStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载设置文件。 此方法不会关闭流对象
|
||||
*
|
||||
* @param settingStream 文件流
|
||||
* @return {@link GroupedMap}
|
||||
* @throws IOException IO异常
|
||||
*/
|
||||
synchronized public GroupedMap load(final InputStream settingStream) throws IOException {
|
||||
final GroupedMap groupedMap = new GroupedMap();
|
||||
LineReader reader = null;
|
||||
try {
|
||||
reader = new LineReader(settingStream, this.charset);
|
||||
// 分组
|
||||
String group = null;
|
||||
|
||||
String line;
|
||||
while (true) {
|
||||
line = reader.readLine();
|
||||
if (line == null) {
|
||||
break;
|
||||
}
|
||||
line = StrUtil.trim(line);
|
||||
// 跳过注释行和空行
|
||||
if (StrUtil.isBlank(line) || StrUtil.startWith(line, COMMENT_FLAG_PRE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 记录分组名
|
||||
if (StrUtil.isWrap(line, CharUtil.BRACKET_START, CharUtil.BRACKET_END)) {
|
||||
group = StrUtil.trim(line.substring(1, line.length() - 1));
|
||||
continue;
|
||||
}
|
||||
|
||||
final String[] keyValue = SplitUtil.split(line, String.valueOf(this.assignFlag), 2, true, false)
|
||||
.toArray(new String[0]);
|
||||
// 跳过不符合键值规范的行
|
||||
if (keyValue.length < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String value = keyValue[1];
|
||||
if (null != this.valueEditor) {
|
||||
value = this.valueEditor.apply(value);
|
||||
}
|
||||
|
||||
// 替换值中的所有变量变量(变量必须是此行之前定义的变量,否则无法找到)
|
||||
if (this.isUseVariable) {
|
||||
value = replaceVar(groupedMap, group, value);
|
||||
}
|
||||
groupedMap.put(group, StrUtil.trim(keyValue[0]), value);
|
||||
}
|
||||
} finally {
|
||||
IoUtil.closeQuietly(reader);
|
||||
}
|
||||
|
||||
return groupedMap;
|
||||
}
|
||||
// endregion
|
||||
|
||||
// region ----- store
|
||||
|
||||
/**
|
||||
* 持久化当前设置,会覆盖掉之前的设置<br>
|
||||
* 持久化会不会保留之前的分组
|
||||
*
|
||||
* @param groupedMap 分组map
|
||||
* @param absolutePath 设置文件的绝对路径
|
||||
*/
|
||||
public void store(final String absolutePath) {
|
||||
store(FileUtil.touch(absolutePath));
|
||||
public void store(final GroupedMap groupedMap, final String absolutePath) {
|
||||
store(groupedMap, FileUtil.touch(absolutePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 持久化当前设置,会覆盖掉之前的设置<br>
|
||||
* 持久化会不会保留之前的分组
|
||||
*
|
||||
* @param groupedMap 分组map
|
||||
* @param file 设置文件
|
||||
* @since 5.4.3
|
||||
*/
|
||||
public void store(final File file) {
|
||||
public void store(final GroupedMap groupedMap, final File file) {
|
||||
Assert.notNull(file, "File to store must be not null !");
|
||||
log.debug("Store Setting to [{}]...", file.getAbsolutePath());
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = FileUtil.getPrintWriter(file, charset, false);
|
||||
store(writer);
|
||||
store(groupedMap, writer);
|
||||
} finally {
|
||||
IoUtil.closeQuietly(writer);
|
||||
}
|
||||
@ -251,16 +246,18 @@ public class SettingLoader {
|
||||
/**
|
||||
* 存储到Writer
|
||||
*
|
||||
* @param writer Writer
|
||||
* @param groupedMap 分组Map
|
||||
* @param writer Writer
|
||||
*/
|
||||
synchronized private void store(final PrintWriter writer) {
|
||||
for (final Entry<String, LinkedHashMap<String, String>> groupEntry : this.groupedMap.entrySet()) {
|
||||
synchronized private void store(final GroupedMap groupedMap, final PrintWriter writer) {
|
||||
for (final Entry<String, LinkedHashMap<String, String>> groupEntry : groupedMap.entrySet()) {
|
||||
writer.println(StrUtil.format("{}{}{}", CharUtil.BRACKET_START, groupEntry.getKey(), CharUtil.BRACKET_END));
|
||||
for (final Entry<String, String> entry : groupEntry.getValue().entrySet()) {
|
||||
writer.println(StrUtil.format("{} {} {}", entry.getKey(), this.assignFlag, entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
// endregion
|
||||
|
||||
// ----------------------------------------------------------------------------------- Private method start
|
||||
|
||||
@ -271,7 +268,7 @@ public class SettingLoader {
|
||||
* @param value 值
|
||||
* @return 替换后的字符串
|
||||
*/
|
||||
private String replaceVar(final String group, String value) {
|
||||
private String replaceVar(final GroupedMap groupedMap, final String group, String value) {
|
||||
// 找到所有变量标识
|
||||
final Set<String> vars = ReUtil.findAll(varRegex, value, 0, new HashSet<>());
|
||||
String key;
|
||||
@ -279,12 +276,12 @@ public class SettingLoader {
|
||||
key = ReUtil.get(varRegex, var, 1);
|
||||
if (StrUtil.isNotBlank(key)) {
|
||||
// 本分组中查找变量名对应的值
|
||||
String varValue = this.groupedMap.get(group, key);
|
||||
String varValue = groupedMap.get(group, key);
|
||||
// 跨分组查找
|
||||
if (null == varValue) {
|
||||
final List<String> groupAndKey = SplitUtil.split(key, StrUtil.DOT, 2, true, false);
|
||||
if (groupAndKey.size() > 1) {
|
||||
varValue = this.groupedMap.get(groupAndKey.get(0), groupAndKey.get(1));
|
||||
varValue = groupedMap.get(groupAndKey.get(0), groupAndKey.get(1));
|
||||
}
|
||||
}
|
||||
// 系统参数和环境变量中查找
|
||||
|
Loading…
x
Reference in New Issue
Block a user