use of org.sagacity.sqltoy.callback.XMLCallbackHandler in project sagacity-sqltoy by chenrenfei.
the class TranslateConfigParse method parseTranslateConfig.
/**
* @todo 解析translate配置文件
* @param sqlToyContext
* @param translateMap 最终缓存配置,构建一个空map,在解析过程中填充
* @param checker 更新检测配置
* @param translateConfig 缓存配置文件
* @param charset
* @return
* @throws Exception
*/
public static DefaultConfig parseTranslateConfig(final SqlToyContext sqlToyContext, final IgnoreKeyCaseMap<String, TranslateConfigModel> translateMap, final List<CheckerConfigModel> checker, String translateConfig, String charset) throws Exception {
// 判断缓存翻译的配置文件是否存在
if (FileUtil.getFileInputStream(translateConfig) == null) {
logger.warn("缓存翻译配置文件:{}无法加载,请检查配路径正确性,如不使用缓存翻译可忽略此提示!", translateConfig);
return null;
}
return (DefaultConfig) XMLUtil.readXML(translateConfig, charset, false, new XMLCallbackHandler() {
@Override
public Object process(Document doc, Element root) throws Exception {
DefaultConfig defaultConfig = new DefaultConfig();
NodeList nodeList = root.getElementsByTagName("cache-translates");
if (nodeList.getLength() == 0) {
return defaultConfig;
}
// 解析缓存翻译配置
Element node = (Element) nodeList.item(0);
XMLUtil.setAttributes(node, defaultConfig);
NodeList elts;
Element elt;
NodeList sqlNode;
String sql;
String sqlId;
boolean isShowSql;
int index = 1;
for (String translateType : TRANSLATE_TYPES) {
elts = node.getElementsByTagName(translateType.concat(TRANSLATE_SUFFIX));
if (elts.getLength() > 0) {
for (int i = 0; i < elts.getLength(); i++) {
elt = (Element) elts.item(i);
TranslateConfigModel translateCacheModel = new TranslateConfigModel();
// 设置默认值
translateCacheModel.setHeap(defaultConfig.getDefaultHeap());
translateCacheModel.setOffHeap(defaultConfig.getDefaultOffHeap());
translateCacheModel.setDiskSize(defaultConfig.getDefaultDiskSize());
translateCacheModel.setKeepAlive(defaultConfig.getDefaultKeepAlive());
XMLUtil.setAttributes(elt, translateCacheModel);
translateCacheModel.setType(translateType);
// 非sqlId模式定义
if (translateType.equals("sql")) {
if (StringUtil.isBlank(translateCacheModel.getSql())) {
sqlNode = elt.getElementsByTagName("sql");
if (sqlNode.getLength() > 0) {
sql = StringUtil.trim(sqlNode.item(0).getTextContent());
} else {
sql = StringUtil.trim(elt.getTextContent());
}
sqlId = "s_trans_cache_0" + index;
isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, SqlUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyConfig.setParamsName(SqlConfigParseUtils.getSqlParamsName(sqlToyConfig.getSql(null), true));
sqlToyContext.putSqlToyConfig(sqlToyConfig);
translateCacheModel.setSql(sqlId);
index++;
}
}
// local模式是避免一些额外争议的产物,有部分开发者坚持缓存要应用自己管理
if (translateType.equals("local") && !elt.hasAttribute("keep-alive")) {
translateCacheModel.setKeepAlive(-1);
}
translateMap.put(translateCacheModel.getCache(), translateCacheModel);
logger.debug("已经加载缓存翻译:cache={},type={}", (translateCacheModel.getCache() == null) ? "[非增量]" : translateCacheModel.getCache(), translateType);
}
}
}
nodeList = root.getElementsByTagName("cache-update-checkers");
// 解析更新检测器
if (nodeList.getLength() == 0) {
return defaultConfig;
}
node = (Element) nodeList.item(0);
// 集群节点时间偏差(秒)
if (node.hasAttribute("cluster-time-deviation")) {
defaultConfig.setDeviationSeconds(Integer.parseInt(node.getAttribute("cluster-time-deviation")));
if (Math.abs(defaultConfig.getDeviationSeconds()) > 60) {
logger.debug("您设置的集群节点时间差异参数cluster-time-deviation={} 秒>60秒,将设置为60秒!", defaultConfig.getDeviationSeconds());
defaultConfig.setDeviationSeconds(-60);
} else {
defaultConfig.setDeviationSeconds(0 - Math.abs(defaultConfig.getDeviationSeconds()));
}
}
String nodeType;
index = 1;
// 缓存更新检测
for (String translateType : TRANSLATE_CHECKER_TYPES) {
nodeType = translateType.concat(CHECKER_SUFFIX);
elts = node.getElementsByTagName(nodeType);
if (elts.getLength() > 0) {
for (int i = 0; i < elts.getLength(); i++) {
elt = (Element) elts.item(i);
CheckerConfigModel checherConfigModel = new CheckerConfigModel();
XMLUtil.setAttributes(elt, checherConfigModel);
// 数据交互类型
checherConfigModel.setType(translateType.replace("-increment", ""));
// 增量方式更新
if (translateType.endsWith("-increment")) {
checherConfigModel.setIncrement(true);
// 增量方式必须要指定缓存名称
if (StringUtil.isBlank(checherConfigModel.getCache())) {
logger.error("translate update checker:{} must config with cache=\"xxx\"!", nodeType);
throw new IllegalArgumentException(nodeType + " must config with cache=\"xxx\"");
}
}
// sql模式且非sqlId模式定义
if (checherConfigModel.getType().equals("sql")) {
if (StringUtil.isBlank(checherConfigModel.getSql())) {
sqlId = (checherConfigModel.isIncrement() ? "s_trans_merge_chk_0" : "s_trans_chk_0") + index;
sqlNode = elt.getElementsByTagName("sql");
if (sqlNode.getLength() > 0) {
sql = StringUtil.trim(sqlNode.item(0).getTextContent());
} else {
sql = StringUtil.trim(elt.getTextContent());
}
isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, SqlUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyConfig.setParamsName(SqlConfigParseUtils.getSqlParamsName(sqlToyConfig.getSql(null), true));
// 增加条件参数检查,避免开发者手误然后找不到原因!有出现:lastUpdateTime 和 lastUpdateTimee 的找半天发现不了问题的!
if (sqlToyConfig.getParamsName() != null && sqlToyConfig.getParamsName().length > 1) {
throw new IllegalArgumentException("请检查缓存更新检测sql语句中的参数名称,所有参数名称要保持一致为lastUpdateTime!当前有:" + sqlToyConfig.getParamsName().length + " 个不同条件参数名!");
}
sqlToyContext.putSqlToyConfig(sqlToyConfig);
checherConfigModel.setSql(sqlId);
index++;
}
}
// 剔除tab\回车等特殊字符
String frequency = SqlUtil.clearMistyChars(checherConfigModel.getCheckFrequency(), "");
List<TimeSection> timeSections = new ArrayList<TimeSection>();
// frequency的格式 frequency="0..12?15,12..18:30?10,18:30..24?60"
if (StringUtil.isNotBlank(frequency)) {
// 统一格式,去除全角字符,去除空白
frequency = StringUtil.toDBC(frequency).replaceAll("\\;", ",").trim();
// 可以是单个频率值,表示0到24小时采用统一的频率
if (NumberUtil.isInteger(frequency)) {
TimeSection section = new TimeSection();
section.setStart(0);
section.setEnd(2400);
section.setIntervalSeconds(Integer.parseInt(frequency));
timeSections.add(section);
} else {
// 归整分割符号统一为逗号,将时间格式由HH:mm 转为HHmm格式
String[] sectionsStr = frequency.split("\\,");
for (int j = 0; j < sectionsStr.length; j++) {
TimeSection section = new TimeSection();
// 问号切割获取时间区间和时间间隔
String[] sectionPhase = sectionsStr[j].split("\\?");
// 获取开始和结束时间点
String[] startEnd = sectionPhase[0].split("\\.{2}");
section.setIntervalSeconds(Integer.parseInt(sectionPhase[1].trim()));
section.setStart(getHourMinute(startEnd[0].trim()));
section.setEnd(getHourMinute(startEnd[1].trim()));
timeSections.add(section);
}
}
}
checherConfigModel.setTimeSections(timeSections);
checker.add(checherConfigModel);
logger.debug("已经加载针对缓存:{} 更新的检测器,type={}", checherConfigModel.getCache(), translateType);
}
}
}
return defaultConfig;
}
});
}
use of org.sagacity.sqltoy.callback.XMLCallbackHandler in project sagacity-sqltoy by chenrenfei.
the class TranslateConfigParse method parseTranslateConfig.
/**
* @todo 解析translate配置文件
* @param translateMap
* @param checker
* @param translateConfig
* @param charset
* @throws Exception
*/
public static DefaultConfig parseTranslateConfig(final SqlToyContext sqlToyContext, final HashMap<String, TranslateConfigModel> translateMap, final List<CheckerConfigModel> checker, String translateConfig, String charset) throws Exception {
return (DefaultConfig) XMLUtil.readXML(translateConfig, charset, false, new XMLCallbackHandler() {
@Override
public Object process(Document doc, Element root) throws Exception {
// 解析缓存翻译配置
Element node = root.element("cache-translates");
DefaultConfig defaultConfig = new DefaultConfig();
if (node.attribute("disk-store-path") != null)
defaultConfig.setDiskStorePath(node.attributeValue("disk-store-path"));
List<Element> elts;
for (String translateType : TRANSLATE_TYPES) {
elts = node.elements(translateType.concat(TRANSLATE_SUFFIX));
if (elts != null && !elts.isEmpty()) {
int index = 1;
for (Element elt : elts) {
TranslateConfigModel translateCacheModel = new TranslateConfigModel();
XMLUtil.setAttributes(elt, translateCacheModel);
translateCacheModel.setType(translateType);
if (translateType.equals("sql")) {
if (StringUtil.isBlank(translateCacheModel.getSql())) {
String sql = (elt.element("sql") != null) ? elt.elementText("sql") : elt.getText();
String sqlId = "SQLTOY_TRANSLATE_Cache_ID_00" + index;
boolean isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, StringUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyContext.putSqlToyConfig(sqlToyConfig);
translateCacheModel.setSql(sqlId);
}
index++;
}
// 过期时长
if (translateCacheModel.getKeepAlive() <= 0)
translateCacheModel.setKeepAlive(SqlToyConstants.getCacheExpireSeconds());
translateMap.put(translateCacheModel.getCache(), translateCacheModel);
}
}
}
// 解析更新检测器
node = root.element("cache-update-checkers");
if (node != null) {
for (String translateType : TRANSLATE_TYPES) {
elts = node.elements(translateType.concat(CHECKER_SUFFIX));
if (elts != null && !elts.isEmpty()) {
int index = 1;
for (Element elt : elts) {
CheckerConfigModel checherConfigModel = new CheckerConfigModel();
XMLUtil.setAttributes(elt, checherConfigModel);
checherConfigModel.setType(translateType);
if (translateType.equals("sql")) {
if (StringUtil.isBlank(checherConfigModel.getSql())) {
String sqlId = "SQLTOY_TRANSLATE_Check_ID_00" + index;
String sql = (elt.element("sql") != null) ? elt.elementText("sql") : elt.getText();
boolean isShowSql = StringUtil.matches(sql, SqlToyConstants.NOT_PRINT_REGEX);
SqlToyConfig sqlToyConfig = new SqlToyConfig(sqlId, StringUtil.clearMistyChars(SqlUtil.clearMark(sql), " "));
sqlToyConfig.setShowSql(!isShowSql);
sqlToyContext.putSqlToyConfig(sqlToyConfig);
checherConfigModel.setSql(sqlId);
}
index++;
}
// 剔除tab\回车等特殊字符
String frequency = StringUtil.clearMistyChars(checherConfigModel.getCheckFrequency(), "");
List<TimeSection> timeSections = new ArrayList<TimeSection>();
// frequency的格式 frequency="0..12?15,12..18:30?10,18:30..24?60"
if (StringUtil.isNotBlank(frequency)) {
// 统一格式,去除全角字符,去除空白
frequency = frequency.replaceAll("\\;", ",").replaceAll("\\?", "?").replaceAll("\\.", ".").replaceAll("\\。", ".").replaceAll("\\,", ",").trim();
// 可以是单个频率值,表示0到24小时采用统一的频率
if (CommonUtils.isInteger(frequency)) {
TimeSection section = new TimeSection();
section.setStart(0);
section.setEnd(2400);
section.setIntervalSeconds(Integer.parseInt(frequency));
timeSections.add(section);
} else {
// 归整分割符号统一为逗号,将时间格式由HH:mm 转为HHmm格式
String[] sectionsStr = frequency.split("\\,");
for (int i = 0; i < sectionsStr.length; i++) {
TimeSection section = new TimeSection();
// 问号切割获取时间区间和时间间隔
String[] sectionPhase = sectionsStr[i].split("\\?");
// 获取开始和结束时间点
String[] startEnd = sectionPhase[0].split("\\.{2}");
section.setIntervalSeconds(Integer.parseInt(sectionPhase[1].trim()));
section.setStart(getHourMinute(startEnd[0].trim()));
section.setEnd(getHourMinute(startEnd[1].trim()));
timeSections.add(section);
}
}
}
checherConfigModel.setTimeSections(timeSections);
checker.add(checherConfigModel);
}
}
}
}
return defaultConfig;
}
});
}
Aggregations