1
0
mirror of https://e.coding.net/circlecloud/YumCore.git synced 2024-11-22 01:48:50 +00:00

feat: 添加自动配置转换解析

Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
502647092 2016-10-17 00:41:06 +08:00
parent 7711cb3d74
commit 7ee5fc9b40
5 changed files with 209 additions and 130 deletions

View File

@ -67,8 +67,7 @@ public class FileConfig extends AbstractConfig {
/**
* 从文件载入配置
*
* @param file
* 配置文件名称
* @param file 配置文件名称
*/
public FileConfig(File file) {
Validate.notNull(file, FILE_NOT_BE_NULL);
@ -78,10 +77,8 @@ public class FileConfig extends AbstractConfig {
/**
* 从文件载入配置
*
* @param parent
* 文件夹
* @param filename
* 配置文件名称
* @param parent 文件夹
* @param filename 配置文件名称
*/
public FileConfig(File parent, String filename) {
init(new File(parent, filename), true);
@ -90,8 +87,7 @@ public class FileConfig extends AbstractConfig {
/**
* 从数据流载入配置文件
*
* @param stream
* 数据流
* @param stream 数据流
*/
public FileConfig(InputStream stream) {
init(stream);
@ -100,8 +96,7 @@ public class FileConfig extends AbstractConfig {
/**
* 从文件载入配置
*
* @param filename
* 配置文件名称
* @param filename 配置文件名称
*/
public FileConfig(String filename) {
init(new File(plugin.getDataFolder(), filename), true);
@ -110,10 +105,8 @@ public class FileConfig extends AbstractConfig {
/**
* 从文件载入配置
*
* @param parent
* 文件夹
* @param filename
* 配置文件名称
* @param parent 文件夹
* @param filename 配置文件名称
*/
public FileConfig(String parent, String filename) {
init(new File(parent, filename), true);
@ -122,12 +115,9 @@ public class FileConfig extends AbstractConfig {
/**
* 添加到List末尾
*
* @param <E>
* List内容类型
* @param path
* 路径
* @param obj
* 对象
* @param <E> List内容类型
* @param path 路径
* @param obj 对象
* @return {@link FileConfig}
*/
public <E> FileConfig addToList(String path, E obj) {
@ -142,10 +132,8 @@ public class FileConfig extends AbstractConfig {
/**
* 添加到StringList末尾
*
* @param path
* 路径
* @param obj
* 字符串
* @param path 路径
* @param obj 字符串
* @return {@link FileConfig}
*/
public FileConfig addToStringList(String path, String obj) {
@ -156,12 +144,9 @@ public class FileConfig extends AbstractConfig {
/**
* 添加到StringList末尾
*
* @param path
* 路径
* @param obj
* 字符串
* @param allowrepeat
* 是否允许重复
* @param path 路径
* @param obj 字符串
* @param allowrepeat 是否允许重复
* @return {@link FileConfig}
*/
public FileConfig addToStringList(String path, String obj, boolean allowrepeat) {
@ -179,8 +164,7 @@ public class FileConfig extends AbstractConfig {
/**
* 获得已颜色转码的文本
*
* @param cfgmsg
* 待转码的List
* @param cfgmsg 待转码的List
* @return 颜色转码后的文本
*/
public List<String> getColorList(List<String> cfgmsg) {
@ -206,8 +190,7 @@ public class FileConfig extends AbstractConfig {
/**
* 获得Location
*
* @param key
*
* @param key
* @return {@link Location}
*/
public Location getLocation(String key) {
@ -217,10 +200,8 @@ public class FileConfig extends AbstractConfig {
/**
* 获得Location
*
* @param path
*
* @param def
* 默认地点
* @param path
* @param def 默认地点
* @return {@link Location}
*/
public Location getLocation(String path, Location def) {
@ -231,8 +212,7 @@ public class FileConfig extends AbstractConfig {
/**
* 获得已颜色转码的文本
*
* @param path
* 配置路径
* @param path 配置路径
* @return 颜色转码后的文本
*/
public String getMessage(String path) {
@ -242,10 +222,8 @@ public class FileConfig extends AbstractConfig {
/**
* 获得已颜色转码的文本
*
* @param path
* 配置路径
* @param def
* 默认文本
* @param path 配置路径
* @param def 默认文本
* @return 颜色转码后的文本
*/
public String getMessage(String path, String def) {
@ -259,8 +237,7 @@ public class FileConfig extends AbstractConfig {
/**
* 获得已颜色转码的文本
*
* @param path
* 配置路径
* @param path 配置路径
* @return 颜色转码后的文本
*/
public List<String> getMessageList(String path) {
@ -277,8 +254,7 @@ public class FileConfig extends AbstractConfig {
/**
* 获得字符串数组
*
* @param path
* 配置路径
* @param path 配置路径
* @return 字符串数组
*/
public String[] getStringArray(String path) {
@ -300,10 +276,8 @@ public class FileConfig extends AbstractConfig {
/**
* 比较版本号
*
* @param newver
* 新版本
* @param oldver
* 旧版本
* @param newver 新版本
* @param oldver 旧版本
* @return 是否需要更新
*/
public boolean needUpdate(String newver, String oldver) {
@ -340,12 +314,9 @@ public class FileConfig extends AbstractConfig {
/**
* 从List移除对象
*
* @param <E>
* List内容对象类型
* @param path
* 路径
* @param obj
* 对象
* @param <E> List内容对象类型
* @param path 路径
* @param obj 对象
* @return {@link FileConfig}
*/
public <E> FileConfig removeFromList(String path, E obj) {
@ -359,10 +330,8 @@ public class FileConfig extends AbstractConfig {
/**
* 从StringList移除对象
*
* @param path
* 路径
* @param obj
* 对象
* @param path 路径
* @param obj 对象
* @return {@link FileConfig}
*/
public FileConfig removeFromStringList(String path, String obj) {
@ -436,8 +405,7 @@ public class FileConfig extends AbstractConfig {
/**
* 备份配置文件
*
* @param oldcfg
* 配置文件
* @param oldcfg 配置文件
*/
protected void backupConfig(FileConfig oldcfg) {
String filename = oldcfg.getConfigName();
@ -455,8 +423,7 @@ public class FileConfig extends AbstractConfig {
/**
* 检查配置文件
*
* @param file
* 配置文件
* @param file 配置文件
*/
protected void check(File file) {
String filename = file.getName();
@ -509,8 +476,7 @@ public class FileConfig extends AbstractConfig {
/**
* 初始化FileConfig
*
* @param file
* 配置文件
* @param file 配置文件
* @return FileConfig
*/
protected FileConfig init(File file) {
@ -521,10 +487,8 @@ public class FileConfig extends AbstractConfig {
/**
* 初始化FileConfig
*
* @param file
* 配置文件
* @param check
* 是否检查文件
* @param file 配置文件
* @param check 是否检查文件
* @return FileConfig
*/
protected FileConfig init(File file, boolean check) {
@ -544,8 +508,7 @@ public class FileConfig extends AbstractConfig {
/**
* 初始化FileConfig
*
* @param stream
* 输入流
* @param stream 输入流
* @return FileConfig
*/
protected FileConfig init(InputStream stream) {
@ -571,10 +534,8 @@ public class FileConfig extends AbstractConfig {
/**
* 检查配置文件版本
*
* @param newcfg
* 新配置文件
* @param oldcfg
* 旧配置文件
* @param newcfg 新配置文件
* @param oldcfg 旧配置文件
* @return 是否需要升级
*/
protected boolean needUpdate(FileConfig newcfg, FileConfig oldcfg) {
@ -584,10 +545,8 @@ public class FileConfig extends AbstractConfig {
/**
* 更新配置文件
*
* @param newcfg
* 新配置文件
* @param oldcfg
* 旧配置文件
* @param newcfg 新配置文件
* @param oldcfg 旧配置文件
* @return 更新以后的配置文件
*/
protected FileConfig updateConfig(FileConfig newCfg, FileConfig oldCfg) {
@ -597,12 +556,9 @@ public class FileConfig extends AbstractConfig {
/**
* 更新配置文件
*
* @param newCfg
* 新的配置文件
* @param oldCfg
* 老的配置文件
* @param force
* 是否强制更新
* @param newCfg 新的配置文件
* @param oldCfg 老的配置文件
* @param force 是否强制更新
* @return 更新以后的配置文件
*/
protected FileConfig updateConfig(FileConfig newCfg, FileConfig oldCfg, boolean force) {
@ -621,7 +577,8 @@ public class FileConfig extends AbstractConfig {
// 复制旧的数据
for (String string : oldConfigKeys) {
Object var = oldCfg.get(string);
if (var != null && !(var instanceof MemorySection)) {
// 需要进行节点检查 还有类型检查 不同类型情况下 使用新配置
if (var != null && !(var instanceof MemorySection) && newCfg.get(string).getClass().equals(var.getClass())) {
Log.debug(String.format(CONFIG_UPDATE_VALUE, string, var));
newCfg.set(string, var);
}

View File

@ -0,0 +1,22 @@
package pw.yumc.YumCore.config.exception;
/**
* 配置注入解析异常
*
* @author
* @since 2016年10月5日 下午5:15:43
*/
public class ConfigParseException extends RuntimeException {
public ConfigParseException(Exception e) {
super(e);
}
public ConfigParseException(String string) {
super(string);
}
public ConfigParseException(String string, Exception e) {
super(string, e);
}
}

View File

@ -12,23 +12,27 @@ import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.commands.exception.CommandParseException;
import pw.yumc.YumCore.config.annotation.ConfigNode;
import pw.yumc.YumCore.config.annotation.Default;
import pw.yumc.YumCore.config.annotation.Nullable;
import pw.yumc.YumCore.config.exception.ConfigParseException;
/**
* 抽象注入配置
*
* @since 2016年7月5日 上午10:11:22
* @author
* @since 2016年7月5日 上午10:11:22
*/
public abstract class AbstractInjectConfig {
private static String INJECT_TYPE_ERROR = "配置节点 %s 数据类型不匹配 应该为: %s 但实际为: %s!";
private static String INJECT_ERROR = "自动注入配置失败 可能造成插件运行错误 %s: %s!";
private static String DATE_PARSE_ERROR = "配置节点 {0} 日期解析失败 格式应该为: {1} 但输入值为: {2}!";
private static String PATH_NOT_FOUND = "配置节点 %s 丢失 将使用默认值!";
private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
static {
}
private ConfigurationSection config;
/**
@ -122,17 +126,9 @@ public abstract class AbstractInjectConfig {
* @throws NoSuchMethodException
* @throws SecurityException
*/
private Object convertType(Class<?> type, String path, Object value) throws ParseException, IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException {
switch (type.getName()) {
case "java.util.Date":
return df.parse((String) value);
case "java.util.List":
return config.getList(path);
case "java.util.Map":
return config.getConfigurationSection(path).getValues(true);
default:
return hanldeDefault(type, path, value);
}
private Object convertType(Class<?> type, String path, Object value) throws CommandParseException, IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException {
Object result = InjectParse.parse(type, config, path);
return result == null ? hanldeDefault(type, path, value) : result;
}
/**
@ -179,7 +175,7 @@ public abstract class AbstractInjectConfig {
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
private void hanldeValue(String path, Field field, Object value) throws IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException, ParseException {
private void hanldeValue(String path, Field field, Object value) throws IllegalAccessException, IllegalArgumentException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException, ConfigParseException {
Class<?> type = field.getType();
if (!type.equals(value.getClass())) {
value = convertType(type, path, value);
@ -232,10 +228,10 @@ public abstract class AbstractInjectConfig {
}
hanldeValue(path, field, value);
} catch (IllegalArgumentException ex) {
Log.w(INJECT_TYPE_ERROR, path, field.getType().getName(), value.getClass().getName());
Log.w(INJECT_TYPE_ERROR, path, field.getType().getName(), value != null ? value.getClass().getName() : "空指针");
Log.debug(ex);
} catch (ParseException e) {
Log.w(DATE_PARSE_ERROR, path, DATE_FORMAT, value);
} catch (ConfigParseException e) {
Log.w(e.getMessage());
} catch (InstantiationException | InvocationTargetException | NoSuchMethodException | SecurityException | IllegalAccessException ex) {
Log.w(INJECT_ERROR, ex.getClass().getName(), ex.getMessage());
Log.debug(ex);

View File

@ -0,0 +1,90 @@
package pw.yumc.YumCore.config.inject;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.bukkit.configuration.ConfigurationSection;
import pw.yumc.YumCore.config.exception.ConfigParseException;
/**
* 注入配置类解析
*
* @author
* @since 2016年10月16日 下午3:26:48
*/
public class InjectParse {
private static String DATE_PARSE_ERROR = "配置节点 {0} 日期解析失败 格式应该为: {1} 但输入值为: {2}!";
private static String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
private static SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT);
private static Map<Class, Parse> allparse = new HashMap<>();
static {
new ListParse();
new MapParse();
new DateParse();
}
public static Object parse(Class clazz, ConfigurationSection config, String path) {
return allparse.containsKey(clazz) ? allparse.get(clazz).parse(config, path) : null;
}
/**
* 配置解析注册
*
* @param clazz
*
* @param parse
* 解析类
*/
public static void register(Class clazz, Parse parse) {
allparse.put(clazz, parse);
}
public static class DateParse implements Parse<Date> {
public DateParse() {
allparse.put(Date.class, this);
}
@Override
public Date parse(ConfigurationSection config, String path) {
String value = "0000-00-00 00:00:00";
try {
value = config.getString(path);
return df.parse(value);
} catch (ParseException e) {
throw new ConfigParseException(String.format(DATE_PARSE_ERROR, path, DATE_FORMAT, value), e);
}
}
}
public static class ListParse implements Parse<List> {
public ListParse() {
allparse.put(List.class, this);
}
@Override
public List parse(ConfigurationSection config, String path) {
return config.getList(path);
}
}
public static class MapParse implements Parse<Map> {
public MapParse() {
allparse.put(Map.class, this);
}
@Override
public Map parse(ConfigurationSection config, String path) {
return config.getConfigurationSection(path).getValues(true);
}
}
public static interface Parse<FC> {
public FC parse(ConfigurationSection config, String path);
}
}

View File

@ -15,6 +15,9 @@ import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import pw.yumc.YumCore.bukkit.Log;
import pw.yumc.YumCore.bukkit.P;
import pw.yumc.YumCore.config.inject.InjectParse;
import pw.yumc.YumCore.config.inject.InjectParse.Parse;
import pw.yumc.YumCore.sql.core.DataBaseCore;
import pw.yumc.YumCore.sql.core.KeyValue;
import pw.yumc.YumCore.sql.core.MySQLCore;
@ -231,29 +234,6 @@ public class DataBase {
}
// @SuppressWarnings("unchecked")
// public <M> List<M> dbSelect( Class<? extends Model<?>> model, KeyValue selCondition) {
// List<M> modellist = new ArrayList<>();
// String sql = "SELECT " + toKeys(model) + " FROM `" + model.getAnnotation(Entity.class).name() + "`" + (selCondition == null ? "" : " WHERE " + selCondition.toWhereString());
// try {
// ResultSet dbresult = this.dataBaseCore.execute(sql);
// while (dbresult.next()) {
// M m = (M) model.newInstance();
// Field[] fields = model.getDeclaredFields();
// for ( Field col : fields) {
// col.set(m, dbresult.getObject(col.getName()));
// }
// modellist.add(m);
// }
// } catch ( InstantiationException e) {
// info("模型类实例化失败!");
// e.printStackTrace();
// } catch ( Exception e) {
// sqlerr(sql, e);
// }
// return modellist;
// }
/**
* 对数据库表进行选择操作
*
@ -283,6 +263,29 @@ public class DataBase {
return kvlist;
}
// @SuppressWarnings("unchecked")
// public <M> List<M> dbSelect( Class<? extends Model<?>> model, KeyValue selCondition) {
// List<M> modellist = new ArrayList<>();
// String sql = "SELECT " + toKeys(model) + " FROM `" + model.getAnnotation(Entity.class).name() + "`" + (selCondition == null ? "" : " WHERE " + selCondition.toWhereString());
// try {
// ResultSet dbresult = this.dataBaseCore.execute(sql);
// while (dbresult.next()) {
// M m = (M) model.newInstance();
// Field[] fields = model.getDeclaredFields();
// for ( Field col : fields) {
// col.set(m, dbresult.getObject(col.getName()));
// }
// modellist.add(m);
// }
// } catch ( InstantiationException e) {
// info("模型类实例化失败!");
// e.printStackTrace();
// } catch ( Exception e) {
// sqlerr(sql, e);
// }
// return modellist;
// }
/**
* 对数据库表进行选择操作
*
@ -489,6 +492,17 @@ public class DataBase {
Log.info(info);
}
public static class DataBaseParse implements Parse<DataBase> {
public DataBaseParse() {
InjectParse.register(DataBase.class, this);
}
@Override
public DataBase parse(ConfigurationSection config, String path) {
return DataBase.create(P.instance, config.getConfigurationSection(path));
}
}
// private String toKeys( Class<? extends Model<?>> model) {
// Field[] fields = model.getDeclaredFields();
// StringBuilder sb = new StringBuilder();