/*
* 文件名称: DefaultUConfig.java
* 版权信息: Copyright 2001-2011 ZheJiang Collaboration Data System Co., LTD. All right reserved.
* ----------------------------------------------------------------------------------------------
* 修改历史:
* ----------------------------------------------------------------------------------------------
* 修改原因: 新增
* 修改人员: LuoJingtian
* 修改日期: 2011-12-19
* 修改内容:
*/
package com.mfh.comna.comn.cfg;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import com.mfh.comn.config.ConfigItem;
import com.mfh.comn.config.ConfigLocationItem;
import com.mfh.comn.config.IConfiguration;
import com.mfh.comn.config.SingleConfiguration;
import com.mfh.comn.config.UConfig;
import com.mfh.comn.utils.W3cDomUtils;
/**
* 默认统一配置实现.
* @author <a href="mailto:luojt@zjcds.com">LuoJingtian</a> created on 2011-12-19
* @since chch Framework 1.0
*/
public class DefaultUConfig implements UConfig {
/** 统一配置项信息 */
private ConfigItem configItem;
/**
* 合并规则
* @see {@link com.mfh.comn.config.UConfig.MergeRule }
* @see {@link com.mfh.comn.config.UConfig.MergeRuleName }
*/
private int mergeRule;
/** 当指定合并规则为:merge时, 可以返回合并后的Document */
private Document mergeDoc;
/** 日志记录器 */
private static org.slf4j.Logger logger = LoggerFactory.getLogger(DefaultUConfig.class);
/** 统一配置项 */
private List<SingleConfiguration> compositeConfig = new ArrayList<SingleConfiguration>();
private boolean isNotEmpty(List<?> collections) {
if (collections != null && collections.size() > 0)
return true;
else
return false;
}
/**
* 从指定的配置项初始化一个1+N组合配置
* @author LuoJingtian created on 2011-12-20
* @since chch Framework 1.0
*/
@Override
public void init(ConfigItem configItem, Map<String, Class<SingleConfiguration>> configClass) {
this.configItem = configItem;
// 校验统一配置项是否配置正确
checkConfigItem();
try {
switch (mergeRule) {
case MergeRule.ORDER: {// 顺序: 按照1+N定义顺序找到第一个配置就直接返回
SingleConfiguration defaultConfig = getConfiguration(configItem.getDefaultLocation(), configClass);
if (defaultConfig != null) {
compositeConfig.add(defaultConfig);
}
List<SingleConfiguration> extendsConfigs = getConfigurations(configItem.getExtendsLocations(), configClass);
addConfigrations(extendsConfigs);
break;
}
case MergeRule.MERGE: { // 合并, 按照定义顺序添加配置, 找到第一个配置就直接返回
SingleConfiguration defaultConfig = getConfiguration(configItem.getDefaultLocation(), configClass);
if (defaultConfig != null) {
compositeConfig.add(defaultConfig);
}
List<SingleConfiguration> extendsConfigs = getConfigurations(configItem.getExtendsLocations(), configClass);
addConfigrations(extendsConfigs);
if (defaultConfig instanceof XMLConfiguration) {
XMLConfiguration defaultXmlConfig = (XMLConfiguration)defaultConfig;
Document defaultDoc = defaultXmlConfig.getDocument();
XMLConfiguration extendsXmlConfig;
for (SingleConfiguration item :extendsConfigs) {
extendsXmlConfig = (XMLConfiguration)item;
W3cDomUtils.copy(extendsXmlConfig.getDocument(), defaultDoc);
}
/*XMLConfiguration mergeXmlConfig = new XMLConfiguration();
mergeXmlConfig.load(new InputStreamReader(new ByteArrayInputStream(W3cDomUtils.toXmlString(
defaultDoc).getBytes(charset)), charset));
mergeDoc = mergeXmlConfig.getDocument();
compositeConfig.add(mergeXmlConfig);*/
mergeDoc = defaultDoc;
}
break;
}
case MergeRule.REPLACE: // 替换: 以后面的N配置替换前面的N(或1)配置, 优先读取最后的配置
default: {//默认规则与替换规则相同
SingleConfiguration defaultConfig = getConfiguration(configItem.getDefaultLocation(), configClass);
try {
if (defaultConfig == null) {
logger.warn("配置文件" + configItem.getDefaultLocation().getLocation() + "读取失败!");
break;
}
List<ConfigLocationItem> configLocationItems = configItem.getExtendsLocations();
List<SingleConfiguration> extendsConfigs = new ArrayList<SingleConfiguration>();
if (isNotEmpty(configLocationItems)) {
SingleConfiguration firstOk = defaultConfig;
for (ConfigLocationItem configLocationItem : configLocationItems) {
SingleConfiguration cfg = getConfiguration(configLocationItem, configClass);
if (cfg != null) {
extendsConfigs.add(cfg);
// if (cfg.isEmpty()) {//把上一个好的的拷贝进来
// InputStream defaultIn = firstOk.getReadStream();
// File out = cfg.getWriteAbleFile();
// if (out.exists() == false) {
// if (out.getParentFile().exists() == false)
// out.getParentFile().mkdirs();
// out.createNewFile();
// }
// IOUtils.copy(defaultIn, out);
// cfg.refresh();
// }
// else
// firstOk = cfg;
}
}
}
Collections.reverse(extendsConfigs);
addConfigrations(extendsConfigs);
}
catch(Exception ex) {
logger.warn("读取扩展规则失败:" + ex.getMessage() + ";原因是:" + ex.getCause().getMessage());
}
if (defaultConfig != null) {
compositeConfig.add(defaultConfig);
}
}
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 校验配置项
* @author LuoJingtian created on 2011-12-21
* @since chch Framework 1.0
*/
private void checkConfigItem() {
if (configItem == null) {
String errMsg = "读取的配置项不能为空.";
logger.warn(errMsg);
throw new RuntimeException(errMsg);
}
if (StringUtils.isBlank(configItem.getDomain())) {
String errMsg = "读取的配置项Domain不能为空.";
logger.warn(errMsg);
throw new RuntimeException(errMsg);
}
checkConfigLocationItem();
}
/**
* 校验配置位置项
* @author LuoJingtian created on 2011-12-21
* @since chch Framework 1.0
*/
private void checkConfigLocationItem() {
this.mergeRule = handleMergeRule(configItem.getMergeRule());
// 校验默认配置位置项: 必须指定默认配置位置项
if (configItem.getDefaultLocation() == null) {
String errMsg = "配置错误:" + configItem.getDomain() + "未指定默认配置位置.";
logger.warn(errMsg);
throw new RuntimeException(errMsg);
}
// 校验扩展位置配置项: 对合并规则, type必须全部为xml
if (mergeRule == MergeRule.MERGE) {
List<ConfigLocationItem> extendsConfLocationItems = configItem.getExtendsLocations();
if (isNotEmpty(extendsConfLocationItems)) {
for (ConfigLocationItem extendsConfLocationItem : extendsConfLocationItems) {
if (!MergeTypeName.XML.equalsIgnoreCase(extendsConfLocationItem.getType())) {
String errMsg = "配置错误:" + configItem.getDomain()
+ "指定合并规则为[merge]时, default 和 extends 配置必须同时为xml或者同时为properties.";
logger.warn(errMsg);
throw new RuntimeException(errMsg);
}
}
}
}
}
/**
* 对配置文件中给定的1+N配置项合并规则做映射
* @param mergeRule 配置文件中给定的1+N配置项合并规则
* @return 映射后的配置项合并规则
* @author LuoJingtian created on 2011-12-21
* @since chch Framework 1.0
*/
private int handleMergeRule(String mergeRule) {
// 默认即为替换方式, 以最后一个N配置extends location为准
if (MergeRuleName.DEFAULT.equalsIgnoreCase(mergeRule) || MergeRuleName.REPLACE.equalsIgnoreCase(mergeRule)) {
return MergeRule.REPLACE;
}
// 排序方式优先使用default location的配置
else if (MergeRuleName.ORDER.equalsIgnoreCase(mergeRule)) {
return MergeRule.ORDER;
}
// 合并方式对所有配置做合并, XML(体现为Document节点合并)和properties合并后读取到的是一个列表
else if (MergeRuleName.MERGE.equalsIgnoreCase(mergeRule)) {
return MergeRule.MERGE;
}
else {
return MergeRule.REPLACE;
}
}
/**
* 添加Configuration 到
* @param extendsConfigs
* @author LuoJingtian created on 2011-12-19
* @since chch Framework 1.0
*/
private void addConfigrations(List<SingleConfiguration> extendsConfigs) {
for(SingleConfiguration extendsConfiguration : extendsConfigs) {
if (extendsConfiguration != null) {
compositeConfig.add(extendsConfiguration);
}
}
}
/**
* 从指定配置位置项列表获取所有配置接口
* @param configLocationItems 配置位置项列表
* @return 所有配置接口
* @author LuoJingtian created on 2011-12-19
* @since chch Framework 1.0
*/
private List<SingleConfiguration> getConfigurations(List<ConfigLocationItem> configLocationItems,
Map<String, Class<SingleConfiguration>> configClass)
throws Exception {
List<SingleConfiguration> configurationList = new ArrayList<SingleConfiguration>();
if (isNotEmpty(configLocationItems)) {
for (ConfigLocationItem configLocationItem : configLocationItems) {
configurationList.add(getConfiguration(configLocationItem, configClass));
}
}
return configurationList;
}
/**
* 从指定配置位置项获取一个配置接口
* @param configLocationItem 配置位置项
* @return 配置接口
* @author LuoJingtian created on 2011-12-19
* @since chch Framework 1.0
*/
private SingleConfiguration getConfiguration(ConfigLocationItem configLocationItem,
Map<String, Class<SingleConfiguration>> configClass){
if (configLocationItem != null) {
String type = configLocationItem.getType();
Class<SingleConfiguration> classItem = configClass.get(type);
if (classItem == null)
throw new RuntimeException("指定类型" + type + "的配置文件没有定义实现类!");
try {
SingleConfiguration cItem = null;
cItem = classItem.newInstance();
String configLocation = configLocationItem.getLocation();
// 按照Spring习惯配置的路径在非WEB环境做路径兼容处理
configLocation = handlePath(configLocation);
logger.info("尝试读取以下路径的资源:" + configLocation);
cItem.loadFromFile(configLocation);
return cItem;
}
catch(Exception ex) {
logger.error("尝试读取配置失败:" + configLocationItem.getLocation());
throw new RuntimeException("尝试读取配置失败:" + configLocationItem.getLocation(), ex);
}
}
return null;
}
private static String handlePath(String configLocation) {
return configLocation;
}
@Override
public Document getMergeDocument() {
if (mergeRule == MergeRule.MERGE) {
//其实本类不支持此方法。
return mergeDoc;
}
return null;
}
// -------------------------------- 以下为Override方法 -------------------------------- //
/**
* 是否替换方案
* @return
* @author zhangyz created on 2013-5-26
*/
private boolean isReplace() {
return this.mergeRule == MergeRule.REPLACE || this.mergeRule == MergeRule.DEFAULT;
}
/**
* 是否合并方案
* @return
* @author zhangyz created on 2013-5-26
*/
private boolean isMerge() {
return this.mergeRule == MergeRule.MERGE;
}
@Override
public void clear() {
if (isReplace())
compositeConfig.get(0).clear();
else if (isMerge()) {
for (IConfiguration item : compositeConfig)
item.clear();
}
else
compositeConfig.get(0).clear();
}
@Override
public void clearProperty(String key) {
if (isReplace())
compositeConfig.get(0).clearProperty(key);
else if (isMerge()) {
for (IConfiguration item : compositeConfig)
item.clearProperty(key);
}
else
compositeConfig.get(0).clearProperty(key);
}
@Override
public void commitWrite(){
if (isReplace())
compositeConfig.get(0).commitWrite();
else {
for (IConfiguration item : compositeConfig)
item.commitWrite();
}
}
@Override
public boolean isEmpty() {
for (IConfiguration item : compositeConfig) {
if (!item.isEmpty())
return false;
}
return true;
}
@Override
public void addProperty(String key, Object defaultValue) {
if (compositeConfig.get(0).containsKey(key))
compositeConfig.get(0).setProperty(key, defaultValue);
else
compositeConfig.get(0).addProperty(key, defaultValue);
}
@Override
public void setProperty(String key, Object value) {
if (this.isReplace() || this.isMerge()) {
if (compositeConfig.get(0).containsKey(key))
compositeConfig.get(0).setProperty(key, value);
else
compositeConfig.get(0).addProperty(key, value);
}
else {
boolean bFind = false;
for (IConfiguration item : compositeConfig) {
if (item.containsKey(key)) {
item.setProperty(key, value);
bFind = true;
break;
}
}
if (bFind) {
compositeConfig.get(0).addProperty(key, value);
}
}
}
@Override
public boolean containsKey(String key) {
for (IConfiguration item : compositeConfig) {
if (item.containsKey(key))
return true;
}
return false;
}
@Override
public BigDecimal getBigDecimal(String key) {
if (key == null)
return null;
BigDecimal ret;
for (IConfiguration item : compositeConfig) {
ret = item.getBigDecimal(key);
if (ret != null)
return ret;
}
return null;
}
@Override
public BigDecimal getBigDecimal(String key, BigDecimal defaultValue) {
if (key == null)
return defaultValue;
BigDecimal ret = getBigDecimal(key);
if (ret == null)
return defaultValue;
else
return ret;
}
@Override
public BigInteger getBigInteger(String key) {
if (key == null)
return null;
BigInteger ret;
for (IConfiguration item : compositeConfig) {
ret = item.getBigInteger(key);
if (ret != null)
return ret;
}
return null;
}
@Override
public BigInteger getBigInteger(String key, BigInteger defaultValue) {
if (key == null)
return defaultValue;
BigInteger ret = getBigInteger(key);
if (ret == null)
return defaultValue;
else
return ret;
}
@Override
public boolean getBoolean(String key) {
if (key == null)
return false;
Boolean ret;
for (IConfiguration item : compositeConfig) {
ret = item.getBoolean(key);
if (ret != null)
return ret;
}
return false;
}
@Override
public boolean getBoolean(String key, boolean defaultValue) {
if (key == null)
return defaultValue;
Boolean ret;
for (IConfiguration item : compositeConfig) {
ret = item.getBoolean(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Boolean getBoolean(String key, Boolean defaultValue) {
if (key == null)
return defaultValue;
Boolean ret;
for (IConfiguration item : compositeConfig) {
ret = item.getBoolean(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public byte getByte(String key) {
byte bb = 0;
return getByte(key, bb);
}
@Override
public byte getByte(String key, byte defaultValue) {
if (key == null)
return defaultValue;
Byte ret;
for (IConfiguration item : compositeConfig) {
ret = item.getByte(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Byte getByte(String key, Byte defaultValue) {
if (key == null)
return defaultValue;
Byte ret;
for (IConfiguration item : compositeConfig) {
ret = item.getByte(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public double getDouble(String key) {
return getDouble(key, 0);
}
@Override
public double getDouble(String key, double defaultValue) {
if (key == null)
return defaultValue;
Double ret;
for (IConfiguration item : compositeConfig) {
ret = item.getDouble(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Double getDouble(String key, Double defaultValue) {
if (key == null)
return defaultValue;
Double ret;
for (IConfiguration item : compositeConfig) {
ret = item.getDouble(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public float getFloat(String key) {
return getFloat(key, 0);
}
@Override
public float getFloat(String key, float defaultValue) {
if (key == null)
return defaultValue;
Float ret;
for (IConfiguration item : compositeConfig) {
ret = item.getFloat(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Float getFloat(String key, Float defaultValue) {
return compositeConfig.get(0).getFloat(key, defaultValue);
}
@Override
public int getInt(String key) {
return getInt(key ,0);
}
@Override
public int getInt(String key, int defaultValue) {
if (key == null)
return defaultValue;
Integer ret;
for (IConfiguration item : compositeConfig) {
ret = item.getInt(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Integer getInteger(String key, Integer defaultValue) {
return compositeConfig.get(0).getInteger(key, defaultValue);
}
@Override
public Iterator<?> getKeys() {
Iterator<?> ret;
for (IConfiguration item : compositeConfig) {
ret = item.getKeys();
if (ret != null)
return ret;
}
return null;
}
/*@Override
public Iterator<?> getKeys(String key) {
Iterator<?> ret;
for (Configuration item : compositeConfig) {
ret = item.getKeys(key);
if (ret != null)
return ret;
}
return null;
}*/
@Override
public List<?> getList(String key) {
List<?> ret;
for (IConfiguration item : compositeConfig) {
ret = item.getList(key);
if (ret != null)
return ret;
}
return null;
}
/*@SuppressWarnings("rawtypes")
@Override
public List<?> getList(String key, List defaultValue) {
List<?> ret;
for (IConfiguration item : compositeConfig) {
ret = item.getList(key);
if (ret != null)
return ret;
}
return defaultValue;
}*/
@Override
public long getLong(String key) {
return getLong(key, 0);
}
@Override
public long getLong(String key, long defaultValue) {
if (key == null)
return defaultValue;
Long ret;
for (IConfiguration item : compositeConfig) {
ret = item.getLong(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Long getLong(String key, Long defaultValue) {
if (key == null)
return defaultValue;
Long ret;
for (IConfiguration item : compositeConfig) {
ret = item.getLong(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Properties getProperties(String key) {
if (key == null)
return null;
Properties ret;
for (IConfiguration item : compositeConfig) {
ret = (Properties)item.getProperty(key);
if (ret != null)
return ret;
}
return null;
}
@Override
public Object getProperty(String key) {
if (key == null)
return null;
Object ret;
for (IConfiguration item : compositeConfig) {
ret = item.getProperty(key);
if (ret != null)
return ret;
}
return null;
}
@Override
public short getShort(String key) {
return this.getShort(key, (short)0);
}
@Override
public short getShort(String key, short defaultValue) {
if (key == null)
return defaultValue;
Short ret;
for (IConfiguration item : compositeConfig) {
ret = item.getShort(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public Short getShort(String key, Short defaultValue) {
if (key == null)
return defaultValue;
Short ret;
for (IConfiguration item : compositeConfig) {
ret = item.getShort(key);
if (ret != null)
return ret;
}
return defaultValue;
}
@Override
public String getString(String key) {
if (key == null)
return null;
String ret;
for (IConfiguration item : compositeConfig) {
ret = item.getString(key);
if (ret != null)
return ret;
}
return null;
}
@Override
public String getStringNotNull(String s) {
String ret = getString(s);
if (ret == null || ret.length() == 0)
throw new RuntimeException(s + "配置型不能为空!");
return ret;
}
@Override
public String getString(String key, String defaultValue) {
if (key == null)
return defaultValue;
String ret = getString(key);
if (ret == null)
return defaultValue;
else
return ret;
}
/*@Override
public String[] getStringArray(String key) {
String[] ret;
for (Configuration item : compositeConfig) {
ret = item.getStringArray(key);
if (ret != null)
return ret;
}
return null;
}*/
/*@Override
public Configuration subset(String prefix) {
throw new RuntimeException("不支持此方法");
}*/
@Override
public Properties getProperties(){
Properties props = new Properties();
Iterator<?> iter = this.getKeys();
while (iter.hasNext()){
String key = (String)iter.next();
props.put(key, this.getProperty(key));
}
return props;
}
}