![JAR search and dependency download from the Maven repository](/logo.png)
net.hasor.cobble.setting.BasicSettings Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hasor.cobble.setting;
import net.hasor.cobble.BeanUtils;
import net.hasor.cobble.StringUtils;
import net.hasor.cobble.convert.ConverterUtils;
import net.hasor.cobble.logging.Logger;
import net.hasor.cobble.logging.LoggerFactory;
import net.hasor.cobble.setting.data.TreeNode;
import net.hasor.cobble.text.token.GenericTokenParser;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Settings接口的抽象实现。
* @author 赵永春 ([email protected])
* @version : 2013-4-2
*/
public class BasicSettings extends AbstractSettings implements Settings {
protected static Logger logger = LoggerFactory.getLogger(BasicSettings.class);
private final Map dataMap = new ConcurrentHashMap<>();
private final Map envMap = new ConcurrentHashMap<>();
protected Map allSettingValue() {
return this.dataMap;
}
@Override
protected Map envMap() {
return this.envMap;
}
/** 清空已经装载的所有数据 */
protected void cleanData() {
this.envMap().clear();
this.allSettingValue().clear();
}
/** 加载预定义的环境变量 */
protected void loadEnvironment() throws IOException {
// 1st,System.getProperties()
Properties prop = System.getProperties();
for (Object propKey : prop.keySet()) {
String k = propKey.toString();
Object v = prop.get(propKey);
if (v != null) {
envMap().put(k.toUpperCase(), v.toString());
}
}
// 2st,System.getenv()
Map envMap = System.getenv();
for (String key : envMap.keySet()) {
envMap().put(key.toUpperCase(), envMap.get(key));
}
}
/** 加载预定义的配置信息 */
protected void loadSettings() throws IOException {
}
/** replace environment variable in config */
protected void updateSettings() {
Collection valueSet = this.allSettingValue().values();
for (TreeNode sv : valueSet) {
sv.update((dataNode, context) -> {
String[] values = dataNode.getValues();
for (int index = 0; index < values.length; index++) {
String oldVar = values[index];
String newVal = evalSetting(oldVar);
if (!StringUtils.equals(oldVar, newVal)) {
dataNode.replace(index, newVal);
}
}
}, this);
}
}
@Override
public void refresh() throws IOException {
this.loadEnvironment();
this.updateSettings();
}
public String evalSetting(String evalString) {
if (StringUtils.isBlank(evalString)) {
return "";
}
String newEvalString = new GenericTokenParser(new String[] { "${" }, "}", (hasFound, openToken, closeToken, content) -> {
String varKey = content;
String varDefault = "";
int defaultIndexOf = content.indexOf(":");
if (defaultIndexOf != -1) {
varDefault = content.substring(defaultIndexOf + 1);
varKey = content.substring(0, defaultIndexOf);
}
String envKey = "%" + varKey.toUpperCase() + "%";
String var = this.evalEnv(envKey);
if (StringUtils.isBlank(var) && StringUtils.isNotBlank(varDefault)) {
var = varDefault;
}
if (envKey.equalsIgnoreCase(var)) {
return envKey;
} else {
return var;
}
}).parse(evalString);
if (!evalString.equalsIgnoreCase(newEvalString)) {
logger.debug("replace settingValue '" + evalString + "' to '" + newEvalString + "'.");
}
return newEvalString;
}
private String evalEnv(String evalString) {
if (StringUtils.isBlank(evalString)) {
return "";
}
Pattern keyPattern = Pattern.compile("(?:%([\\w\\._-]+)%){1,1}");// (?:%([\w\._-]+)%)
Matcher keyM = keyPattern.matcher(evalString);
Map data = new HashMap<>();
Map envMap = this.envMap();
while (keyM.find()) {
String varKeyOri = keyM.group(1);
String keyName = "%" + varKeyOri + "%";
String var = envMap.get(varKeyOri.toUpperCase());
if (var == null) {
data.put(keyName, "");
} else {
data.put(keyName, evalEnv(var));
}
}
String newEvalString = evalString;
for (String key : data.keySet()) {
newEvalString = newEvalString.replace(key, data.get(key));
}
logger.debug("evalString '" + evalString + "' eval to '" + newEvalString + "'.");
return newEvalString;
}
/** 获取可用的命名空间 */
public String[] getSettingArray() {
Set nsSet = this.allSettingValue().keySet();
return nsSet.toArray(new String[0]);
}
protected boolean isNsView() {
return false;
}
/** 获取指在某个特定命名空间下的Settings接口对象 */
public final BasicSettings getSettings(final String namespace) {
final Map localData = Collections.unmodifiableMap(new HashMap() {{
put(namespace, allSettingValue().get(namespace));
}});
return new BasicSettings() {
public Map allSettingValue() {
return localData;
}
protected boolean isNsView() {
return true;
}
};
}
/** 将整个配置项的多个值全部删除 */
public void removeSetting(String key) {
if (StringUtils.isBlank(key)) {
throw new IllegalArgumentException("namespace or key is blank.");
}
String lowerCaseKey = key.trim();
for (TreeNode treeNode : this.allSettingValue().values()) {
treeNode.findClear(lowerCaseKey);
}
}
/** 将整个配置项的多个值全部删除 */
public void removeSetting(String key, String namespace) {
if (StringUtils.isBlank(namespace) || StringUtils.isBlank(key)) {
throw new IllegalArgumentException("namespace or key is blank.");
}
TreeNode treeNode = this.allSettingValue().get(namespace);
if (treeNode != null) {
treeNode.findClear(key.trim());
}
}
/** 设置参数,如果出现多个值,则会覆盖 */
public void setSetting(String key, Object value, String namespace) {
if (StringUtils.isBlank(namespace) || StringUtils.isBlank(key)) {
throw new IllegalArgumentException("namespace or key is blank.");
}
Map treeNodeMap = this.allSettingValue();
TreeNode dataNode = treeNodeMap.get(namespace);
if (dataNode == null) {
if (isNsView()) {
throw new IllegalStateException("namespace view mode, cannot be added new namespace.");
}
dataNode = new TreeNode("", namespace);
treeNodeMap.put(namespace, dataNode);
}
if (value instanceof SettingNode) {
SettingNode node = (SettingNode) value;
dataNode.setNode(key.trim(), node);
} else {
String valueStr = (value == null) ? null : value.toString();
dataNode.setValue(key.trim(), valueStr);
}
}
/** 添加参数,如果参数名称相同则追加一项 */
public void addSetting(String key, Object value, String namespace) {
if (StringUtils.isBlank(key)) {
throw new IllegalArgumentException("key is blank.");
}
if (StringUtils.isBlank(namespace)) {
namespace = Settings.DefaultNameSpace;
}
Map treeNodeMap = this.allSettingValue();
TreeNode dataNode = treeNodeMap.get(namespace);
if (dataNode == null) {
if (isNsView()) {
throw new IllegalStateException("namespace view mode, cannot be added new namespace.");
}
dataNode = new TreeNode("", namespace);
treeNodeMap.put(namespace, dataNode);
}
if (value instanceof SettingNode) {
SettingNode node = (SettingNode) value;
dataNode.addNode(key.trim(), node);
} else {
String valueStr = (value == null) ? null : value.toString();
dataNode.addValue(key.trim(), valueStr);
}
}
protected SettingNode[] findSettingValue(String name) {
if (StringUtils.isBlank(name)) {
return new SettingNode[0];
}
List dataNodeList = new ArrayList<>();
String lowerCase = name.trim();
for (TreeNode dataNode : this.allSettingValue().values()) {
List treeNodeList = dataNode.findNodes(lowerCase);
if (treeNodeList != null) {
treeNodeList.forEach(settingNode -> {
if (!settingNode.isEmpty()) {
dataNodeList.add(settingNode);
}
});
}
}
if (dataNodeList.isEmpty()) {
return new SettingNode[0];
}
// 排序 DefaultNameSpace 放到最后,同时 getToType 会取最后一条,相同命名空间的数据 add 最后一条要优先前面的。
// 因此只能通过排序放到最后。否则无法满足当 不同命名空间空间下 DefaultNameSpace 有两条数据情况下 DefaultNameSpace 中最后一条优先的要求。
dataNodeList.sort((o1, o2) -> {
int o1Index = DefaultNameSpace.equalsIgnoreCase(o1.getSpace()) ? 0 : -1;
int o2Index = DefaultNameSpace.equalsIgnoreCase(o2.getSpace()) ? 0 : -1;
return Integer.compare(o1Index, o2Index);
});
return dataNodeList.toArray(new SettingNode[0]);
}
protected T convertTo(Object oriObject, final Class toType, final T defaultValue) {
// .获取不到数据,使用默认值替代
if (oriObject == null) {
if (defaultValue != null) {
return defaultValue;
} else {
return (T) BeanUtils.getDefaultValue(toType);
}
}
// .如果数据就是目标需要的类型那么就直接返回
if (toType.isInstance(oriObject)) {
return (T) oriObject;
}
// .转换类型
return (T) ConverterUtils.convert(toType, oriObject);
}
/** 解析全局配置参数,并且返回toType参数指定的类型。 */
public final T getToType(final String name, final Class toType, final T defaultValue) {
SettingNode[] settingVar = this.findSettingValue(name);
if (settingVar == null || settingVar.length == 0) {
return defaultValue;
}
if (settingVar.length == 0) {
return null;
}
if (SettingNode.class == toType || TreeNode.class == toType) {
return (T) settingVar[settingVar.length - 1];
} else {
return convertTo(settingVar[settingVar.length - 1].getValue(), toType, defaultValue);
}
}
public T[] getToTypeArray(final String name, final Class toType, final T defaultValue) {
SettingNode[] varArrays = this.findSettingValue(name);
if (varArrays == null) {
return (T[]) Array.newInstance(toType, 0);
}
if (SettingNode.class == toType || TreeNode.class == toType) {
return (T[]) varArrays;
}
List targetObjects = new ArrayList<>();
for (SettingNode var : varArrays) {
for (String item : var.getValues()) {
T finalItem = convertTo(item, toType, defaultValue);
targetObjects.add(finalItem);
}
}
return targetObjects.toArray((T[]) Array.newInstance(toType, targetObjects.size()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy