package com.walker.infrastructure.arguments;
|
|
import com.walker.infrastructure.arguments.support.DefaultVariable;
|
import com.walker.infrastructure.utils.StringUtils;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.Iterator;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.TreeMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
|
/**
|
* 抽象的参数管理器实现。
|
* @author shikeying
|
*
|
*/
|
public abstract class AbstractArgumentsManager implements ArgumentsManager {
|
|
protected Logger logger = LoggerFactory.getLogger(getClass());
|
|
private Object source;
|
|
/* 分组集合 */
|
private Map<String, Group> groupMap = new TreeMap<String, Group>();
|
|
/* 变量集合与组ID映射关系:key=groupId, value=variable ID set */
|
private ConcurrentHashMap<String, List<String>> variableMap = new ConcurrentHashMap<String, List<String>>(8);
|
|
private ConcurrentHashMap<String, Variable> allVars = new ConcurrentHashMap<String, Variable>(32);
|
|
private Object lock = new Object();
|
|
@Override
|
public void setSource(Object source){
|
assert (source != null);
|
this.source = source;
|
}
|
|
@Override
|
public void afterPropertiesSet() throws Exception{
|
// if(this.source == null){
|
// throw new ArgumentsException("parameter: source is not found!");
|
// }
|
|
List<Group> groupList = null;
|
|
try{
|
groupList = load(source);
|
} catch(Exception ex){
|
throw new ArgumentsException("业务加载配置参数失败:" + ex.getMessage(), ex);
|
}
|
|
initGroup(groupList);
|
|
if(logger.isDebugEnabled()){
|
logger.debug("~~~~~~~~~~~~~~~~~ 系统加载所有配置参数-start ~~~~~~~~~~~~~~~~~");
|
for(Variable v : allVars.values()){
|
logger.debug(v.toString());
|
}
|
logger.debug("~~~~~~~~~~~~~~~~~ 系统加载所有配置参数-end ~~~~~~~~~~~~~~~~~");
|
}
|
}
|
|
private void initGroup(List<Group> groupList){
|
if(groupList != null){
|
Collections.sort(groupList);
|
for(Group g : groupList){
|
groupMap.put(g.getId(), g);
|
initVariableInGroup(g);
|
}
|
}
|
}
|
|
private void initVariableInGroup(Group group){
|
List<Variable> varList = group.getChildren();
|
if(varList != null && varList.size() > 0){
|
List<String> varIds = new ArrayList<String>(8);
|
for(Variable v : varList){
|
allVars.put(v.getId(), v);
|
varIds.add(v.getId());
|
}
|
variableMap.put(group.getId(), varIds);
|
} else
|
variableMap.put(group.getId(), null);
|
}
|
|
/**
|
* 加载具体的参数数据,并返回分组集合信息,分组中包含了可变参数数据。</p>
|
* 子类实现具体加载过程。
|
* @param source 输入参数,由业务设置加载数据的原始参数,如:xml文件、数据源等。
|
* @return
|
*/
|
protected abstract List<Group> load(Object source) throws Exception;
|
|
/**
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
*
|
* 以下为系统提供的标准API
|
*
|
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
*/
|
|
@Override
|
public Variable getVariable(String id) {
|
assert (StringUtils.isNotEmpty(id));
|
Variable var = allVars.get(id);
|
if(var == null)
|
throw new ElementNotFoundException("variable not found: " + id);
|
return var;
|
}
|
|
@Override
|
public void persist(String variableId, Object value) {
|
if(groupMap.size() > 1)
|
throw new ArgumentsException("存在多个分组,请调用方法: persist(String groupId, String variableId, Object value)");
|
String groupId = groupMap.keySet().iterator().next();
|
persist(groupId, variableId, value);
|
}
|
|
@Override
|
public void persist(String groupId, String variableId, Object value) {
|
assert (StringUtils.isNotEmpty(groupId));
|
assert (value != null);
|
|
/* 更新实体中的数据 */
|
try {
|
saveVariable(groupId, variableId, value);
|
} catch (Exception e) {
|
throw new ArgumentsException("更新可变参数到业务中出现错误: " + e.getMessage(), e);
|
}
|
|
synchronized (lock) {
|
updateCache(groupId, variableId, value);
|
}
|
}
|
|
private void updateCache(String groupId, String variableId, Object value){
|
if(groupMap.get(groupId) == null)
|
throw new IllegalArgumentException("not found group id: " + groupId);
|
List<String> existVarSet = variableMap.get(groupId);
|
if(existVarSet == null)
|
throw new ArgumentsException("not found variable in cache: " + variableId);
|
if(existVarSet.contains(variableId)){
|
// 暂时先强制转换成具体对象,调用更改值的方法,后续扩充时需要注意,可能会不合适。
|
DefaultVariable current = (DefaultVariable)allVars.get(variableId);
|
current.setValue(value);
|
} else
|
throw new ElementNotFoundException("var id: " + variableId);
|
}
|
|
@Override
|
public void persist(List<Object[]> changedList){
|
if(changedList == null) return;
|
for(Object[] arr : changedList){
|
if(arr.length != 3)
|
throw new IllegalArgumentException("输入参数不正确,集合中为数组,每个数组需要三个元素: groupId, variableId, value.");
|
if(StringUtils.isEmpty(arr[0].toString()))
|
throw new IllegalArgumentException("第一个参数:groupId不存在或者是空值");
|
if(StringUtils.isEmpty(arr[1].toString()))
|
throw new IllegalArgumentException("第二个参数:variableId不存在或者是空值");
|
if(arr[2] == null)
|
throw new IllegalArgumentException("第三个参数:value不存在或者是空值");
|
}
|
|
/* 更新实体中的数据 */
|
try {
|
saveVariables(changedList);
|
} catch (Exception e) {
|
throw new ArgumentsException("更新可变参数到业务中出现错误: " + e.getMessage(), e);
|
}
|
|
synchronized (lock){
|
for(Object[] args : changedList){
|
updateCache(args[0].toString(), args[1].toString(), args[2]);
|
}
|
}
|
}
|
|
@Override
|
public void insert(List<Object[]> insertList) {
|
if(insertList == null) return;
|
for(Object[] arr : insertList){
|
if(arr.length != 2)
|
throw new IllegalArgumentException("输入参数不正确,集合中为数组,每个数组需要两个元素: group, variable.");
|
if(StringUtils.isEmpty(arr[0].toString()))
|
throw new IllegalArgumentException("第一个参数:group不存在或者是空值");
|
if(StringUtils.isEmpty(arr[1].toString()))
|
throw new IllegalArgumentException("第二个参数:variable不存在或者是空值");
|
}
|
/* 更新实体中的数据 */
|
try {
|
insertVariables(insertList);
|
} catch (Exception e) {
|
throw new ArgumentsException("新建可变参数出现错误: " + e.getMessage(), e);
|
}
|
|
synchronized (lock){
|
for(Object[] args : insertList){
|
insertCache((Group)args[0], (Variable)args[1]);
|
}
|
}
|
}
|
|
/**
|
* 由子类来实现具体的更新介质中的参数,如:数据库、配置文件等。
|
* @param groupId 分组ID
|
* @param variableId 可变参数ID
|
* @param value 更新的值
|
* @throws Exception
|
*/
|
protected abstract void saveVariable(String groupId
|
, String variableId, Object value) throws Exception;
|
|
/**
|
* 子类实现持久化更新参数信息到介质中,如:数据库、配置文件等。</p>
|
* 批量更新方法,集合中是数组对象,Object[]{groupId, variableId, value}</br>
|
* 即:分组ID、可变参数ID、更新的值。
|
* @param changedList 需要更新的参数集合。
|
* @throws Exception
|
*/
|
protected abstract void saveVariables(List<Object[]> changedList) throws Exception;
|
|
/**
|
* 加入新的参数集合,集合中是数组对象,Object[]{group, variable}
|
* 如果已经存在该参数,则不再创建。
|
* @param insertList
|
* @throws Exception
|
*/
|
protected abstract void insertVariables(List<Object[]> insertList) throws Exception;
|
|
private void insertCache(Group group, Variable variable){
|
assert (group != null);
|
assert (variable != null);
|
if(!groupMap.containsKey(group.getId())){
|
groupMap.put(group.getId(), group);
|
}
|
if(!allVars.containsKey(variable.getId())){
|
// 不包含才加入到缓存
|
allVars.put(variable.getId(), variable);
|
List<String> varList = variableMap.get(group.getId());
|
if(varList == null){
|
varList = new ArrayList<String>(2);
|
variableMap.put(group.getId(), varList);
|
}
|
varList.add(variable.getId());
|
}
|
}
|
|
@Override
|
public List<Group> getGroupList() {
|
if(groupMap.size() == 0) return null;
|
List<Group> list = new ArrayList<Group>(8);
|
for(Iterator<Group> it = groupMap.values().iterator(); it.hasNext();){
|
list.add(it.next());
|
}
|
Collections.sort(list);
|
return list;
|
}
|
|
@Override
|
public List<Variable> getVariableList(String groupId) {
|
assert (StringUtils.isNotEmpty(groupId));
|
if(groupMap.size() == 0){
|
return null;
|
}
|
List<String> varIds = variableMap.get(groupId);
|
if(varIds == null)
|
return null;
|
|
List<Variable> result = new ArrayList<Variable>(8);
|
Variable var = null;
|
for(String vid : varIds){
|
var = allVars.get(vid);
|
if(var == null) throw new ElementNotFoundException("var id: " + vid);
|
result.add(var);
|
}
|
return result;
|
}
|
|
@Override
|
public void destroy() throws Exception{
|
this.source = null;
|
this.groupMap.clear();
|
this.variableMap.clear();
|
this.allVars.clear();
|
}
|
}
|