323 lines
11 KiB
Java
323 lines
11 KiB
Java
|
|
package manager;
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||
|
|
import org.slf4j.Logger;
|
||
|
|
import org.slf4j.LoggerFactory;
|
||
|
|
import utils.StringUtil;
|
||
|
|
import utils.SysUtil;
|
||
|
|
|
||
|
|
import java.io.*;
|
||
|
|
import java.lang.reflect.Field;
|
||
|
|
import java.lang.reflect.Method;
|
||
|
|
import java.util.*;
|
||
|
|
|
||
|
|
public class STableManager {
|
||
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(STableManager.class);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* table表包名
|
||
|
|
*/
|
||
|
|
private static String data_parackage = null;
|
||
|
|
|
||
|
|
private static String jsonPath;
|
||
|
|
|
||
|
|
private static int currentDbVersion;
|
||
|
|
|
||
|
|
public static void initialize(String data_parackage) throws Exception {
|
||
|
|
STableManager.data_parackage = data_parackage;
|
||
|
|
updateTablesWithTableNames(false);
|
||
|
|
initJsonPath();
|
||
|
|
initDbVersion();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 根据表名字更新表数据
|
||
|
|
*
|
||
|
|
* @throws Exception
|
||
|
|
*/
|
||
|
|
public static void updateTablesWithTableNames(boolean isHotFix) throws Exception {
|
||
|
|
String[] tableList = null;
|
||
|
|
if (isHotFix) {
|
||
|
|
CDataBaseVersion version = getJsonFilePathInJsonConf("c_database_version.json",CDataBaseVersion.class);
|
||
|
|
if (version == null || version.getTables().isEmpty() || currentDbVersion >= version.getVersion()) { // 启动而不是热更
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
currentDbVersion = version.getVersion();
|
||
|
|
//更新指定表
|
||
|
|
tableList = version.getTables().split("\\|");
|
||
|
|
}
|
||
|
|
Set<Class<?>> messageCommandClasses = ClassScanner.listClassesWithAnnotation(data_parackage, Table.class);
|
||
|
|
for (Class<?> cls : messageCommandClasses) {
|
||
|
|
String tableName = cls.getAnnotation(Table.class).name();
|
||
|
|
if (tableList != null) {
|
||
|
|
if (!isHotFixContainTableName(tableList, tableName)) {
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Object stable = cls.newInstance();
|
||
|
|
Method method = cls.getMethod("init");
|
||
|
|
method.invoke(stable);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static boolean isHotFixContainTableName(String[] tableNames, String curTableName) {
|
||
|
|
if (tableNames == null) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (tableNames.length == 0) {
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
for (String oneTable : tableNames) {
|
||
|
|
if (oneTable.equalsIgnoreCase(curTableName)) {
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 读取配置表到内存
|
||
|
|
*/
|
||
|
|
public static <T> Map<Integer, T> getConfig(Class<T> clazz) throws Exception {
|
||
|
|
Map<Integer, T> map = new HashMap<>();
|
||
|
|
try {
|
||
|
|
String tableName = clazz.getAnnotation(Table.class).name();
|
||
|
|
String path = SysUtil.getPath("conf", "server", tableName + ".txt");
|
||
|
|
File file = new File(path);
|
||
|
|
|
||
|
|
if (!file.exists()) {
|
||
|
|
LOGGER.error("file not find {}, do not find sheet with {} you need rebuild all sheet by gen sheet tool!", path, tableName);
|
||
|
|
// return null;
|
||
|
|
}
|
||
|
|
LOGGER.info("initMap:{}", clazz.getSimpleName());
|
||
|
|
readFileToCache(clazz, map, file);
|
||
|
|
} catch (Exception e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
return map;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static <T> void readFileToCache(Class<T> clazz, Map<Integer, T> map, File file) throws IOException, InstantiationException, IllegalAccessException, NoSuchFieldException {
|
||
|
|
String line;
|
||
|
|
List<String> key = new ArrayList<>();
|
||
|
|
List<String> type = new ArrayList<>();
|
||
|
|
int lineNum = 0;
|
||
|
|
try(BufferedReader bufferedReader = new BufferedReader(new FileReader(file))){
|
||
|
|
while ((line = bufferedReader.readLine()) != null) {
|
||
|
|
if (line.isEmpty()){
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
T obj = clazz.newInstance();
|
||
|
|
String[] prarms = line.split("\\t");
|
||
|
|
switch (lineNum) {
|
||
|
|
case 0:
|
||
|
|
prarms = StringUtil.fieldHandle(prarms);
|
||
|
|
key.addAll(Arrays.asList(prarms));
|
||
|
|
break;
|
||
|
|
case 1:
|
||
|
|
type.addAll(Arrays.asList(prarms));
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
dealParams(clazz, map, key, type, obj, prarms);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
lineNum++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 读取配置表到内存
|
||
|
|
*/
|
||
|
|
public static <T> Map<Integer, Map<Integer, T>> getMapConfig(Class<T> clazz) throws Exception {
|
||
|
|
Map<Integer, Map<Integer, T>> map = new HashMap<>();
|
||
|
|
String tableName = clazz.getAnnotation(Table.class).name();
|
||
|
|
String pathDir = SysUtil.getPath("conf", "server");
|
||
|
|
File mapDir = new File(pathDir);
|
||
|
|
String prefix = tableName + "_";
|
||
|
|
int preLength = prefix.length();
|
||
|
|
for(File mapFile : mapDir.listFiles()){
|
||
|
|
tableName = mapFile.getName();
|
||
|
|
if(!mapFile.getName().startsWith(prefix)){
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
int mapId = Integer.parseInt(tableName.substring(preLength).split("\\.")[0]);
|
||
|
|
LOGGER.info("initMap:{}", tableName);
|
||
|
|
Map<Integer, T> mapConf = new HashMap<>();
|
||
|
|
readFileToCache(clazz,mapConf,mapFile);
|
||
|
|
map.put(mapId, mapConf);
|
||
|
|
}
|
||
|
|
return map;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 处理参数
|
||
|
|
*/
|
||
|
|
private static <T> void dealParams(Class<T> clazz, Map<Integer, T> map, List<String> key, List<String> type, T obj, String[] prarms) throws NoSuchFieldException, IllegalAccessException {
|
||
|
|
int id = Integer.parseInt(prarms[0]);
|
||
|
|
for (int i = 0; i < prarms.length; i++) {
|
||
|
|
try {
|
||
|
|
Field field = clazz.getDeclaredField(key.get(i));
|
||
|
|
boolean flag = field.isAccessible();
|
||
|
|
field.setAccessible(true);
|
||
|
|
switch (type.get(i)) {
|
||
|
|
case "int":
|
||
|
|
field.set(obj, Integer.parseInt(prarms[i]));
|
||
|
|
break;
|
||
|
|
case "string":
|
||
|
|
case "stringt":
|
||
|
|
if (!"null".equalsIgnoreCase(prarms[i]) || !"".equalsIgnoreCase(prarms[i])) {
|
||
|
|
field.set(obj, prarms[i]);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
case "long":
|
||
|
|
field.set(obj, Long.parseLong(prarms[i]));
|
||
|
|
break;
|
||
|
|
case "double":
|
||
|
|
field.set(obj, Double.parseDouble(prarms[i]));
|
||
|
|
break;
|
||
|
|
case "float":
|
||
|
|
field.set(obj, Float.parseFloat(prarms[i]));
|
||
|
|
break;
|
||
|
|
case "bool":
|
||
|
|
field.set(obj, Boolean.parseBoolean(prarms[i]));
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
if (type.get(i).startsWith("ref")) {
|
||
|
|
field.set(obj, Integer.parseInt(prarms[i]));
|
||
|
|
} else if (type.get(i).startsWith("mut")) {
|
||
|
|
mut(key, type, obj, prarms, i, field);
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
field.setAccessible(flag);
|
||
|
|
map.put(id, obj);
|
||
|
|
} catch (NoSuchFieldException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 操作mut开头的类型
|
||
|
|
*/
|
||
|
|
private static <T> void mut(List<String> key, List<String> type, T obj, String[] prarms, int i, Field field) throws IllegalAccessException {
|
||
|
|
String[] params = type.get(i).split(",");
|
||
|
|
String[] type1 = params[1].split("#");
|
||
|
|
int dimension = dimension(type1, params);
|
||
|
|
if (dimension == 0) {
|
||
|
|
field.set(obj, prarms[i]);
|
||
|
|
} else {
|
||
|
|
//全为int或者float
|
||
|
|
switch (type1[0]) {
|
||
|
|
case "int":
|
||
|
|
intField(obj, prarms, i, field, dimension);
|
||
|
|
break;
|
||
|
|
case "float":
|
||
|
|
floatField(obj, prarms, i, field, dimension);
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static <T> void floatField(T obj, String[] prarms, int i, Field field, int dimension) throws IllegalAccessException {
|
||
|
|
switch (dimension) {
|
||
|
|
case 1:
|
||
|
|
field.set(obj, StringUtil.parseFiledFloat(prarms[i]));
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
field.set(obj, StringUtil.parseFiledFloat2(prarms[i]));
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
field.set(obj, StringUtil.parseFiledFloat3(prarms[i]));
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static <T> void intField(T obj, String[] prarms, int i, Field field, int dimension) throws IllegalAccessException {
|
||
|
|
switch (dimension) {
|
||
|
|
case 1:
|
||
|
|
field.set(obj, StringUtil.parseFiledInt(prarms[i]));
|
||
|
|
break;
|
||
|
|
case 2:
|
||
|
|
field.set(obj, StringUtil.parseFiledInt2(prarms[i]));
|
||
|
|
break;
|
||
|
|
case 3:
|
||
|
|
field.set(obj, StringUtil.parseFiledInt3(prarms[i]));
|
||
|
|
break;
|
||
|
|
default:
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 判断是几维数组
|
||
|
|
*/
|
||
|
|
private static int dimension(String type[], String[] params) throws IllegalAccessException {
|
||
|
|
|
||
|
|
String type1 = type[0];
|
||
|
|
boolean flag = false;
|
||
|
|
for (int i = 0; i < type.length; i++) {
|
||
|
|
if (!type1.equals(type[i])) {
|
||
|
|
flag = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (flag) {
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
return Integer.parseInt(params[2]);
|
||
|
|
}
|
||
|
|
|
||
|
|
private static String getType(String param) {
|
||
|
|
String[] params = param.split(",");
|
||
|
|
String[] type = params[1].split("#");
|
||
|
|
return type[0];
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
public static <T> T getJsonFilePathInJsonConf(String fileName, Class<T> fileClass) {
|
||
|
|
File file = new File(jsonPath + fileName);
|
||
|
|
if (!file.exists()) {
|
||
|
|
LOGGER.info("the {} is not exist",fileName);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
try (InputStream in = new FileInputStream(file);) {
|
||
|
|
ObjectMapper mapper = new ObjectMapper();
|
||
|
|
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
||
|
|
return mapper.readValue(in, fileClass);
|
||
|
|
} catch (FileNotFoundException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
} catch (IOException e) {
|
||
|
|
e.printStackTrace();
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void initJsonPath() {
|
||
|
|
String osName = System.getProperty("os.name");
|
||
|
|
jsonPath = "../conf/";
|
||
|
|
if (osName.matches("^(?i)Windows.*$")) {// Window 系统
|
||
|
|
jsonPath = "conf/";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
private static void initDbVersion() {
|
||
|
|
CDataBaseVersion cDataBaseVersion = getJsonFilePathInJsonConf("c_database_version.json",CDataBaseVersion.class);
|
||
|
|
if (null == cDataBaseVersion) {
|
||
|
|
currentDbVersion = 0;
|
||
|
|
} else {
|
||
|
|
currentDbVersion = cDataBaseVersion.getVersion();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|