com.anysoft.util.Properties Maven / Gradle / Ivy
package com.anysoft.util;
import java.util.*;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.anysoft.formula.DataProvider;
/**
* 变量集
* @author duanyy
*
* @version 1.2.3 [20140725 duanyy]
* - 增加loadFromString
*
* @version 1.6.1.1 [20141118 duanyy]
* - 实现DataProvider接口
*
* @version 1.6.3.30 [20150714 duanyy]
* - 修正缺省值为null的空指针问题
*
* @version 1.6.4.43 [20160411 duanyy]
* - DataProvider增加获取原始值接口
*
* @version 1.6.7.7 [20170126 duanyy]
* - 增加loadFrom系列方法,用于从Json对象,Element节点,Element属性列表中装入变量列表
*
* @version 1.6.8.10 [20170418 duanyy]
* - 在装入xml配置文件时,可从env中获取变量
*
*/
abstract public class Properties implements DataProvider{
/**
* logger of log4j
*/
protected static Logger logger = LoggerFactory.getLogger(Properties.class);
/**
* 变量域
*/
protected String domain = "Default";
/**
* 父节点
*/
protected Properties parent = null;
/**
* 变量开始字符
*/
public static final String VariableStart = "${";
/**
* 变量结束字符
*/
public static final String VariableEnd = "}";
/**
* 构造函数
* @param _domain 变量域
* @param _parent 父节点
*/
public Properties(String _domain,Properties _parent){
domain = _domain;
parent = _parent;
}
/**
* 构造函数
* @param _domain 变量域
* @see #Properties(String, Properties)
*/
public Properties(String _domain){
this(_domain,null);
}
/**
* 构造函数
*/
public Properties(){
this("Default",null);
}
/**
* 获取变量域
* @return domain
*/
public String getDomain(){
return domain;
}
/**
* 设置变量域
* @param _domain
*/
public void setDomain(String _domain){
domain = _domain;
}
/**
* 设置变量集的父节点
* @param _parent 父节点
*/
public Properties PutParent(Properties _parent){
Properties temp = parent;
parent = _parent;
return temp;
}
/**
* 利用变量集变量来计算给定字符串
* @param pattern 字符串
* @return 计算后的字符串
*/
public String transform(String pattern){
return FillValue("",pattern);
}
/**
* 从字符串装入变量
*
* 从一个字符串装入变量,字符串的语法如下:
* var1=val1;var2=val2
* 从上面的字符串中可以解析出2个变量:var1和var2,其取值分别是val1和val2
*/
public void loadFromString(String _para){
loadFromString(_para,";","=");
}
/**
* 从字符串装入变量
* @param _para 字符串
* @param delimeter1 间隔符
* @param delimeter2 间隔符
*
* @since 1.2.3
*/
public void loadFromString(String _para,String delimeter1,String delimeter2){
StringTokenizer __t = new StringTokenizer(_para,delimeter1);
while (__t.hasMoreTokens()) {
String __pair = __t.nextToken();
int __index = __pair.indexOf(delimeter2);
if (__index < 0){
continue;
}
String __name = __pair.substring(0,__index);
String __value = __pair.substring(__index + 1,__pair.length());
SetValue(__name,__value);
}
}
/**
* 从JSON对象的属性列表中装入
* @param json Json对象
*
* @since 1.6.7.7
*/
public void loadFrom(Map json){
Iterator> iter = json.entrySet().iterator();
while (iter.hasNext()){
Entry entry = iter.next();
String key = entry.getKey();
Object value = entry.getValue();
if (value instanceof String || value instanceof Number){
SetValue(key,value.toString());
}
}
}
/**
* 从Element节点的属性列表中装入
* @param elem Element节点
*
* @since 1.6.7.7
*/
public void loadFromElementAttrs(Element elem){
if (elem != null){
NamedNodeMap attrs = elem.getAttributes();
for (int i = 0 ;i < attrs.getLength() ; i ++){
Node n = attrs.item(i);
if (Node.ATTRIBUTE_NODE != n.getNodeType()){
continue;
}
Attr attr = (Attr)n;
String key = attr.getName();
String value = attr.getValue();
if (StringUtils.isNotEmpty(key) && StringUtils.isNotEmpty(value)){
SetValue(key,value);
}
}
}
}
/**
* 从Element中装入
* @param root Element节点
*
* @since 1.6.7.7
*/
public void loadFrom(Element root){
NodeList nodeList = root.getChildNodes();
for (int i = 0 ; i < nodeList.getLength() ; i ++){
Node node = nodeList.item(i);
if (node.getNodeType() != Node.ELEMENT_NODE){
continue;
}
if ("parameter".equals(node.getNodeName())){
Element e = (Element)node;
String id = XmlTools.getString(e,"id","");
String value = XmlTools.getString(e,"value","");
if (StringUtils.isEmpty(id)){
continue;
}
if (StringUtils.isNotEmpty(value)){
boolean fromEnv = XmlTools.getBoolean(e, "fromEnv", false);
if (fromEnv){
value = System.getenv(value);
if (StringUtils.isEmpty(value)){
value = XmlTools.getString(e, "dft", "");
}
}else{
boolean fromProperties = XmlTools.getBoolean(e, "fromProperties", false);
if (fromProperties){
value = System.getProperty(value);
if (StringUtils.isEmpty(value)){
value = XmlTools.getString(e, "dft", "");
}
}
}
}
//支持final标示,如果final为true,则不覆盖原有的取值
boolean isFinal = XmlTools.getBoolean(e, "final", false);
if (isFinal){
String oldValue = GetValue(id, "", false,false);
if (StringUtils.isEmpty(oldValue)){
SetValue(id,value);
boolean system = XmlTools.getBoolean(e, "system", false);
if (system){
System.setProperty(id, value);
logger.info(String.format("Set system property:%s=%s", id,value));
}
}
}else{
SetValue(id,value);
boolean system = XmlTools.getBoolean(e, "system", false);
if (system){
System.setProperty(id, value);
logger.info(String.format("Set system property:%s=%s", id,value));
}
}
}
}
}
/**
* 设置变量
* @param _name 变量名
* @param _value 变量值
*/
public void SetValue(String _name,String _value){
_SetValue(_name,_value);
}
/**
* 获取变量值
* @param _name 变量名
* @param _defaultValue 缺省值
* @param _bVariable 是否计算变量
* @param _bNoParent 是否取父节点的变量
* @return 变量值
*/
public String GetValue(String _name,String _defaultValue,boolean _bVariable,boolean _bNoParent){
String __value;
__value = _GetValue(_name);
if (__value == null || __value.length() <= 0){
//在本变量集没有找到
if (parent != null && !_bNoParent){
//定义了父节点
__value = parent.GetValue(_name,_defaultValue,false,false);
if (__value == _defaultValue){
//没有找到,尝试采用parent.模式
int __index = _name.indexOf("parent.");
if (__index == 0){
__value = parent.GetValue(
_name.substring(7),
_defaultValue,
false,
false
);
}
}
}
else{
__value = _defaultValue;
}
}
//在本变量集找到
if (_bVariable && __value != null && __value.length() > 0){
//计算变量
__value = FillValue(_name,__value);
}
return __value;
}
/**
* 进行变量填充式计算
* @param _name 最初的变量名
* @param _value 计算的原始值
* @return 计算后的取值
*/
public String FillValue(String _name,String _value){
int __startIndex = _value.indexOf(VariableStart);
if (__startIndex < 0){
//没有找到变量
return _value;
}
//在变量之前的字符串
String __tmpValue = _value.substring(0,__startIndex);
int __endIndex = _value.indexOf(VariableEnd,__startIndex + VariableStart.length());
if (__endIndex < 0){
//没有发现变量结束符
return __tmpValue;
}
//变量名
String __varName = _value.substring(
__startIndex + VariableStart.length(),
__endIndex - VariableStart.length() + VariableStart.length()
);
//在变量之后的字符串
String __afterValue = _value.substring(__endIndex + VariableEnd.length());
//取变量的值
String __varValue;
if (!__varName.equals(_name)){
__varValue = GetValue(__varName,"",false,false);
if (__varValue.length() >= 0){
__tmpValue += __varValue;
}
__tmpValue += __afterValue;
return FillValue(_name,__tmpValue);
}
return __tmpValue;
}
/**
* 获取变量值
* @param _name 变量名
* @param _defaultValue 缺省值
* @param _bVariable 是否计算变量
* @return 变量值
*/
public String GetValue(String _name,String _defaultValue,boolean _bVariable){
return GetValue(_name,_defaultValue,_bVariable,false);
}
/**
* 获取变量值
* @param _name 变量名
* @param _defaultValue 缺省值
* @return 变量值
*/
public String GetValue(String _name,String _defaultValue){
return GetValue(_name,_defaultValue,true,false);
}
/**
* 设置变量
* @param _name 变量名
* @param _value 变量值
*/
abstract protected void _SetValue(String _name,String _value);
/**
* 获取变量
* @param _name 变量名
* @return 变量值
*/
abstract protected String _GetValue(String _name);
/**
* 清楚变量
*/
abstract public void Clear();
public String getValue(String varName, Object context, String defaultValue) {
return GetValue(varName, defaultValue);
}
public Object getContext(String varName) {
return cookies;
}
@Override
public String getRawValue(String varName, Object context, String dftValue) {
return GetValue(varName,dftValue,false,false);
}
protected static Object cookies = new Object();
}