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> 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 Map getConfig(Class clazz) throws Exception { Map 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 void readFileToCache(Class clazz, Map map, File file) throws IOException, InstantiationException, IllegalAccessException, NoSuchFieldException { String line; List key = new ArrayList<>(); List 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 Map> getMapConfig(Class clazz) throws Exception { Map> 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 mapConf = new HashMap<>(); readFileToCache(clazz,mapConf,mapFile); map.put(mapId, mapConf); } return map; } /** * 处理参数 */ private static void dealParams(Class clazz, Map map, List key, List 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 void mut(List key, List 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 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 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 getJsonFilePathInJsonConf(String fileName, Class 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(); } } }