change line sep

This commit is contained in:
Looly
2021-01-20 17:10:45 +08:00
parent 720d24566b
commit 4e38adb32d
1450 changed files with 183940 additions and 183940 deletions

View File

@@ -1,341 +1,341 @@
package cn.hutool.setting;
import java.io.Serializable;
import java.lang.reflect.Type;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.getter.OptNullBasicTypeFromStringGetter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
/**
* Setting抽象类
*
* @author Looly
*/
public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<String>, Serializable {
private static final long serialVersionUID = 6200156302595905863L;
private final static Log log = LogFactory.get();
/**
* 数组类型值默认分隔符
*/
public final static String DEFAULT_DELIMITER = ",";
/**
* 默认分组
*/
public final static String DEFAULT_GROUP = StrUtil.EMPTY;
@Override
public String getStr(String key, String defaultValue) {
return getStr(key, DEFAULT_GROUP, defaultValue);
}
/**
* 获得字符串类型值
*
* @param key KEY
* @param group 分组
* @param defaultValue 默认值
* @return 值,如果字符串为{@code null}返回默认值
*/
public String getStr(String key, String group, String defaultValue) {
final String value = getByGroup(key, group);
return ObjectUtil.defaultIfNull(value, defaultValue);
}
/**
* 获得字符串类型值,如果字符串为{@code null}或者""返回默认值
*
* @param key KEY
* @param group 分组
* @param defaultValue 默认值
* @return 值,如果字符串为{@code null}或者""返回默认值
* @since 5.2。4
*/
public String getStrNotEmpty(String key, String group, String defaultValue) {
final String value = getByGroup(key, group);
return ObjectUtil.defaultIfEmpty(value, defaultValue);
}
/**
* 获得指定分组的键对应值
*
* @param key 键
* @param group 分组
* @return 值
*/
public abstract String getByGroup(String key, String group);
// --------------------------------------------------------------- Get
/**
* 带有日志提示的get如果没有定义指定的KEY则打印debug日志
*
* @param key 键
* @return 值
*/
public String getWithLog(String key) {
final String value = getStr(key);
if (value == null) {
log.debug("No key define for [{}]!", key);
}
return value;
}
/**
* 带有日志提示的get如果没有定义指定的KEY则打印debug日志
*
* @param key 键
* @param group 分组
* @return 值
*/
public String getByGroupWithLog(String key, String group) {
final String value = getByGroup(key, group);
if (value == null) {
log.debug("No key define for [{}] of group [{}] !", key, group);
}
return value;
}
// --------------------------------------------------------------- Get string array
/**
* 获得数组型
*
* @param key 属性名
* @return 属性值
*/
public String[] getStrings(String key) {
return getStrings(key, null);
}
/**
* 获得数组型
*
* @param key 属性名
* @param defaultValue 默认的值
* @return 属性值
*/
public String[] getStringsWithDefault(String key, String[] defaultValue) {
String[] value = getStrings(key, null);
if (null == value) {
value = defaultValue;
}
return value;
}
/**
* 获得数组型
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public String[] getStrings(String key, String group) {
return getStrings(key, group, DEFAULT_DELIMITER);
}
/**
* 获得数组型
*
* @param key 属性名
* @param group 分组名
* @param delimiter 分隔符
* @return 属性值
*/
public String[] getStrings(String key, String group, String delimiter) {
final String value = getByGroup(key, group);
if (StrUtil.isBlank(value)) {
return null;
}
return StrUtil.split(value, delimiter);
}
// --------------------------------------------------------------- Get int
/**
* 获取数字型型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Integer getInt(String key, String group) {
return getInt(key, group, null);
}
/**
* 获取数字型型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Integer getInt(String key, String group, Integer defaultValue) {
return Convert.toInt(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get bool
/**
* 获取波尔型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Boolean getBool(String key, String group) {
return getBool(key, group, null);
}
/**
* 获取波尔型型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Boolean getBool(String key, String group, Boolean defaultValue) {
return Convert.toBool(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get long
/**
* 获取long类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Long getLong(String key, String group) {
return getLong(key, group, null);
}
/**
* 获取long类型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Long getLong(String key, String group, Long defaultValue) {
return Convert.toLong(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get char
/**
* 获取char类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Character getChar(String key, String group) {
final String value = getByGroup(key, group);
if (StrUtil.isBlank(value)) {
return null;
}
return value.charAt(0);
}
// --------------------------------------------------------------- Get double
/**
* 获取double类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Double getDouble(String key, String group) {
return getDouble(key, group, null);
}
/**
* 获取double类型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Double getDouble(String key, String group, Double defaultValue) {
return Convert.toDouble(getByGroup(key, group), defaultValue);
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> Bean类型
* @param group 分组
* @param bean Bean对象
* @return Bean
*/
public <T> T toBean(final String group, T bean) {
return BeanUtil.fillBean(bean, new ValueProvider<String>() {
@Override
public Object value(String key, Type valueType) {
return getByGroup(key, group);
}
@Override
public boolean containsKey(String key) {
return null != getByGroup(key, group);
}
}, CopyOptions.create());
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> Bean类型
* @param group 分组
* @param beanClass Bean类型
* @return Bean
* @since 5.0.6
*/
public <T> T toBean(String group, Class<T> beanClass) {
return toBean(group, ReflectUtil.newInstanceIfPossible(beanClass));
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> bean类型
* @param bean Bean
* @return Bean
*/
public <T> T toBean(T bean) {
return toBean(null, bean);
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> bean类型
* @param beanClass Bean类型
* @return Bean
* @since 5.0.6
*/
public <T> T toBean(Class<T> beanClass) {
return toBean(null, beanClass);
}
}
package cn.hutool.setting;
import java.io.Serializable;
import java.lang.reflect.Type;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.bean.copier.ValueProvider;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.getter.OptNullBasicTypeFromStringGetter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
/**
* Setting抽象类
*
* @author Looly
*/
public abstract class AbsSetting implements OptNullBasicTypeFromStringGetter<String>, Serializable {
private static final long serialVersionUID = 6200156302595905863L;
private final static Log log = LogFactory.get();
/**
* 数组类型值默认分隔符
*/
public final static String DEFAULT_DELIMITER = ",";
/**
* 默认分组
*/
public final static String DEFAULT_GROUP = StrUtil.EMPTY;
@Override
public String getStr(String key, String defaultValue) {
return getStr(key, DEFAULT_GROUP, defaultValue);
}
/**
* 获得字符串类型值
*
* @param key KEY
* @param group 分组
* @param defaultValue 默认值
* @return 值,如果字符串为{@code null}返回默认值
*/
public String getStr(String key, String group, String defaultValue) {
final String value = getByGroup(key, group);
return ObjectUtil.defaultIfNull(value, defaultValue);
}
/**
* 获得字符串类型值,如果字符串为{@code null}或者""返回默认值
*
* @param key KEY
* @param group 分组
* @param defaultValue 默认值
* @return 值,如果字符串为{@code null}或者""返回默认值
* @since 5.2。4
*/
public String getStrNotEmpty(String key, String group, String defaultValue) {
final String value = getByGroup(key, group);
return ObjectUtil.defaultIfEmpty(value, defaultValue);
}
/**
* 获得指定分组的键对应值
*
* @param key 键
* @param group 分组
* @return 值
*/
public abstract String getByGroup(String key, String group);
// --------------------------------------------------------------- Get
/**
* 带有日志提示的get如果没有定义指定的KEY则打印debug日志
*
* @param key 键
* @return 值
*/
public String getWithLog(String key) {
final String value = getStr(key);
if (value == null) {
log.debug("No key define for [{}]!", key);
}
return value;
}
/**
* 带有日志提示的get如果没有定义指定的KEY则打印debug日志
*
* @param key 键
* @param group 分组
* @return 值
*/
public String getByGroupWithLog(String key, String group) {
final String value = getByGroup(key, group);
if (value == null) {
log.debug("No key define for [{}] of group [{}] !", key, group);
}
return value;
}
// --------------------------------------------------------------- Get string array
/**
* 获得数组型
*
* @param key 属性名
* @return 属性值
*/
public String[] getStrings(String key) {
return getStrings(key, null);
}
/**
* 获得数组型
*
* @param key 属性名
* @param defaultValue 默认的值
* @return 属性值
*/
public String[] getStringsWithDefault(String key, String[] defaultValue) {
String[] value = getStrings(key, null);
if (null == value) {
value = defaultValue;
}
return value;
}
/**
* 获得数组型
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public String[] getStrings(String key, String group) {
return getStrings(key, group, DEFAULT_DELIMITER);
}
/**
* 获得数组型
*
* @param key 属性名
* @param group 分组名
* @param delimiter 分隔符
* @return 属性值
*/
public String[] getStrings(String key, String group, String delimiter) {
final String value = getByGroup(key, group);
if (StrUtil.isBlank(value)) {
return null;
}
return StrUtil.split(value, delimiter);
}
// --------------------------------------------------------------- Get int
/**
* 获取数字型型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Integer getInt(String key, String group) {
return getInt(key, group, null);
}
/**
* 获取数字型型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Integer getInt(String key, String group, Integer defaultValue) {
return Convert.toInt(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get bool
/**
* 获取波尔型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Boolean getBool(String key, String group) {
return getBool(key, group, null);
}
/**
* 获取波尔型型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Boolean getBool(String key, String group, Boolean defaultValue) {
return Convert.toBool(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get long
/**
* 获取long类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Long getLong(String key, String group) {
return getLong(key, group, null);
}
/**
* 获取long类型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Long getLong(String key, String group, Long defaultValue) {
return Convert.toLong(getByGroup(key, group), defaultValue);
}
// --------------------------------------------------------------- Get char
/**
* 获取char类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Character getChar(String key, String group) {
final String value = getByGroup(key, group);
if (StrUtil.isBlank(value)) {
return null;
}
return value.charAt(0);
}
// --------------------------------------------------------------- Get double
/**
* 获取double类型属性值
*
* @param key 属性名
* @param group 分组名
* @return 属性值
*/
public Double getDouble(String key, String group) {
return getDouble(key, group, null);
}
/**
* 获取double类型属性值
*
* @param key 属性名
* @param group 分组名
* @param defaultValue 默认值
* @return 属性值
*/
public Double getDouble(String key, String group, Double defaultValue) {
return Convert.toDouble(getByGroup(key, group), defaultValue);
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> Bean类型
* @param group 分组
* @param bean Bean对象
* @return Bean
*/
public <T> T toBean(final String group, T bean) {
return BeanUtil.fillBean(bean, new ValueProvider<String>() {
@Override
public Object value(String key, Type valueType) {
return getByGroup(key, group);
}
@Override
public boolean containsKey(String key) {
return null != getByGroup(key, group);
}
}, CopyOptions.create());
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> Bean类型
* @param group 分组
* @param beanClass Bean类型
* @return Bean
* @since 5.0.6
*/
public <T> T toBean(String group, Class<T> beanClass) {
return toBean(group, ReflectUtil.newInstanceIfPossible(beanClass));
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> bean类型
* @param bean Bean
* @return Bean
*/
public <T> T toBean(T bean) {
return toBean(null, bean);
}
/**
* 将setting中的键值关系映射到对象中原理是调用对象对应的set方法<br>
* 只支持基本类型的转换
*
* @param <T> bean类型
* @param beanClass Bean类型
* @return Bean
* @since 5.0.6
*/
public <T> T toBean(Class<T> beanClass) {
return toBean(null, beanClass);
}
}

View File

@@ -1,318 +1,318 @@
package cn.hutool.setting;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
/**
* 基于分组的Map<br>
* 此对象方法线程安全
*
* @author looly
* @since 4.0.11
*/
public class GroupedMap extends LinkedHashMap<String, LinkedHashMap<String, String>> {
private static final long serialVersionUID = -7777365130776081931L;
private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock();
private final ReadLock readLock = cacheLock.readLock();
private final WriteLock writeLock = cacheLock.writeLock();
private int size = -1;
/**
* 获取分组对应的值如果分组不存在或者值不存在则返回null
*
* @param group 分组
* @param key 键
* @return 值如果分组不存在或者值不存在则返回null
*/
public String get(String group, String key) {
readLock.lock();
try {
LinkedHashMap<String, String> map = this.get(StrUtil.nullToEmpty(group));
if (MapUtil.isNotEmpty(map)) {
return map.get(key);
}
} finally {
readLock.unlock();
}
return null;
}
@Override
public LinkedHashMap<String, String> get(Object key) {
readLock.lock();
try {
return super.get(key);
} finally {
readLock.unlock();
}
}
/**
* 总的键值对数
*
* @return 总键值对数
*/
@Override
public int size() {
writeLock.lock();
try {
if (this.size < 0) {
this.size = 0;
for (LinkedHashMap<String, String> value : this.values()) {
this.size += value.size();
}
}
} finally {
writeLock.unlock();
}
return this.size;
}
/**
* 将键值对加入到对应分组中
*
* @param group 分组
* @param key 键
* @param value 值
* @return 此key之前存在的值如果没有返回null
*/
public String put(String group, String key, String value) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.computeIfAbsent(group, k -> new LinkedHashMap<>());
this.size = -1;
return valueMap.put(key, value);
} finally {
writeLock.unlock();
}
}
/**
* 加入多个键值对到某个分组下
*
* @param group 分组
* @param m 键值对
* @return this
*/
public GroupedMap putAll(String group, Map<? extends String, ? extends String> m) {
for (Entry<? extends String, ? extends String> entry : m.entrySet()) {
this.put(group, entry.getKey(), entry.getValue());
}
return this;
}
/**
* 从指定分组中删除指定值
*
* @param group 分组
* @param key 键
* @return 被删除的值如果值不存在返回null
*/
public String remove(String group, String key) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.remove(key);
}
} finally {
writeLock.unlock();
}
return null;
}
/**
* 某个分组对应的键值对是否为空
*
* @param group 分组
* @return 是否为空
*/
public boolean isEmpty(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.isEmpty();
}
} finally {
readLock.unlock();
}
return true;
}
/**
* 是否为空,如果多个分组同时为空,也按照空处理
*
* @return 是否为空,如果多个分组同时为空,也按照空处理
*/
@Override
public boolean isEmpty() {
return this.size() == 0;
}
/**
* 指定分组中是否包含指定key
*
* @param group 分组
* @param key 键
* @return 是否包含key
*/
public boolean containsKey(String group, String key) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.containsKey(key);
}
} finally {
readLock.unlock();
}
return false;
}
/**
* 指定分组中是否包含指定值
*
* @param group 分组
* @param value 值
* @return 是否包含值
*/
public boolean containsValue(String group, String value) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.containsValue(value);
}
} finally {
readLock.unlock();
}
return false;
}
/**
* 清除指定分组下的所有键值对
*
* @param group 分组
* @return this
*/
public GroupedMap clear(String group) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
valueMap.clear();
}
} finally {
writeLock.unlock();
}
return this;
}
@Override
public Set<String> keySet() {
readLock.lock();
try {
return super.keySet();
} finally {
readLock.unlock();
}
}
/**
* 指定分组所有键的Set
*
* @param group 分组
* @return 键Set
*/
public Set<String> keySet(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.keySet();
}
} finally {
readLock.unlock();
}
return Collections.emptySet();
}
/**
* 指定分组下所有值
*
* @param group 分组
* @return 值
*/
public Collection<String> values(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.values();
}
} finally {
readLock.unlock();
}
return Collections.emptyList();
}
@Override
public Set<java.util.Map.Entry<String, LinkedHashMap<String, String>>> entrySet() {
readLock.lock();
try {
return super.entrySet();
} finally {
readLock.unlock();
}
}
/**
* 指定分组下所有键值对
*
* @param group 分组
* @return 键值对
*/
public Set<Entry<String, String>> entrySet(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.entrySet();
}
} finally {
readLock.unlock();
}
return Collections.emptySet();
}
@Override
public String toString() {
readLock.lock();
try {
return super.toString();
} finally {
readLock.unlock();
}
}
}
package cn.hutool.setting;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
/**
* 基于分组的Map<br>
* 此对象方法线程安全
*
* @author looly
* @since 4.0.11
*/
public class GroupedMap extends LinkedHashMap<String, LinkedHashMap<String, String>> {
private static final long serialVersionUID = -7777365130776081931L;
private final ReentrantReadWriteLock cacheLock = new ReentrantReadWriteLock();
private final ReadLock readLock = cacheLock.readLock();
private final WriteLock writeLock = cacheLock.writeLock();
private int size = -1;
/**
* 获取分组对应的值如果分组不存在或者值不存在则返回null
*
* @param group 分组
* @param key 键
* @return 值如果分组不存在或者值不存在则返回null
*/
public String get(String group, String key) {
readLock.lock();
try {
LinkedHashMap<String, String> map = this.get(StrUtil.nullToEmpty(group));
if (MapUtil.isNotEmpty(map)) {
return map.get(key);
}
} finally {
readLock.unlock();
}
return null;
}
@Override
public LinkedHashMap<String, String> get(Object key) {
readLock.lock();
try {
return super.get(key);
} finally {
readLock.unlock();
}
}
/**
* 总的键值对数
*
* @return 总键值对数
*/
@Override
public int size() {
writeLock.lock();
try {
if (this.size < 0) {
this.size = 0;
for (LinkedHashMap<String, String> value : this.values()) {
this.size += value.size();
}
}
} finally {
writeLock.unlock();
}
return this.size;
}
/**
* 将键值对加入到对应分组中
*
* @param group 分组
* @param key 键
* @param value 值
* @return 此key之前存在的值如果没有返回null
*/
public String put(String group, String key, String value) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.computeIfAbsent(group, k -> new LinkedHashMap<>());
this.size = -1;
return valueMap.put(key, value);
} finally {
writeLock.unlock();
}
}
/**
* 加入多个键值对到某个分组下
*
* @param group 分组
* @param m 键值对
* @return this
*/
public GroupedMap putAll(String group, Map<? extends String, ? extends String> m) {
for (Entry<? extends String, ? extends String> entry : m.entrySet()) {
this.put(group, entry.getKey(), entry.getValue());
}
return this;
}
/**
* 从指定分组中删除指定值
*
* @param group 分组
* @param key 键
* @return 被删除的值如果值不存在返回null
*/
public String remove(String group, String key) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.remove(key);
}
} finally {
writeLock.unlock();
}
return null;
}
/**
* 某个分组对应的键值对是否为空
*
* @param group 分组
* @return 是否为空
*/
public boolean isEmpty(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.isEmpty();
}
} finally {
readLock.unlock();
}
return true;
}
/**
* 是否为空,如果多个分组同时为空,也按照空处理
*
* @return 是否为空,如果多个分组同时为空,也按照空处理
*/
@Override
public boolean isEmpty() {
return this.size() == 0;
}
/**
* 指定分组中是否包含指定key
*
* @param group 分组
* @param key 键
* @return 是否包含key
*/
public boolean containsKey(String group, String key) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.containsKey(key);
}
} finally {
readLock.unlock();
}
return false;
}
/**
* 指定分组中是否包含指定值
*
* @param group 分组
* @param value 值
* @return 是否包含值
*/
public boolean containsValue(String group, String value) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.containsValue(value);
}
} finally {
readLock.unlock();
}
return false;
}
/**
* 清除指定分组下的所有键值对
*
* @param group 分组
* @return this
*/
public GroupedMap clear(String group) {
group = StrUtil.nullToEmpty(group).trim();
writeLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
valueMap.clear();
}
} finally {
writeLock.unlock();
}
return this;
}
@Override
public Set<String> keySet() {
readLock.lock();
try {
return super.keySet();
} finally {
readLock.unlock();
}
}
/**
* 指定分组所有键的Set
*
* @param group 分组
* @return 键Set
*/
public Set<String> keySet(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.keySet();
}
} finally {
readLock.unlock();
}
return Collections.emptySet();
}
/**
* 指定分组下所有值
*
* @param group 分组
* @return 值
*/
public Collection<String> values(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.values();
}
} finally {
readLock.unlock();
}
return Collections.emptyList();
}
@Override
public Set<java.util.Map.Entry<String, LinkedHashMap<String, String>>> entrySet() {
readLock.lock();
try {
return super.entrySet();
} finally {
readLock.unlock();
}
}
/**
* 指定分组下所有键值对
*
* @param group 分组
* @return 键值对
*/
public Set<Entry<String, String>> entrySet(String group) {
group = StrUtil.nullToEmpty(group).trim();
readLock.lock();
try {
final LinkedHashMap<String, String> valueMap = this.get(group);
if (MapUtil.isNotEmpty(valueMap)) {
return valueMap.entrySet();
}
} finally {
readLock.unlock();
}
return Collections.emptySet();
}
@Override
public String toString() {
readLock.lock();
try {
return super.toString();
} finally {
readLock.unlock();
}
}
}

View File

@@ -1,312 +1,312 @@
package cn.hutool.setting;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* 分组化的Set集合类<br>
* 在配置文件中可以用中括号分隔不同的分组每个分组会放在独立的Set中用group区别<br>
* 无分组的集合和`[]`分组集合会合并成员,重名的分组也会合并成员<br>
* 分组配置文件如下:
*
* <pre>
* [group1]
* aaa
* bbb
* ccc
*
* [group2]
* aaa
* ccc
* ddd
* </pre>
*
* @author Looly
* @since 3.1.0
*/
public class GroupedSet extends HashMap<String, LinkedHashSet<String>> {
private static final long serialVersionUID = -8430706353275835496L;
// private final static Log log = StaticLog.get();
/** 注释符号(当有此符号在行首,表示此行为注释) */
private final static String COMMENT_FLAG_PRE = "#";
/** 分组行识别的环绕标记 */
private final static char[] GROUP_SURROUND = { '[', ']' };
/** 本设置对象的字符集 */
private Charset charset;
/** 设定文件的URL */
private URL groupedSetUrl;
/**
* 基本构造<br>
* 需自定义初始化配置文件
*
* @param charset 字符集
*/
public GroupedSet(Charset charset) {
this.charset = charset;
}
/**
* 构造使用相对于Class文件根目录的相对路径
*
* @param pathBaseClassLoader 相对路径相对于当前项目的classes路径
* @param charset 字符集
*/
public GroupedSet(String pathBaseClassLoader, Charset charset) {
if (null == pathBaseClassLoader) {
pathBaseClassLoader = StrUtil.EMPTY;
}
final URL url = URLUtil.getURL(pathBaseClassLoader);
if (url == null) {
throw new RuntimeException(StrUtil.format("Can not find GroupSet file: [{}]", pathBaseClassLoader));
}
this.init(url, charset);
}
/**
* 构造
*
* @param configFile 配置文件对象
* @param charset 字符集
*/
public GroupedSet(File configFile, Charset charset) {
if (configFile == null) {
throw new RuntimeException("Null GroupSet file!");
}
final URL url = URLUtil.getURL(configFile);
this.init(url, charset);
}
/**
* 构造相对于classes读取文件
*
* @param path 相对路径
* @param clazz 基准类
* @param charset 字符集
*/
public GroupedSet(String path, Class<?> clazz, Charset charset) {
final URL url = URLUtil.getURL(path, clazz);
if (url == null) {
throw new RuntimeException(StrUtil.format("Can not find GroupSet file: [{}]", path));
}
this.init(url, charset);
}
/**
* 构造
*
* @param url 设定文件的URL
* @param charset 字符集
*/
public GroupedSet(URL url, Charset charset) {
if (url == null) {
throw new RuntimeException("Null url define!");
}
this.init(url, charset);
}
/**
* 构造
*
* @param pathBaseClassLoader 相对路径相对于当前项目的classes路径
*/
public GroupedSet(String pathBaseClassLoader) {
this(pathBaseClassLoader, CharsetUtil.CHARSET_UTF_8);
}
/*--------------------------公有方法 start-------------------------------*/
/**
* 初始化设定文件
*
* @param groupedSetUrl 设定文件的URL
* @param charset 字符集
* @return 成功初始化与否
*/
public boolean init(URL groupedSetUrl, Charset charset) {
if (groupedSetUrl == null) {
throw new RuntimeException("Null GroupSet url or charset define!");
}
this.charset = charset;
this.groupedSetUrl = groupedSetUrl;
return this.load(groupedSetUrl);
}
/**
* 加载设置文件
*
* @param groupedSetUrl 配置文件URL
* @return 加载是否成功
*/
synchronized public boolean load(URL groupedSetUrl) {
if (groupedSetUrl == null) {
throw new RuntimeException("Null GroupSet url define!");
}
// log.debug("Load GroupSet file [{}]", groupedSetUrl.getPath());
InputStream settingStream = null;
try {
settingStream = groupedSetUrl.openStream();
load(settingStream);
} catch (IOException e) {
// log.error(e, "Load GroupSet error!");
return false;
} finally {
IoUtil.close(settingStream);
}
return true;
}
/**
* 重新加载配置文件
*/
public void reload() {
this.load(groupedSetUrl);
}
/**
* 加载设置文件。 此方法不会关闭流对象
*
* @param settingStream 文件流
* @return 加载成功与否
* @throws IOException IO异常
*/
public boolean load(InputStream settingStream) throws IOException {
super.clear();
BufferedReader reader = null;
try {
reader = IoUtil.getReader(settingStream, charset);
// 分组
String group;
LinkedHashSet<String> valueSet = null;
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
line = line.trim();
// 跳过注释行和空行
if (StrUtil.isBlank(line) || line.startsWith(COMMENT_FLAG_PRE)) {
// 空行和注释忽略
continue;
} else if (line.startsWith(StrUtil.BACKSLASH + COMMENT_FLAG_PRE)) {
// 对于值中出现开头为#的字符串,需要转义处理,在此做反转义
line = line.substring(1);
}
// 记录分组名
if (line.charAt(0) == GROUP_SURROUND[0] && line.charAt(line.length() - 1) == GROUP_SURROUND[1]) {
// 开始新的分组取值,当出现重名分组时候,合并分组值
group = line.substring(1, line.length() - 1).trim();
valueSet = super.get(group);
if (null == valueSet) {
valueSet = new LinkedHashSet<>();
}
super.put(group, valueSet);
continue;
}
// 添加值
if (null == valueSet) {
// 当出现无分组值的时候会导致valueSet为空此时group为""
valueSet = new LinkedHashSet<>();
super.put(StrUtil.EMPTY, valueSet);
}
valueSet.add(line);
}
} finally {
IoUtil.close(reader);
}
return true;
}
/**
* @return 获得设定文件的路径
*/
public String getPath() {
return groupedSetUrl.getPath();
}
/**
* @return 获得所有分组名
*/
public Set<String> getGroups() {
return super.keySet();
}
/**
* 获得对应分组的所有值
*
* @param group 分组名
* @return 分组的值集合
*/
public LinkedHashSet<String> getValues(String group) {
if (group == null) {
group = StrUtil.EMPTY;
}
return super.get(group);
}
/**
* 是否在给定分组的集合中包含指定值<br>
* 如果给定分组对应集合不存在则返回false
*
* @param group 分组名
* @param value 测试的值
* @param otherValues 其他值
* @return 是否包含
*/
public boolean contains(String group, String value, String... otherValues) {
if (ArrayUtil.isNotEmpty(otherValues)) {
// 需要测试多个值的情况
final List<String> valueList = ListUtil.toList(otherValues);
valueList.add(value);
return contains(group, valueList);
} else {
// 测试单个值
final LinkedHashSet<String> valueSet = getValues(group);
if (CollectionUtil.isEmpty(valueSet)) {
return false;
}
return valueSet.contains(value);
}
}
/**
* 是否在给定分组的集合中全部包含指定值集合<br>
* 如果给定分组对应集合不存在则返回false
*
* @param group 分组名
* @param values 测试的值集合
* @return 是否包含
*/
public boolean contains(String group, Collection<String> values) {
final LinkedHashSet<String> valueSet = getValues(group);
if (CollectionUtil.isEmpty(values) || CollectionUtil.isEmpty(valueSet)) {
return false;
}
return valueSet.containsAll(values);
}
}
package cn.hutool.setting;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
/**
* 分组化的Set集合类<br>
* 在配置文件中可以用中括号分隔不同的分组每个分组会放在独立的Set中用group区别<br>
* 无分组的集合和`[]`分组集合会合并成员,重名的分组也会合并成员<br>
* 分组配置文件如下:
*
* <pre>
* [group1]
* aaa
* bbb
* ccc
*
* [group2]
* aaa
* ccc
* ddd
* </pre>
*
* @author Looly
* @since 3.1.0
*/
public class GroupedSet extends HashMap<String, LinkedHashSet<String>> {
private static final long serialVersionUID = -8430706353275835496L;
// private final static Log log = StaticLog.get();
/** 注释符号(当有此符号在行首,表示此行为注释) */
private final static String COMMENT_FLAG_PRE = "#";
/** 分组行识别的环绕标记 */
private final static char[] GROUP_SURROUND = { '[', ']' };
/** 本设置对象的字符集 */
private Charset charset;
/** 设定文件的URL */
private URL groupedSetUrl;
/**
* 基本构造<br>
* 需自定义初始化配置文件
*
* @param charset 字符集
*/
public GroupedSet(Charset charset) {
this.charset = charset;
}
/**
* 构造使用相对于Class文件根目录的相对路径
*
* @param pathBaseClassLoader 相对路径相对于当前项目的classes路径
* @param charset 字符集
*/
public GroupedSet(String pathBaseClassLoader, Charset charset) {
if (null == pathBaseClassLoader) {
pathBaseClassLoader = StrUtil.EMPTY;
}
final URL url = URLUtil.getURL(pathBaseClassLoader);
if (url == null) {
throw new RuntimeException(StrUtil.format("Can not find GroupSet file: [{}]", pathBaseClassLoader));
}
this.init(url, charset);
}
/**
* 构造
*
* @param configFile 配置文件对象
* @param charset 字符集
*/
public GroupedSet(File configFile, Charset charset) {
if (configFile == null) {
throw new RuntimeException("Null GroupSet file!");
}
final URL url = URLUtil.getURL(configFile);
this.init(url, charset);
}
/**
* 构造相对于classes读取文件
*
* @param path 相对路径
* @param clazz 基准类
* @param charset 字符集
*/
public GroupedSet(String path, Class<?> clazz, Charset charset) {
final URL url = URLUtil.getURL(path, clazz);
if (url == null) {
throw new RuntimeException(StrUtil.format("Can not find GroupSet file: [{}]", path));
}
this.init(url, charset);
}
/**
* 构造
*
* @param url 设定文件的URL
* @param charset 字符集
*/
public GroupedSet(URL url, Charset charset) {
if (url == null) {
throw new RuntimeException("Null url define!");
}
this.init(url, charset);
}
/**
* 构造
*
* @param pathBaseClassLoader 相对路径相对于当前项目的classes路径
*/
public GroupedSet(String pathBaseClassLoader) {
this(pathBaseClassLoader, CharsetUtil.CHARSET_UTF_8);
}
/*--------------------------公有方法 start-------------------------------*/
/**
* 初始化设定文件
*
* @param groupedSetUrl 设定文件的URL
* @param charset 字符集
* @return 成功初始化与否
*/
public boolean init(URL groupedSetUrl, Charset charset) {
if (groupedSetUrl == null) {
throw new RuntimeException("Null GroupSet url or charset define!");
}
this.charset = charset;
this.groupedSetUrl = groupedSetUrl;
return this.load(groupedSetUrl);
}
/**
* 加载设置文件
*
* @param groupedSetUrl 配置文件URL
* @return 加载是否成功
*/
synchronized public boolean load(URL groupedSetUrl) {
if (groupedSetUrl == null) {
throw new RuntimeException("Null GroupSet url define!");
}
// log.debug("Load GroupSet file [{}]", groupedSetUrl.getPath());
InputStream settingStream = null;
try {
settingStream = groupedSetUrl.openStream();
load(settingStream);
} catch (IOException e) {
// log.error(e, "Load GroupSet error!");
return false;
} finally {
IoUtil.close(settingStream);
}
return true;
}
/**
* 重新加载配置文件
*/
public void reload() {
this.load(groupedSetUrl);
}
/**
* 加载设置文件。 此方法不会关闭流对象
*
* @param settingStream 文件流
* @return 加载成功与否
* @throws IOException IO异常
*/
public boolean load(InputStream settingStream) throws IOException {
super.clear();
BufferedReader reader = null;
try {
reader = IoUtil.getReader(settingStream, charset);
// 分组
String group;
LinkedHashSet<String> valueSet = null;
while (true) {
String line = reader.readLine();
if (line == null) {
break;
}
line = line.trim();
// 跳过注释行和空行
if (StrUtil.isBlank(line) || line.startsWith(COMMENT_FLAG_PRE)) {
// 空行和注释忽略
continue;
} else if (line.startsWith(StrUtil.BACKSLASH + COMMENT_FLAG_PRE)) {
// 对于值中出现开头为#的字符串,需要转义处理,在此做反转义
line = line.substring(1);
}
// 记录分组名
if (line.charAt(0) == GROUP_SURROUND[0] && line.charAt(line.length() - 1) == GROUP_SURROUND[1]) {
// 开始新的分组取值,当出现重名分组时候,合并分组值
group = line.substring(1, line.length() - 1).trim();
valueSet = super.get(group);
if (null == valueSet) {
valueSet = new LinkedHashSet<>();
}
super.put(group, valueSet);
continue;
}
// 添加值
if (null == valueSet) {
// 当出现无分组值的时候会导致valueSet为空此时group为""
valueSet = new LinkedHashSet<>();
super.put(StrUtil.EMPTY, valueSet);
}
valueSet.add(line);
}
} finally {
IoUtil.close(reader);
}
return true;
}
/**
* @return 获得设定文件的路径
*/
public String getPath() {
return groupedSetUrl.getPath();
}
/**
* @return 获得所有分组名
*/
public Set<String> getGroups() {
return super.keySet();
}
/**
* 获得对应分组的所有值
*
* @param group 分组名
* @return 分组的值集合
*/
public LinkedHashSet<String> getValues(String group) {
if (group == null) {
group = StrUtil.EMPTY;
}
return super.get(group);
}
/**
* 是否在给定分组的集合中包含指定值<br>
* 如果给定分组对应集合不存在则返回false
*
* @param group 分组名
* @param value 测试的值
* @param otherValues 其他值
* @return 是否包含
*/
public boolean contains(String group, String value, String... otherValues) {
if (ArrayUtil.isNotEmpty(otherValues)) {
// 需要测试多个值的情况
final List<String> valueList = ListUtil.toList(otherValues);
valueList.add(value);
return contains(group, valueList);
} else {
// 测试单个值
final LinkedHashSet<String> valueSet = getValues(group);
if (CollectionUtil.isEmpty(valueSet)) {
return false;
}
return valueSet.contains(value);
}
}
/**
* 是否在给定分组的集合中全部包含指定值集合<br>
* 如果给定分组对应集合不存在则返回false
*
* @param group 分组名
* @param values 测试的值集合
* @return 是否包含
*/
public boolean contains(String group, Collection<String> values) {
final LinkedHashSet<String> valueSet = getValues(group);
if (CollectionUtil.isEmpty(values) || CollectionUtil.isEmpty(valueSet)) {
return false;
}
return valueSet.containsAll(values);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,251 +1,251 @@
package cn.hutool.setting;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
/**
* Setting文件加载器
*
* @author Looly
*
*/
public class SettingLoader {
private static final Log log = Log.get();
/** 注释符号(当有此符号在行首,表示此行为注释) */
private final static char COMMENT_FLAG_PRE = '#';
/** 赋值分隔符(用于分隔键值对) */
private char assignFlag = '=';
/** 变量名称的正则 */
private String varRegex = "\\$\\{(.*?)\\}";
/** 本设置对象的字符集 */
private final Charset charset;
/** 是否使用变量 */
private final boolean isUseVariable;
/** GroupedMap */
private final GroupedMap groupedMap;
/**
* 构造
*
* @param groupedMap GroupedMap
*/
public SettingLoader(GroupedMap groupedMap) {
this(groupedMap, CharsetUtil.CHARSET_UTF_8, false);
}
/**
* 构造
*
* @param groupedMap GroupedMap
* @param charset 编码
* @param isUseVariable 是否使用变量
*/
public SettingLoader(GroupedMap groupedMap, Charset charset, boolean isUseVariable) {
this.groupedMap = groupedMap;
this.charset = charset;
this.isUseVariable = isUseVariable;
}
/**
* 加载设置文件
*
* @param resource 配置文件URL
* @return 加载是否成功
*/
public boolean load(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 (Exception e) {
log.error(e, "Load setting error!");
return false;
} finally {
IoUtil.close(settingStream);
}
return true;
}
/**
* 加载设置文件。 此方法不会关闭流对象
*
* @param settingStream 文件流
* @return 加载成功与否
* @throws IOException IO异常
*/
synchronized public boolean load(InputStream settingStream) throws IOException {
this.groupedMap.clear();
BufferedReader reader = null;
try {
reader = IoUtil.getReader(settingStream, this.charset);
// 分组
String group = null;
String line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
line = line.trim();
// 跳过注释行和空行
if (StrUtil.isBlank(line) || StrUtil.startWith(line, COMMENT_FLAG_PRE)) {
continue;
}
// 记录分组名
if (StrUtil.isSurround(line, CharUtil.BRACKET_START, CharUtil.BRACKET_END)) {
group = line.substring(1, line.length() - 1).trim();
continue;
}
final String[] keyValue = StrUtil.splitToArray(line, this.assignFlag, 2);
// 跳过不符合键值规范的行
if (keyValue.length < 2) {
continue;
}
String value = keyValue[1].trim();
// 替换值中的所有变量变量(变量必须是此行之前定义的变量,否则无法找到)
if (this.isUseVariable) {
value = replaceVar(group, value);
}
this.groupedMap.put(group, keyValue[0].trim(), value);
}
} finally {
IoUtil.close(reader);
}
return true;
}
/**
* 设置变量的正则<br>
* 正则只能有一个group表示变量本身剩余为字符 例如 \$\{(name)\}表示${name}变量名为name的一个变量表示
*
* @param regex 正则
*/
public void setVarRegex(String regex) {
this.varRegex = regex;
}
/**
* 赋值分隔符(用于分隔键值对)
*
* @param assignFlag 正则
* @since 4.6.5
*/
public void setAssignFlag(char assignFlag) {
this.assignFlag = assignFlag;
}
/**
* 持久化当前设置,会覆盖掉之前的设置<br>
* 持久化会不会保留之前的分组
*
* @param absolutePath 设置文件的绝对路径
*/
public void store(String absolutePath) {
store(FileUtil.touch(absolutePath));
}
/**
* 持久化当前设置,会覆盖掉之前的设置<br>
* 持久化会不会保留之前的分组
*
* @param file 设置文件
* @since 5.4.3
*/
public void store(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);
} finally {
IoUtil.close(writer);
}
}
/**
* 存储到Writer
*
* @param writer Writer
*/
synchronized private void store(PrintWriter writer) {
for (Entry<String, LinkedHashMap<String, String>> groupEntry : this.groupedMap.entrySet()) {
writer.println(StrUtil.format("{}{}{}", CharUtil.BRACKET_START, groupEntry.getKey(), CharUtil.BRACKET_END));
for (Entry<String, String> entry : groupEntry.getValue().entrySet()) {
writer.println(StrUtil.format("{} {} {}", entry.getKey(), this.assignFlag, entry.getValue()));
}
}
}
// ----------------------------------------------------------------------------------- Private method start
/**
* 替换给定值中的变量标识
*
* @param group 所在分组
* @param value 值
* @return 替换后的字符串
*/
private String replaceVar(String group, String value) {
// 找到所有变量标识
final Set<String> vars = ReUtil.findAll(varRegex, value, 0, new HashSet<>());
String key;
for (String var : vars) {
key = ReUtil.get(varRegex, var, 1);
if (StrUtil.isNotBlank(key)) {
// 本分组中查找变量名对应的值
String varValue = this.groupedMap.get(group, key);
// 跨分组查找
if (null == varValue) {
final List<String> groupAndKey = StrUtil.split(key, CharUtil.DOT, 2);
if (groupAndKey.size() > 1) {
varValue = this.groupedMap.get(groupAndKey.get(0), groupAndKey.get(1));
}
}
// 系统参数中查找
if (null == varValue) {
varValue = System.getProperty(key);
}
// 环境变量中查找
if (null == varValue) {
varValue = System.getenv(key);
}
if (null != varValue) {
// 替换标识
value = value.replace(var, varValue);
}
}
}
return value;
}
// ----------------------------------------------------------------------------------- Private method end
}
package cn.hutool.setting;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.io.resource.Resource;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
/**
* Setting文件加载器
*
* @author Looly
*
*/
public class SettingLoader {
private static final Log log = Log.get();
/** 注释符号(当有此符号在行首,表示此行为注释) */
private final static char COMMENT_FLAG_PRE = '#';
/** 赋值分隔符(用于分隔键值对) */
private char assignFlag = '=';
/** 变量名称的正则 */
private String varRegex = "\\$\\{(.*?)\\}";
/** 本设置对象的字符集 */
private final Charset charset;
/** 是否使用变量 */
private final boolean isUseVariable;
/** GroupedMap */
private final GroupedMap groupedMap;
/**
* 构造
*
* @param groupedMap GroupedMap
*/
public SettingLoader(GroupedMap groupedMap) {
this(groupedMap, CharsetUtil.CHARSET_UTF_8, false);
}
/**
* 构造
*
* @param groupedMap GroupedMap
* @param charset 编码
* @param isUseVariable 是否使用变量
*/
public SettingLoader(GroupedMap groupedMap, Charset charset, boolean isUseVariable) {
this.groupedMap = groupedMap;
this.charset = charset;
this.isUseVariable = isUseVariable;
}
/**
* 加载设置文件
*
* @param resource 配置文件URL
* @return 加载是否成功
*/
public boolean load(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 (Exception e) {
log.error(e, "Load setting error!");
return false;
} finally {
IoUtil.close(settingStream);
}
return true;
}
/**
* 加载设置文件。 此方法不会关闭流对象
*
* @param settingStream 文件流
* @return 加载成功与否
* @throws IOException IO异常
*/
synchronized public boolean load(InputStream settingStream) throws IOException {
this.groupedMap.clear();
BufferedReader reader = null;
try {
reader = IoUtil.getReader(settingStream, this.charset);
// 分组
String group = null;
String line;
while (true) {
line = reader.readLine();
if (line == null) {
break;
}
line = line.trim();
// 跳过注释行和空行
if (StrUtil.isBlank(line) || StrUtil.startWith(line, COMMENT_FLAG_PRE)) {
continue;
}
// 记录分组名
if (StrUtil.isSurround(line, CharUtil.BRACKET_START, CharUtil.BRACKET_END)) {
group = line.substring(1, line.length() - 1).trim();
continue;
}
final String[] keyValue = StrUtil.splitToArray(line, this.assignFlag, 2);
// 跳过不符合键值规范的行
if (keyValue.length < 2) {
continue;
}
String value = keyValue[1].trim();
// 替换值中的所有变量变量(变量必须是此行之前定义的变量,否则无法找到)
if (this.isUseVariable) {
value = replaceVar(group, value);
}
this.groupedMap.put(group, keyValue[0].trim(), value);
}
} finally {
IoUtil.close(reader);
}
return true;
}
/**
* 设置变量的正则<br>
* 正则只能有一个group表示变量本身剩余为字符 例如 \$\{(name)\}表示${name}变量名为name的一个变量表示
*
* @param regex 正则
*/
public void setVarRegex(String regex) {
this.varRegex = regex;
}
/**
* 赋值分隔符(用于分隔键值对)
*
* @param assignFlag 正则
* @since 4.6.5
*/
public void setAssignFlag(char assignFlag) {
this.assignFlag = assignFlag;
}
/**
* 持久化当前设置,会覆盖掉之前的设置<br>
* 持久化会不会保留之前的分组
*
* @param absolutePath 设置文件的绝对路径
*/
public void store(String absolutePath) {
store(FileUtil.touch(absolutePath));
}
/**
* 持久化当前设置,会覆盖掉之前的设置<br>
* 持久化会不会保留之前的分组
*
* @param file 设置文件
* @since 5.4.3
*/
public void store(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);
} finally {
IoUtil.close(writer);
}
}
/**
* 存储到Writer
*
* @param writer Writer
*/
synchronized private void store(PrintWriter writer) {
for (Entry<String, LinkedHashMap<String, String>> groupEntry : this.groupedMap.entrySet()) {
writer.println(StrUtil.format("{}{}{}", CharUtil.BRACKET_START, groupEntry.getKey(), CharUtil.BRACKET_END));
for (Entry<String, String> entry : groupEntry.getValue().entrySet()) {
writer.println(StrUtil.format("{} {} {}", entry.getKey(), this.assignFlag, entry.getValue()));
}
}
}
// ----------------------------------------------------------------------------------- Private method start
/**
* 替换给定值中的变量标识
*
* @param group 所在分组
* @param value 值
* @return 替换后的字符串
*/
private String replaceVar(String group, String value) {
// 找到所有变量标识
final Set<String> vars = ReUtil.findAll(varRegex, value, 0, new HashSet<>());
String key;
for (String var : vars) {
key = ReUtil.get(varRegex, var, 1);
if (StrUtil.isNotBlank(key)) {
// 本分组中查找变量名对应的值
String varValue = this.groupedMap.get(group, key);
// 跨分组查找
if (null == varValue) {
final List<String> groupAndKey = StrUtil.split(key, CharUtil.DOT, 2);
if (groupAndKey.size() > 1) {
varValue = this.groupedMap.get(groupAndKey.get(0), groupAndKey.get(1));
}
}
// 系统参数中查找
if (null == varValue) {
varValue = System.getProperty(key);
}
// 环境变量中查找
if (null == varValue) {
varValue = System.getenv(key);
}
if (null != varValue) {
// 替换标识
value = value.replace(var, varValue);
}
}
}
return value;
}
// ----------------------------------------------------------------------------------- Private method end
}

View File

@@ -1,31 +1,31 @@
package cn.hutool.setting;
import cn.hutool.core.util.StrUtil;
/**
* 设置异常
* @author xiaoleilu
*/
public class SettingRuntimeException extends RuntimeException{
private static final long serialVersionUID = 7941096116780378387L;
public SettingRuntimeException(Throwable e) {
super(e);
}
public SettingRuntimeException(String message) {
super(message);
}
public SettingRuntimeException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public SettingRuntimeException(String message, Throwable throwable) {
super(message, throwable);
}
public SettingRuntimeException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}
}
package cn.hutool.setting;
import cn.hutool.core.util.StrUtil;
/**
* 设置异常
* @author xiaoleilu
*/
public class SettingRuntimeException extends RuntimeException{
private static final long serialVersionUID = 7941096116780378387L;
public SettingRuntimeException(Throwable e) {
super(e);
}
public SettingRuntimeException(String message) {
super(message);
}
public SettingRuntimeException(String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params));
}
public SettingRuntimeException(String message, Throwable throwable) {
super(message, throwable);
}
public SettingRuntimeException(Throwable throwable, String messageTemplate, Object... params) {
super(StrUtil.format(messageTemplate, params), throwable);
}
}

View File

@@ -1,58 +1,58 @@
package cn.hutool.setting;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.io.resource.NoResourceException;
import cn.hutool.core.util.StrUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Setting工具类<br>
* 提供静态方法获取配置文件
*
* @author looly
*/
public class SettingUtil {
/**
* 配置文件缓存
*/
private static final Map<String, Setting> SETTING_MAP = new ConcurrentHashMap<>();
/**
* 获取当前环境下的配置文件<br>
* name可以为不包括扩展名的文件名默认.setting为结尾也可以是文件名全称
*
* @param name 文件名,如果没有扩展名,默认为.setting
* @return 当前环境下配置文件
*/
public static Setting get(String name) {
return SETTING_MAP.computeIfAbsent(name, (filePath)->{
final String extName = FileNameUtil.extName(filePath);
if (StrUtil.isEmpty(extName)) {
filePath = filePath + "." + Setting.EXT_NAME;
}
return new Setting(filePath, true);
});
}
/**
* 获取给定路径找到的第一个配置文件<br>
* * name可以为不包括扩展名的文件名默认.setting为结尾也可以是文件名全称
*
* @param names 文件名,如果没有扩展名,默认为.setting
*
* @return 当前环境下配置文件
* @since 5.1.3
*/
public static Setting getFirstFound(String... names) {
for (String name : names) {
try {
return get(name);
} catch (NoResourceException e) {
//ignore
}
}
return null;
}
}
package cn.hutool.setting;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.io.resource.NoResourceException;
import cn.hutool.core.util.StrUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Setting工具类<br>
* 提供静态方法获取配置文件
*
* @author looly
*/
public class SettingUtil {
/**
* 配置文件缓存
*/
private static final Map<String, Setting> SETTING_MAP = new ConcurrentHashMap<>();
/**
* 获取当前环境下的配置文件<br>
* name可以为不包括扩展名的文件名默认.setting为结尾也可以是文件名全称
*
* @param name 文件名,如果没有扩展名,默认为.setting
* @return 当前环境下配置文件
*/
public static Setting get(String name) {
return SETTING_MAP.computeIfAbsent(name, (filePath)->{
final String extName = FileNameUtil.extName(filePath);
if (StrUtil.isEmpty(extName)) {
filePath = filePath + "." + Setting.EXT_NAME;
}
return new Setting(filePath, true);
});
}
/**
* 获取给定路径找到的第一个配置文件<br>
* * name可以为不包括扩展名的文件名默认.setting为结尾也可以是文件名全称
*
* @param names 文件名,如果没有扩展名,默认为.setting
*
* @return 当前环境下配置文件
* @since 5.1.3
*/
public static Setting getFirstFound(String... names) {
for (String name : names) {
try {
return get(name);
} catch (NoResourceException e) {
//ignore
}
}
return null;
}
}

View File

@@ -1,69 +1,69 @@
package cn.hutool.setting.dialect;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.NoResourceException;
import cn.hutool.core.util.StrUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Props工具类<br>
* 提供静态方法获取配置文件
*
* @author looly
* @since 5.1.3
*/
public class PropsUtil {
/**
* 配置文件缓存
*/
private static final Map<String, Props> propsMap = new ConcurrentHashMap<>();
/**
* 获取当前环境下的配置文件<br>
* name可以为不包括扩展名的文件名默认.properties也可以是文件名全称
*
* @param name 文件名,如果没有扩展名,默认为.properties
* @return 当前环境下配置文件
*/
public static Props get(String name) {
return propsMap.computeIfAbsent(name, (filePath)->{
final String extName = FileUtil.extName(filePath);
if (StrUtil.isEmpty(extName)) {
filePath = filePath + "." + Props.EXT_NAME;
}
return new Props(filePath);
});
}
/**
* 获取给定路径找到的第一个配置文件<br>
* * name可以为不包括扩展名的文件名默认.properties为结尾也可以是文件名全称
*
* @param names 文件名,如果没有扩展名,默认为.properties
*
* @return 当前环境下配置文件
*/
public static Props getFirstFound(String... names) {
for (String name : names) {
try {
return get(name);
} catch (NoResourceException e) {
//ignore
}
}
return null;
}
/**
* 获取系统参数例如用户在执行java命令时定义的 -Duse=hutool
*
* @return 系统参数Props
* @since 5.5.2
*/
public static Props getSystemProps(){
return new Props(System.getProperties());
}
}
package cn.hutool.setting.dialect;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.NoResourceException;
import cn.hutool.core.util.StrUtil;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Props工具类<br>
* 提供静态方法获取配置文件
*
* @author looly
* @since 5.1.3
*/
public class PropsUtil {
/**
* 配置文件缓存
*/
private static final Map<String, Props> propsMap = new ConcurrentHashMap<>();
/**
* 获取当前环境下的配置文件<br>
* name可以为不包括扩展名的文件名默认.properties也可以是文件名全称
*
* @param name 文件名,如果没有扩展名,默认为.properties
* @return 当前环境下配置文件
*/
public static Props get(String name) {
return propsMap.computeIfAbsent(name, (filePath)->{
final String extName = FileUtil.extName(filePath);
if (StrUtil.isEmpty(extName)) {
filePath = filePath + "." + Props.EXT_NAME;
}
return new Props(filePath);
});
}
/**
* 获取给定路径找到的第一个配置文件<br>
* * name可以为不包括扩展名的文件名默认.properties为结尾也可以是文件名全称
*
* @param names 文件名,如果没有扩展名,默认为.properties
*
* @return 当前环境下配置文件
*/
public static Props getFirstFound(String... names) {
for (String name : names) {
try {
return get(name);
} catch (NoResourceException e) {
//ignore
}
}
return null;
}
/**
* 获取系统参数例如用户在执行java命令时定义的 -Duse=hutool
*
* @return 系统参数Props
* @since 5.5.2
*/
public static Props getSystemProps(){
return new Props(System.getProperties());
}
}

View File

@@ -1,7 +1,7 @@
/**
* 配置文件实现分装例如Properties封装Props
*
* @author looly
*
*/
/**
* 配置文件实现分装例如Properties封装Props
*
* @author looly
*
*/
package cn.hutool.setting.dialect;

View File

@@ -1,7 +1,7 @@
/**
* Setting模块主要针对Properties文件读写做封装同时定义一套自己的配置文件规范实现兼容性良好的配置工具。
*
* @author looly
*
*/
/**
* Setting模块主要针对Properties文件读写做封装同时定义一套自己的配置文件规范实现兼容性良好的配置工具。
*
* @author looly
*
*/
package cn.hutool.setting;

View File

@@ -1,36 +1,36 @@
package cn.hutool.setting.profile;
import cn.hutool.core.lang.Singleton;
import cn.hutool.setting.Setting;
/**
* 全局的Profile配置中心
*
* @author Looly
*
*/
public class GlobalProfile {
private GlobalProfile() {
}
// -------------------------------------------------------------------------------- Static method start
/**
* 设置全局环境
* @param profile 环境
* @return {@link Profile}
*/
public static Profile setProfile(String profile) {
return Singleton.get(Profile.class, profile);
}
/**
* 获得全局的当前环境下对应的配置文件
* @param settingName 配置文件名,可以忽略默认后者(.setting
* @return {@link Setting}
*/
public static Setting getSetting(String settingName) {
return Singleton.get(Profile.class).getSetting(settingName);
}
// -------------------------------------------------------------------------------- Static method end
}
package cn.hutool.setting.profile;
import cn.hutool.core.lang.Singleton;
import cn.hutool.setting.Setting;
/**
* 全局的Profile配置中心
*
* @author Looly
*
*/
public class GlobalProfile {
private GlobalProfile() {
}
// -------------------------------------------------------------------------------- Static method start
/**
* 设置全局环境
* @param profile 环境
* @return {@link Profile}
*/
public static Profile setProfile(String profile) {
return Singleton.get(Profile.class, profile);
}
/**
* 获得全局的当前环境下对应的配置文件
* @param settingName 配置文件名,可以忽略默认后者(.setting
* @return {@link Setting}
*/
public static Setting getSetting(String settingName) {
return Singleton.get(Profile.class).getSetting(settingName);
}
// -------------------------------------------------------------------------------- Static method end
}

View File

@@ -1,148 +1,148 @@
package cn.hutool.setting.profile;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.Setting;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Profile可以让我们定义一系列的配置信息然后指定其激活条件。<br>
* 此类中我们规范一套规则如下:<br>
* 默认的,我们读取${classpath}/default下的配置文件(*.setting文件)当调用setProfile方法时指定一个profile即可读取其目录下的配置文件。<br>
* 比如我们定义几个profiletestdevelopproduction分别代表测试环境、开发环境和线上环境我希望读取数据库配置文件db.setting那么
* <ol>
* <li>test =》 ${classpath}/test/db.setting</li>
* <li>develop =》 ${classpath}/develop/db.setting</li>
* <li>production =》 ${classpath}/production/db.setting</li>
* </ol>
*
* @author Looly
*
*/
public class Profile implements Serializable {
private static final long serialVersionUID = -4189955219454008744L;
/** 默认环境 */
public static final String DEFAULT_PROFILE = "default";
/** 条件 */
private String profile;
/** 编码 */
private Charset charset;
/** 是否使用变量 */
private boolean useVar;
/** 配置文件缓存 */
private final Map<String, Setting> settingMap = new ConcurrentHashMap<>();
// -------------------------------------------------------------------------------- Constructor start
/**
* 默认构造环境使用默认的default编码UTF-8不使用变量
*/
public Profile() {
this(DEFAULT_PROFILE);
}
/**
* 构造编码UTF-8不使用变量
*
* @param profile 环境
*/
public Profile(String profile) {
this(profile, Setting.DEFAULT_CHARSET, false);
}
/**
* 构造
*
* @param profile 环境
* @param charset 编码
* @param useVar 是否使用变量
*/
public Profile(String profile, Charset charset, boolean useVar) {
super();
this.profile = profile;
this.charset = charset;
this.useVar = useVar;
}
// -------------------------------------------------------------------------------- Constructor end
/**
* 获取当前环境下的配置文件
*
* @param name 文件名,如果没有扩展名,默认为.setting
* @return 当前环境下配置文件
*/
public Setting getSetting(String name) {
String nameForProfile = fixNameForProfile(name);
Setting setting = settingMap.get(nameForProfile);
if (null == setting) {
setting = new Setting(nameForProfile, this.charset, this.useVar);
settingMap.put(nameForProfile, setting);
}
return setting;
}
/**
* 设置环境
*
* @param profile 环境
* @return 自身
*/
public Profile setProfile(String profile) {
this.profile = profile;
return this;
}
/**
* 设置编码
*
* @param charset 编码
* @return 自身
*/
public Profile setCharset(Charset charset) {
this.charset = charset;
return this;
}
/**
* 设置是否使用变量
*
* @param useVar 变量
* @return 自身
*/
public Profile setUseVar(boolean useVar) {
this.useVar = useVar;
return this;
}
/**
* 清空所有环境的配置文件
*
* @return 自身
*/
public Profile clear() {
this.settingMap.clear();
return this;
}
// -------------------------------------------------------------------------------- Private method start
/**
* 修正文件名
*
* @param name 文件名
* @return 修正后的文件名
*/
private String fixNameForProfile(String name) {
Assert.notBlank(name, "Setting name must be not blank !");
final String actralProfile = StrUtil.nullToEmpty(this.profile);
if (false == name.contains(StrUtil.DOT)) {
return StrUtil.format("{}/{}.setting", actralProfile, name);
}
return StrUtil.format("{}/{}", actralProfile, name);
}
// -------------------------------------------------------------------------------- Private method end
}
package cn.hutool.setting.profile;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.Setting;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* Profile可以让我们定义一系列的配置信息然后指定其激活条件。<br>
* 此类中我们规范一套规则如下:<br>
* 默认的,我们读取${classpath}/default下的配置文件(*.setting文件)当调用setProfile方法时指定一个profile即可读取其目录下的配置文件。<br>
* 比如我们定义几个profiletestdevelopproduction分别代表测试环境、开发环境和线上环境我希望读取数据库配置文件db.setting那么
* <ol>
* <li>test =》 ${classpath}/test/db.setting</li>
* <li>develop =》 ${classpath}/develop/db.setting</li>
* <li>production =》 ${classpath}/production/db.setting</li>
* </ol>
*
* @author Looly
*
*/
public class Profile implements Serializable {
private static final long serialVersionUID = -4189955219454008744L;
/** 默认环境 */
public static final String DEFAULT_PROFILE = "default";
/** 条件 */
private String profile;
/** 编码 */
private Charset charset;
/** 是否使用变量 */
private boolean useVar;
/** 配置文件缓存 */
private final Map<String, Setting> settingMap = new ConcurrentHashMap<>();
// -------------------------------------------------------------------------------- Constructor start
/**
* 默认构造环境使用默认的default编码UTF-8不使用变量
*/
public Profile() {
this(DEFAULT_PROFILE);
}
/**
* 构造编码UTF-8不使用变量
*
* @param profile 环境
*/
public Profile(String profile) {
this(profile, Setting.DEFAULT_CHARSET, false);
}
/**
* 构造
*
* @param profile 环境
* @param charset 编码
* @param useVar 是否使用变量
*/
public Profile(String profile, Charset charset, boolean useVar) {
super();
this.profile = profile;
this.charset = charset;
this.useVar = useVar;
}
// -------------------------------------------------------------------------------- Constructor end
/**
* 获取当前环境下的配置文件
*
* @param name 文件名,如果没有扩展名,默认为.setting
* @return 当前环境下配置文件
*/
public Setting getSetting(String name) {
String nameForProfile = fixNameForProfile(name);
Setting setting = settingMap.get(nameForProfile);
if (null == setting) {
setting = new Setting(nameForProfile, this.charset, this.useVar);
settingMap.put(nameForProfile, setting);
}
return setting;
}
/**
* 设置环境
*
* @param profile 环境
* @return 自身
*/
public Profile setProfile(String profile) {
this.profile = profile;
return this;
}
/**
* 设置编码
*
* @param charset 编码
* @return 自身
*/
public Profile setCharset(Charset charset) {
this.charset = charset;
return this;
}
/**
* 设置是否使用变量
*
* @param useVar 变量
* @return 自身
*/
public Profile setUseVar(boolean useVar) {
this.useVar = useVar;
return this;
}
/**
* 清空所有环境的配置文件
*
* @return 自身
*/
public Profile clear() {
this.settingMap.clear();
return this;
}
// -------------------------------------------------------------------------------- Private method start
/**
* 修正文件名
*
* @param name 文件名
* @return 修正后的文件名
*/
private String fixNameForProfile(String name) {
Assert.notBlank(name, "Setting name must be not blank !");
final String actralProfile = StrUtil.nullToEmpty(this.profile);
if (false == name.contains(StrUtil.DOT)) {
return StrUtil.format("{}/{}.setting", actralProfile, name);
}
return StrUtil.format("{}/{}", actralProfile, name);
}
// -------------------------------------------------------------------------------- Private method end
}

View File

@@ -1,7 +1,7 @@
/**
* 配置文件实现分装例如Properties封装Props
*
* @author looly
*
*/
/**
* 配置文件实现分装例如Properties封装Props
*
* @author looly
*
*/
package cn.hutool.setting.profile;