Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.sagacity.sqltoy.translate.TranslateFactory Maven / Gradle / Ivy
package org.sagacity.sqltoy.translate;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.sagacity.sqltoy.SqlToyContext;
import org.sagacity.sqltoy.config.model.SqlToyConfig;
import org.sagacity.sqltoy.config.model.SqlType;
import org.sagacity.sqltoy.dialect.DialectFactory;
import org.sagacity.sqltoy.model.QueryExecutor;
import org.sagacity.sqltoy.model.QueryResult;
import org.sagacity.sqltoy.plugins.datasource.DataSourceSelector;
import org.sagacity.sqltoy.translate.model.CacheCheckResult;
import org.sagacity.sqltoy.translate.model.CheckerConfigModel;
import org.sagacity.sqltoy.translate.model.TranslateConfigModel;
import org.sagacity.sqltoy.utils.BeanUtil;
import org.sagacity.sqltoy.utils.CollectionUtil;
import org.sagacity.sqltoy.utils.DateUtil;
import org.sagacity.sqltoy.utils.HttpClientUtils;
import org.sagacity.sqltoy.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
/**
* @project sagacity-sqltoy
* @description 缓存刷新检测接口定义
* @author zhongxuchen
* @version v1.0,Date:2018年3月8日
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class TranslateFactory {
/**
* 定义全局日志
*/
protected final static Logger logger = LoggerFactory.getLogger(TranslateFactory.class);
/**
* @todo 执行检测,返回缓存相关数据最后修改时间,便于比较是否发生变化
* @param sqlToyContext
* @param checkerConfig
* @param preCheckTime
* @return
*/
public static List doCheck(final SqlToyContext sqlToyContext,
final CheckerConfigModel checkerConfig, Timestamp preCheckTime) {
List result = null;
try {
// 直接sql查询加载缓存模式
if ("sql".equals(checkerConfig.getType())) {
result = doSqlCheck(sqlToyContext, checkerConfig, preCheckTime);
} // 调用springBean模式
else if ("service".equals(checkerConfig.getType())) {
result = doServiceCheck(sqlToyContext, checkerConfig, preCheckTime);
} // 调用rest请求模式
else if ("rest".equals(checkerConfig.getType())) {
result = doRestCheck(sqlToyContext, checkerConfig, preCheckTime);
}
// local模式由应用自行管理
} catch (Exception e) {
e.printStackTrace();
logger.error("执行缓存变更检测发生错误,错误信息:{}", e.getMessage());
}
// 增量更新模式
if (checkerConfig.isIncrement()) {
return wrapIncrementCheckResult(result, checkerConfig);
}
// 清空模式
return wrapClearCheckResult(result, checkerConfig);
}
/**
* @todo 执行sql检测
* @param sqlToyContext
* @param checkerConfig
* @param preCheckTime
* @return
* @throws Exception
*/
private static List doSqlCheck(final SqlToyContext sqlToyContext, final CheckerConfigModel checkerConfig,
Timestamp preCheckTime) throws Exception {
final SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(checkerConfig.getSql(), SqlType.search, "",
null);
String dataSourceName = checkerConfig.getDataSource();
if (dataSourceName == null) {
dataSourceName = sqlToyConfig.getDataSource();
}
QueryExecutor query = new QueryExecutor(checkerConfig.getSql(), sqlToyConfig.getParamsName(),
new Object[] { new Date(preCheckTime.getTime()) });
DataSourceSelector dataSourceSelector = sqlToyContext.getDataSourceSelector();
DataSource dataSource = dataSourceSelector.getDataSource(sqlToyContext.getAppContext(), null, dataSourceName,
null, sqlToyContext.getDefaultDataSource());
return DialectFactory.getInstance().findByQuery(sqlToyContext, query, sqlToyConfig, null, dataSource).getRows();
}
/**
* @todo 执行基于service调用的检测
* @param sqlToyContext
* @param checkerConfig 缓存更新检测配置
* @param preCheckTime 上次检测时间
* @return
* @throws Exception
*/
private static List doServiceCheck(final SqlToyContext sqlToyContext, final CheckerConfigModel checkerConfig,
Timestamp preCheckTime) throws Exception {
return (List) sqlToyContext.getServiceData(checkerConfig.getService(), checkerConfig.getMethod(),
new Object[] { preCheckTime });
}
/**
* @todo 执行基于rest请求模式的缓存更新检测
* @param sqlToyContext
* @param checkerConfig 缓存更新检测配置
* @param preCheckTime 上次检测时间
* @return
* @throws Exception
*/
private static List doRestCheck(final SqlToyContext sqlToyContext, final CheckerConfigModel checkerConfig,
Timestamp preCheckTime) throws Exception {
String[] paramNames = { "lastUpdateTime" };
String[] paramValues = { DateUtil.formatDate(preCheckTime, "yyyy-MM-dd HH:mm:ss.SSS") };
String jsonStr = HttpClientUtils.doPost(sqlToyContext, checkerConfig.getUrl(), checkerConfig.getUsername(),
checkerConfig.getPassword(), paramNames, paramValues);
if (jsonStr == null) {
return null;
}
List result = null;
boolean fatal = false;
try {
result = JSON.parseArray(jsonStr, CacheCheckResult.class);
} catch (Exception e) {
fatal = true;
}
if (fatal) {
try {
result = JSON.parseArray(jsonStr, Object[].class);
fatal = false;
} catch (Exception e) {
fatal = true;
}
}
if (fatal) {
logger.warn("rest模式检测缓存是否更新数据格式转换异常,数据格式是数组或CacheCheckResult对象类型的数组!");
}
return result;
}
/**
* @todo 包装检测结果为统一的对象集合
* @param result
* @param checkerConfig
* @return
*/
private static List wrapClearCheckResult(List result, CheckerConfigModel checkerConfig) {
if (result == null || result.isEmpty()) {
return null;
}
if (result.get(0) instanceof CacheCheckResult) {
return result;
}
List cacheSet = null;
if (result.get(0) instanceof Object[]) {
cacheSet = result;
} else if (result.get(0) instanceof List) {
cacheSet = CollectionUtil.innerListToArray(result);
} else if (checkerConfig.getProperties() != null && checkerConfig.getProperties().length > 0) {
cacheSet = BeanUtil.reflectBeansToInnerAry(result, checkerConfig.getProperties(), null, null);
}
if (cacheSet == null) {
return null;
}
List checkResult = new ArrayList();
Object[] row;
CacheCheckResult item;
for (int i = 0; i < cacheSet.size(); i++) {
row = (Object[]) cacheSet.get(i);
item = new CacheCheckResult();
item.setCacheName((String) row[0]);
if (row.length > 1) {
item.setCacheType((String) row[1]);
}
checkResult.add(item);
}
return checkResult;
}
/**
* @todo 包装检测结果为统一的对象集合
* @param result
* @param checkerConfig
* @return
*/
private static List wrapIncrementCheckResult(List result, CheckerConfigModel checkerConfig) {
if (result == null || result.isEmpty()) {
return null;
}
if (result.get(0) instanceof CacheCheckResult) {
return result;
}
List cacheSet = null;
if (result.get(0) instanceof List) {
cacheSet = CollectionUtil.innerListToArray(result);
} else if (result.get(0) instanceof Object[]) {
cacheSet = result;
} else if (checkerConfig.getProperties() != null && checkerConfig.getProperties().length > 0) {
cacheSet = BeanUtil.reflectBeansToInnerAry(result, checkerConfig.getProperties(), null, null);
}
if (cacheSet == null) {
return null;
}
String cacheName = checkerConfig.getCache();
boolean hasInsideGroup = checkerConfig.isHasInsideGroup();
List checkResult = new ArrayList();
Object[] row;
CacheCheckResult item;
Object[] cacheValue;
for (int i = 0; i < cacheSet.size(); i++) {
row = (Object[]) cacheSet.get(i);
item = new CacheCheckResult();
item.setCacheName(cacheName);
// 缓存内部存在分组(参考数据字典表中的字典分类)
if (hasInsideGroup) {
item.setCacheType((String) row[0]);
cacheValue = new Object[row.length - 1];
// 跳过第一列缓存类别
System.arraycopy(row, 1, cacheValue, 0, row.length - 1);
item.setItem(cacheValue);
} else {
item.setItem(row);
}
checkResult.add(item);
}
return checkResult;
}
/**
* @todo 重新查询获取缓存数据
* @param sqlToyContext
* @param cacheModel
* @param cacheType
* @return
*/
public static HashMap getCacheData(final SqlToyContext sqlToyContext,
TranslateConfigModel cacheModel, String cacheType) {
Object result = null;
try {
if ("sql".equals(cacheModel.getType())) {
result = getSqlCacheData(sqlToyContext, cacheModel, cacheType);
} else if ("service".equals(cacheModel.getType())) {
result = getServiceCacheData(sqlToyContext, cacheModel, cacheType);
} else if ("rest".equals(cacheModel.getType())) {
result = getRestCacheData(sqlToyContext, cacheModel, cacheType);
}
} catch (Exception e) {
e.printStackTrace();
logger.error("获取缓存数据失败,返回结果应该是List 或List 或 Map 类型,错误信息:{}",
e.getMessage());
}
HashMap cacheData = wrapCacheResult(result, cacheModel);
// 增加错误日志提醒
if (cacheData == null || cacheData.isEmpty()) {
logger.warn("缓存cacheName={} 数据集为空,请检查对应的配置和查询逻辑是否正确!", cacheModel.getCache());
}
return cacheData;
}
/**
* @todo 通过sql查询获取缓存数据
* @param sqlToyContext
* @param cacheModel
* @param cacheType
* @return
* @throws Exception
*/
private static List getSqlCacheData(final SqlToyContext sqlToyContext, TranslateConfigModel cacheModel,
String cacheType) throws Exception {
final SqlToyConfig sqlToyConfig = sqlToyContext.getSqlToyConfig(cacheModel.getSql(), SqlType.search, "", null);
QueryExecutor queryExecutor = null;
if (StringUtil.isBlank(cacheType)) {
queryExecutor = new QueryExecutor(cacheModel.getSql());
} else {
queryExecutor = new QueryExecutor(cacheModel.getSql(), sqlToyConfig.getParamsName(),
new Object[] { cacheType.trim() });
}
String dataSourceName = cacheModel.getDataSource();
if (dataSourceName == null) {
dataSourceName = sqlToyConfig.getDataSource();
}
DataSourceSelector dataSourceSelector = sqlToyContext.getDataSourceSelector();
DataSource dataSource = dataSourceSelector.getDataSource(sqlToyContext.getAppContext(), null, dataSourceName,
null, sqlToyContext.getDefaultDataSource());
QueryResult result = DialectFactory.getInstance().findByQuery(sqlToyContext, queryExecutor, sqlToyConfig, null,
dataSource);
cacheModel.setProperties(result.getLabelNames());
return result.getRows();
}
/**
* @todo 基于service bean 调用方式获取缓存数据
* @param sqlToyContext
* @param cacheModel
* @param cacheType
* @return
* @throws Exception
*/
private static Object getServiceCacheData(final SqlToyContext sqlToyContext, TranslateConfigModel cacheModel,
String cacheType) throws Exception {
// getDictCache(String cacheType)返回List 或List 参照sql模式
return sqlToyContext.getServiceData(cacheModel.getService(), cacheModel.getMethod(),
StringUtil.isBlank(cacheType) ? new Object[] {} : new Object[] { cacheType.trim() });
}
/**
* @todo 基于rest http 请求获取缓存数据
* @param sqlToyContext
* @param cacheModel
* @param cacheType
* @return
* @throws Exception
*/
private static List getRestCacheData(final SqlToyContext sqlToyContext, TranslateConfigModel cacheModel,
String cacheType) throws Exception {
// 冗余一个参数名称
String[] paramNames = { "cacheType", "type" };
String[] paramValues = null;
if (StringUtil.isNotBlank(cacheType)) {
paramValues = new String[] { cacheType.trim(), cacheType.trim() };
}
String jsonStr = HttpClientUtils.doPost(sqlToyContext, cacheModel.getUrl(), cacheModel.getUsername(),
cacheModel.getPassword(), paramNames, paramValues);
if (jsonStr == null) {
return null;
}
if (cacheModel.getProperties() == null || cacheModel.getProperties().length == 0) {
return JSON.parseArray(jsonStr, Object[].class);
}
JSONArray jsonSet = JSON.parseArray(jsonStr);
if (jsonSet.isEmpty()) {
return null;
}
List result = new ArrayList();
int size = cacheModel.getProperties().length;
JSONObject jsonObj;
Object[] row;
for (Object obj : jsonSet) {
jsonObj = (JSONObject) obj;
row = new Object[size];
for (int i = 0; i < size; i++) {
row[i] = jsonObj.get(cacheModel.getProperties()[i]);
}
result.add(row);
}
return result;
}
/**
* @todo 包装结果,转化为统一的格式
* @param target
* @param cacheModel
* @return
*/
private static HashMap wrapCacheResult(Object target, TranslateConfigModel cacheModel) {
if (target == null) {
return null;
}
if (target instanceof HashMap && ((HashMap) target).isEmpty()) {
return null;
}
if (target instanceof HashMap && ((HashMap) target).values().iterator().next().getClass().isArray()) {
return (HashMap) target;
}
LinkedHashMap result = new LinkedHashMap();
if (target instanceof HashMap) {
if (!((HashMap) target).isEmpty()) {
if (((HashMap) target).values().iterator().next() instanceof List) {
Iterator> iter = ((HashMap) target).entrySet().iterator();
Map.Entry entry;
Object[] row;
while (iter.hasNext()) {
entry = iter.next();
row = new Object[entry.getValue().size()];
entry.getValue().toArray(row);
result.put(entry.getKey(), row);
}
} else {
Iterator> iter = ((HashMap) target).entrySet().iterator();
Map.Entry entry;
while (iter.hasNext()) {
entry = iter.next();
result.put(entry.getKey(), new Object[] { entry.getKey(), entry.getValue() });
}
}
}
} else if (target instanceof List) {
List tempList = (List) target;
if (!tempList.isEmpty()) {
int cacheIndex = cacheModel.getKeyIndex();
if (tempList.get(0) instanceof List) {
List row;
Object[] rowAry;
for (int i = 0, n = tempList.size(); i < n; i++) {
row = (List) tempList.get(i);
rowAry = new Object[row.size()];
row.toArray(rowAry);
result.put(rowAry[cacheIndex].toString(), rowAry);
}
} else if (tempList.get(0) instanceof Object[]) {
Object[] row;
for (int i = 0, n = tempList.size(); i < n; i++) {
row = (Object[]) tempList.get(i);
result.put(row[cacheIndex].toString(), row);
}
} // 对象数组,利用反射提取属性值
else if (cacheModel.getProperties() != null && cacheModel.getProperties().length > 1) {
List dataSet = BeanUtil.reflectBeansToInnerAry(tempList, cacheModel.getProperties(), null,
null);
for (Object[] row : dataSet) {
result.put(row[cacheIndex].toString(), row);
}
}
}
}
return result;
}
}