mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2025-01-23 00:21:30 +01:00
Added annotation handling to the flatfile database handler.
Currently it handles the @ConfigEntry path and specificTo fields. Experimental: There is a class called Setting2.java. It has an annotation that defines its filename as config.yml. Currently, it is using the database folder as its location, but it could be the plugin's datafolder in the future. By placing the config.yml file in the database folder, it will be read. See the code in BSkyBlock onEnable() for how that is done. The main differences between Settings2.java and Settings.java are that all fields are NOT static and therefore it is an object and uses getters and setters. This is because it is a JavaBean. In other code, settings should be queried using this config object.
This commit is contained in:
parent
478968dac7
commit
2d447afa88
@ -45,6 +45,16 @@ public class BSkyBlock extends JavaPlugin {
|
||||
public void onEnable(){
|
||||
plugin = this;
|
||||
|
||||
// Load config - EXPERIMENTAL
|
||||
Settings2 config = new Settings2();
|
||||
try {
|
||||
//config.saveConfig(); // works, but will wipe out comments
|
||||
config = config.loadConfig();
|
||||
getLogger().info("DEBUG: island distance = " + config.getIslandDistance());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Load configuration and locales. If there are no errors, load the plugin.
|
||||
if(PluginConfig.loadPluginConfig(this)){
|
||||
|
||||
|
@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType;
|
||||
import us.tastybento.bskyblock.api.configuration.ISettings;
|
||||
import us.tastybento.bskyblock.api.flags.Flag;
|
||||
import us.tastybento.bskyblock.database.BSBDatabase.DatabaseType;
|
||||
@ -21,10 +22,6 @@ import us.tastybento.bskyblock.database.BSBDatabase.DatabaseType;
|
||||
public class Settings implements ISettings {
|
||||
// ----------------- Constants -----------------
|
||||
|
||||
// Game Type BSKYBLOCK or ACIDISLAND
|
||||
public enum GameType {
|
||||
BSKYBLOCK, ACIDISLAND, BOTH
|
||||
}
|
||||
/*
|
||||
public final static GameType GAMETYPE = GameType.ACIDISLAND;
|
||||
// The spawn command (Essentials spawn for example)
|
||||
|
1115
src/main/java/us/tastybento/bskyblock/Settings2.java
Normal file
1115
src/main/java/us/tastybento/bskyblock/Settings2.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -5,8 +5,6 @@ import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import us.tastybento.bskyblock.Settings.GameType;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
@ -25,4 +23,9 @@ public @interface ConfigEntry {
|
||||
Class<?> adapter() default NoAdapter.class;
|
||||
|
||||
public class NoAdapter {}
|
||||
|
||||
// Game Type BSKYBLOCK or ACIDISLAND
|
||||
public enum GameType {
|
||||
BSKYBLOCK, ACIDISLAND, BOTH
|
||||
}
|
||||
}
|
@ -1,8 +1,36 @@
|
||||
package us.tastybento.bskyblock.api.configuration;
|
||||
|
||||
import java.beans.IntrospectionException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.Settings2;
|
||||
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
|
||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
||||
|
||||
/**
|
||||
* Simple interface for tagging all classes containing ConfigEntries.
|
||||
*
|
||||
* @author Poslovitch
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ISettings {}
|
||||
public interface ISettings<T> {
|
||||
|
||||
// ----------------Saver-------------------
|
||||
@SuppressWarnings("unchecked")
|
||||
public default void saveConfig(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
|
||||
// Get the handler
|
||||
AbstractDatabaseHandler<T> configHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), instance.getClass());
|
||||
// Load every field in the config class
|
||||
configHandler.saveObject(instance); // The string parameter can be anything
|
||||
}
|
||||
// --------------- Loader ------------------
|
||||
@SuppressWarnings("unchecked")
|
||||
public default Settings2 loadConfig() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, ClassNotFoundException, IntrospectionException, SQLException {
|
||||
// Get the handler
|
||||
AbstractDatabaseHandler<Settings2> configHandler = (AbstractDatabaseHandler<Settings2>) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), Settings2.class);
|
||||
// Load every field in the config class
|
||||
return configHandler.loadObject("config");
|
||||
}
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import org.bukkit.Bukkit;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.Settings;
|
||||
import us.tastybento.bskyblock.Settings.GameType;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.NoAdapter;
|
||||
|
||||
public class ConfigLoader {
|
||||
|
27
src/main/java/us/tastybento/bskyblock/config/StoreAt.java
Normal file
27
src/main/java/us/tastybento/bskyblock/config/StoreAt.java
Normal file
@ -0,0 +1,27 @@
|
||||
package us.tastybento.bskyblock.config;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Defines where this data object will be stored.
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface StoreAt {
|
||||
|
||||
/**
|
||||
* Path where this will be stored. If blank, it will be the BSkyBlock database folder.
|
||||
*/
|
||||
String path() default "";
|
||||
|
||||
/**
|
||||
* Filename
|
||||
*/
|
||||
String filename() default "";
|
||||
|
||||
}
|
@ -77,11 +77,11 @@ public class FlatFileDatabaseConnecter implements DatabaseConnecter {
|
||||
/**
|
||||
* Saves a YAML file
|
||||
*
|
||||
* @param yamlFile
|
||||
* @param yamlConfig
|
||||
* @param fileName
|
||||
*/
|
||||
@Override
|
||||
public void saveYamlFile(YamlConfiguration yamlFile, String tableName, String fileName) {
|
||||
public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName) {
|
||||
if (!fileName.endsWith(".yml")) {
|
||||
fileName = fileName + ".yml";
|
||||
}
|
||||
@ -91,7 +91,7 @@ public class FlatFileDatabaseConnecter implements DatabaseConnecter {
|
||||
tableFolder.mkdirs();
|
||||
}
|
||||
try {
|
||||
yamlFile.save(file);
|
||||
yamlConfig.save(file);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -17,12 +17,18 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import us.tastybento.bskyblock.Settings;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.NoAdapter;
|
||||
import us.tastybento.bskyblock.config.StoreAt;
|
||||
import us.tastybento.bskyblock.database.DatabaseConnecter;
|
||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
||||
import us.tastybento.bskyblock.util.Util;
|
||||
@ -39,6 +45,7 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
|
||||
private static final String DATABASE_FOLDER_NAME = "database";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
public FlatFileDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
||||
super(plugin, type, databaseConnecter);
|
||||
}
|
||||
@ -70,13 +77,20 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
*/
|
||||
@Override
|
||||
public T loadObject(String key) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException, ClassNotFoundException {
|
||||
YamlConfiguration config = databaseConnecter.loadYamlFile(type.getSimpleName(), key);
|
||||
String path = dataObject.getSimpleName();
|
||||
String fileName = key;
|
||||
StoreAt storeAt = dataObject.getAnnotation(StoreAt.class);
|
||||
if (storeAt != null) {
|
||||
path = storeAt.path();
|
||||
fileName = storeAt.filename();
|
||||
}
|
||||
YamlConfiguration config = databaseConnecter.loadYamlFile(path, fileName);
|
||||
return createObject(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean objectExits(String key) {
|
||||
return databaseConnecter.uniqueIdExists(type.getSimpleName(), key);
|
||||
return databaseConnecter.uniqueIdExists(dataObject.getSimpleName(), key);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -103,14 +117,23 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
}
|
||||
}
|
||||
};
|
||||
String path = dataObject.getSimpleName();
|
||||
StoreAt storeAt = dataObject.getAnnotation(StoreAt.class);
|
||||
if (storeAt != null) {
|
||||
path = storeAt.path();
|
||||
}
|
||||
File dataFolder = new File(plugin.getDataFolder(), DATABASE_FOLDER_NAME);
|
||||
File tableFolder = new File(dataFolder, type.getSimpleName());
|
||||
File tableFolder = new File(dataFolder, path);
|
||||
if (!tableFolder.exists()) {
|
||||
// Nothing there...
|
||||
tableFolder.mkdirs();
|
||||
}
|
||||
for (File file: tableFolder.listFiles(ymlFilter)) {
|
||||
YamlConfiguration config = databaseConnecter.loadYamlFile(type.getSimpleName(), file.getName());
|
||||
String fileName = file.getName();
|
||||
if (storeAt != null) {
|
||||
fileName = storeAt.filename();
|
||||
}
|
||||
YamlConfiguration config = databaseConnecter.loadYamlFile(dataObject.getSimpleName(), fileName);
|
||||
list.add(createObject(config));
|
||||
}
|
||||
return list;
|
||||
@ -131,15 +154,33 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
* @throws ClassNotFoundException
|
||||
*/
|
||||
private T createObject(YamlConfiguration config) throws InstantiationException, IllegalAccessException, IntrospectionException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException {
|
||||
T instance = type.newInstance();
|
||||
T instance = dataObject.newInstance();
|
||||
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
// Run through all the fields in the object
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
// Gets the getter and setters for this field
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
// Get the write method
|
||||
Method method = propertyDescriptor.getWriteMethod();
|
||||
if (DEBUG)
|
||||
plugin.getLogger().info("DEBUG: " + field.getName() + ": " + propertyDescriptor.getPropertyType().getTypeName());
|
||||
if (config.contains(field.getName())) {
|
||||
String storageLocation = field.getName();
|
||||
// Check if there is an annotation on the field
|
||||
ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class);
|
||||
// If there is a config annotation then do something
|
||||
if (configEntry != null) {
|
||||
if (!configEntry.path().isEmpty()) {
|
||||
storageLocation = configEntry.path();
|
||||
}
|
||||
if (!configEntry.specificTo().equals(GameType.BOTH) && !configEntry.specificTo().equals(Settings.GAMETYPE)) {
|
||||
Bukkit.getLogger().info(field.getName() + " not applicable to this game type");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Look in the YAML Config to see if this field exists (it should)
|
||||
if (config.contains(storageLocation)) {
|
||||
// Handle storage of maps. Check if this type is a Map
|
||||
if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
||||
// Note that we have no idea what type this is
|
||||
List<Type> collectionTypes = Util.getCollectionParameterTypes(method);
|
||||
@ -150,9 +191,9 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
plugin.getLogger().info("DEBUG: is Map or HashMap<" + keyType.getTypeName() + ", " + valueType.getTypeName() + ">");
|
||||
// TODO: this may not work with all keys. Further serialization may be required.
|
||||
Map<Object,Object> value = new HashMap<Object, Object>();
|
||||
for (String key : config.getConfigurationSection(field.getName()).getKeys(false)) {
|
||||
for (String key : config.getConfigurationSection(storageLocation).getKeys(false)) {
|
||||
Object mapKey = deserialize(key,Class.forName(keyType.getTypeName()));
|
||||
Object mapValue = deserialize(config.get(field.getName() + "." + key), Class.forName(valueType.getTypeName()));
|
||||
Object mapValue = deserialize(config.get(storageLocation + "." + key), Class.forName(valueType.getTypeName()));
|
||||
if (DEBUG) {
|
||||
plugin.getLogger().info("DEBUG: mapKey = " + mapKey + " (" + mapKey.getClass().getCanonicalName() + ")");
|
||||
plugin.getLogger().info("DEBUG: mapValue = " + mapValue + " (" + mapValue.getClass().getCanonicalName() + ")");
|
||||
@ -177,13 +218,13 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
plugin.getLogger().info("DEBUG: collection type argument = " + collectionTypes);
|
||||
plugin.getLogger().info("DEBUG: setType = " + setType.getTypeName());
|
||||
}
|
||||
for (Object listValue: config.getList(field.getName())) {
|
||||
for (Object listValue: config.getList(storageLocation)) {
|
||||
//plugin.getLogger().info("DEBUG: collectionResultSet size = " + collectionResultSet.getFetchSize());
|
||||
((Set<Object>) value).add(deserialize(listValue,Class.forName(setType.getTypeName())));
|
||||
}
|
||||
|
||||
// TODO: this may not work with all keys. Further serialization may be required.
|
||||
//Set<Object> value = new HashSet((List<Object>) config.getList(field.getName()));
|
||||
//Set<Object> value = new HashSet((List<Object>) config.getList(storageLocation));
|
||||
method.invoke(instance, value);
|
||||
} else if (List.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
||||
//plugin.getLogger().info("DEBUG: is Set " + propertyDescriptor.getReadMethod().getGenericReturnType().getTypeName());
|
||||
@ -197,18 +238,18 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
List<Object> value = new ArrayList<Object>();
|
||||
//plugin.getLogger().info("DEBUG: collection type argument = " + collectionTypes);
|
||||
//plugin.getLogger().info("DEBUG: setType = " + setType.getTypeName());
|
||||
for (Object listValue: config.getList(field.getName())) {
|
||||
for (Object listValue: config.getList(storageLocation)) {
|
||||
//plugin.getLogger().info("DEBUG: collectionResultSet size = " + collectionResultSet.getFetchSize());
|
||||
((List<Object>) value).add(deserialize(listValue,Class.forName(setType.getTypeName())));
|
||||
}
|
||||
// TODO: this may not work with all keys. Further serialization may be required.
|
||||
//Set<Object> value = new HashSet((List<Object>) config.getList(field.getName()));
|
||||
//Set<Object> value = new HashSet((List<Object>) config.getList(storageLocation));
|
||||
method.invoke(instance, value);
|
||||
} else {
|
||||
// Not a collection
|
||||
if (DEBUG)
|
||||
plugin.getLogger().info("DEBUG: not a collection");
|
||||
Object value = config.get(field.getName());
|
||||
Object value = config.get(storageLocation);
|
||||
if (DEBUG) {
|
||||
plugin.getLogger().info("DEBUG: value = " + value);
|
||||
plugin.getLogger().info("DEBUG: property type = " + propertyDescriptor.getPropertyType());
|
||||
@ -238,17 +279,33 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
public void saveObject(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
||||
// This is the Yaml Configuration that will be used and saved at the end
|
||||
YamlConfiguration config = new YamlConfiguration();
|
||||
|
||||
// The file name of the Yaml file.
|
||||
String filename = "";
|
||||
String path = dataObject.getSimpleName();
|
||||
StoreAt storeAt = instance.getClass().getAnnotation(StoreAt.class);
|
||||
if (storeAt != null) {
|
||||
path = storeAt.path();
|
||||
filename = storeAt.filename();
|
||||
}
|
||||
|
||||
// Run through all the fields in the class that is being stored. EVERY field must have a get and set method
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
|
||||
String storageLocation = field.getName();
|
||||
// Check if there is an annotation on the field
|
||||
ConfigEntry configEntry = field.getAnnotation(ConfigEntry.class);
|
||||
// If there is a config path annotation then do something
|
||||
if (configEntry != null && !configEntry.path().isEmpty()) {
|
||||
storageLocation = configEntry.path();
|
||||
}
|
||||
// Get the property descriptor for this field
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
// Get the read method, i.e., getXXXX();
|
||||
Method method = propertyDescriptor.getReadMethod();
|
||||
// Invoke the read method to get the value. We have no idea what type of value it is.
|
||||
Object value = method.invoke(instance);
|
||||
//plugin.getLogger().info("DEBUG: writing " + field.getName());
|
||||
|
||||
//plugin.getLogger().info("DEBUG: property desc = " + propertyDescriptor.getPropertyType().getTypeName());
|
||||
// Depending on the vale type, it'll need serializing differenty
|
||||
// Check if this field is the mandatory UniqueId field. This is used to identify this instantiation of the class
|
||||
@ -257,17 +314,18 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
//plugin.getLogger().info("DEBUG: uniqueId = " + value);
|
||||
String id = (String)value;
|
||||
if (id.isEmpty()) {
|
||||
id = databaseConnecter.getUniqueId(type.getSimpleName());
|
||||
id = databaseConnecter.getUniqueId(dataObject.getSimpleName());
|
||||
// Set it in the class so that it will be used next time
|
||||
propertyDescriptor.getWriteMethod().invoke(instance, id);
|
||||
}
|
||||
// Save the name for when the file is saved
|
||||
filename = id;
|
||||
if (filename.isEmpty())
|
||||
filename = id;
|
||||
}
|
||||
// Collections need special serialization
|
||||
if (propertyDescriptor.getPropertyType().equals(HashMap.class) || propertyDescriptor.getPropertyType().equals(Map.class)) {
|
||||
if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
||||
// Maps need to have keys serialized
|
||||
//plugin.getLogger().info("DEBUG: Map for " + field.getName());
|
||||
//plugin.getLogger().info("DEBUG: Map for " + storageLocation);
|
||||
if (value != null) {
|
||||
Map<Object, Object> result = new HashMap<Object, Object>();
|
||||
for (Entry<Object, Object> object : ((Map<Object,Object>)value).entrySet()) {
|
||||
@ -276,31 +334,29 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
result.put(serialize(object.getKey()), object.getValue());
|
||||
}
|
||||
// Save the list in the config file
|
||||
config.set(field.getName(), result);
|
||||
config.set(storageLocation, result);
|
||||
}
|
||||
} else if (propertyDescriptor.getPropertyType().equals(Set.class)) {
|
||||
} else if (Set.class.isAssignableFrom(propertyDescriptor.getPropertyType())) {
|
||||
// Sets need to be serialized as string lists
|
||||
if (DEBUG)
|
||||
plugin.getLogger().info("DEBUG: Set for " + field.getName());
|
||||
plugin.getLogger().info("DEBUG: Set for " + storageLocation);
|
||||
if (value != null) {
|
||||
List<Object> list = new ArrayList<Object>();
|
||||
for (Object object : (Set<Object>)value) {
|
||||
list.add(serialize(object));
|
||||
}
|
||||
// Save the list in the config file
|
||||
config.set(field.getName(), list);
|
||||
config.set(storageLocation, list);
|
||||
}
|
||||
} else {
|
||||
// For all other data that doesn't need special serialization
|
||||
config.set(field.getName(), serialize(value));
|
||||
config.set(storageLocation, serialize(value));
|
||||
}
|
||||
}
|
||||
if (filename.isEmpty()) {
|
||||
throw new IllegalArgumentException("No uniqueId in class");
|
||||
}
|
||||
// Save the file in the right folder
|
||||
databaseConnecter.saveYamlFile(config, type.getSimpleName(), filename);
|
||||
|
||||
databaseConnecter.saveYamlFile(config, path, filename);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -379,14 +435,14 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
@Override
|
||||
public void deleteObject(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
|
||||
// The file name of the Yaml file.
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
|
||||
Method method = propertyDescriptor.getReadMethod();
|
||||
String fileName = (String) method.invoke(instance);
|
||||
if (!fileName.endsWith(".yml")) {
|
||||
fileName = fileName + ".yml";
|
||||
}
|
||||
File dataFolder = new File(plugin.getDataFolder(), DATABASE_FOLDER_NAME);
|
||||
File tableFolder = new File(dataFolder, type.getSimpleName());
|
||||
File tableFolder = new File(dataFolder, dataObject.getSimpleName());
|
||||
if (tableFolder.exists()) {
|
||||
File file = new File(tableFolder, fileName);
|
||||
file.delete();
|
||||
|
@ -19,10 +19,10 @@ import us.tastybento.bskyblock.database.DatabaseConnecter;
|
||||
public abstract class AbstractDatabaseHandler<T> {
|
||||
|
||||
/**
|
||||
* The type of the objects that should be created and filled with values
|
||||
* The data object that should be created and filled with values
|
||||
* from the database or inserted into the database
|
||||
*/
|
||||
protected Class<T> type;
|
||||
protected Class<T> dataObject;
|
||||
|
||||
/**
|
||||
* Contains the settings to create a connection to the database like
|
||||
@ -52,7 +52,7 @@ public abstract class AbstractDatabaseHandler<T> {
|
||||
protected AbstractDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
|
||||
this.plugin = plugin;
|
||||
this.databaseConnecter = databaseConnecter;
|
||||
this.type = type;
|
||||
this.dataObject = type;
|
||||
this.selectQuery = createSelectQuery();
|
||||
this.insertQuery = createInsertQuery();
|
||||
this.deleteQuery = createDeleteQuery();
|
||||
|
@ -125,11 +125,11 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
private void createSchema() throws IntrospectionException, SQLException {
|
||||
PreparedStatement pstmt = null;
|
||||
try {
|
||||
String sql = "CREATE TABLE IF NOT EXISTS `" + type.getCanonicalName() + "` (";
|
||||
String sql = "CREATE TABLE IF NOT EXISTS `" + dataObject.getCanonicalName() + "` (";
|
||||
// Run through the fields of the class using introspection
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
// Get the description of the field
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
//plugin.getLogger().info("DEBUG: Field = " + field.getName() + "(" + propertyDescriptor.getPropertyType().getTypeName() + ")");
|
||||
// Get default SQL mappings
|
||||
// Get the write method for this field. This method will take an argument of the type of this field.
|
||||
@ -152,7 +152,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
propertyDescriptor.getPropertyType().equals(HashMap.class) ||
|
||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
||||
// The ID in this table relates to the parent table and is unique
|
||||
String setSql = "CREATE TABLE IF NOT EXISTS `" + type.getCanonicalName() + "." + field.getName() + "` ("
|
||||
String setSql = "CREATE TABLE IF NOT EXISTS `" + dataObject.getCanonicalName() + "." + field.getName() + "` ("
|
||||
+ "uniqueId VARCHAR(36) NOT NULL, ";
|
||||
// Get columns separated by commas
|
||||
setSql += getCollectionColumnString(writeMethod,false,true);
|
||||
@ -207,7 +207,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
|
||||
boolean first = true;
|
||||
/* Iterate the column-names */
|
||||
for (Field f : type.getDeclaredFields()) {
|
||||
for (Field f : dataObject.getDeclaredFields()) {
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
@ -321,7 +321,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
sb.append(getColumns(false));
|
||||
sb.append(" FROM ");
|
||||
sb.append("`");
|
||||
sb.append(type.getCanonicalName());
|
||||
sb.append(dataObject.getCanonicalName());
|
||||
sb.append("`");
|
||||
|
||||
return sb.toString();
|
||||
@ -339,7 +339,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
sb.append("REPLACE INTO ");
|
||||
sb.append("`");
|
||||
// The table name is the canonical name, so that add-ons can be sure of a unique table in the database
|
||||
sb.append(type.getCanonicalName());
|
||||
sb.append(dataObject.getCanonicalName());
|
||||
sb.append("`");
|
||||
sb.append("(");
|
||||
sb.append(getColumns(false));
|
||||
@ -388,7 +388,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
// insertQuery is created in super from the createInsertQuery() method
|
||||
preparedStatement = connection.prepareStatement(insertQuery);
|
||||
// Get the uniqueId. As each class extends DataObject, it must have this method in it.
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor("uniqueId", dataObject);
|
||||
Method getUniqueId = propertyDescriptor.getReadMethod();
|
||||
final String uniqueId = (String) getUniqueId.invoke(instance);
|
||||
if (DEBUG) {
|
||||
@ -402,9 +402,9 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
if (DEBUG)
|
||||
plugin.getLogger().info("DEBUG: insert Query " + insertQuery);
|
||||
// Run through the fields in the class using introspection
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
// Get the field's property descriptor
|
||||
propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
// Get the read method for this field
|
||||
Method method = propertyDescriptor.getReadMethod();
|
||||
if (DEBUG)
|
||||
@ -421,14 +421,14 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
||||
// Collection
|
||||
// The table is cleared for this uniqueId every time the data is stored
|
||||
String clearTableSql = "DELETE FROM `" + type.getCanonicalName() + "." + field.getName() + "` WHERE uniqueId = ?";
|
||||
String clearTableSql = "DELETE FROM `" + dataObject.getCanonicalName() + "." + field.getName() + "` WHERE uniqueId = ?";
|
||||
PreparedStatement collStatement = connection.prepareStatement(clearTableSql);
|
||||
collStatement.setString(1, uniqueId);
|
||||
collStatement.execute();
|
||||
if (DEBUG)
|
||||
plugin.getLogger().info("DEBUG: collStatement " + collStatement.toString());
|
||||
// Insert into the table
|
||||
String setSql = "INSERT INTO `" + type.getCanonicalName() + "." + field.getName() + "` (uniqueId, ";
|
||||
String setSql = "INSERT INTO `" + dataObject.getCanonicalName() + "." + field.getName() + "` (uniqueId, ";
|
||||
// Get the columns we are going to insert, just the names of them
|
||||
setSql += getCollectionColumnString(propertyDescriptor.getWriteMethod(), false, false) + ") ";
|
||||
// Get all the ?'s for the columns
|
||||
@ -602,7 +602,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
plugin.getLogger().info("DEBUG: loading object for " + uniqueId);
|
||||
try {
|
||||
connection = databaseConnecter.createConnection();
|
||||
String query = "SELECT " + getColumns(false) + " FROM `" + type.getCanonicalName() + "` WHERE uniqueId = ? LIMIT 1";
|
||||
String query = "SELECT " + getColumns(false) + " FROM `" + dataObject.getCanonicalName() + "` WHERE uniqueId = ? LIMIT 1";
|
||||
PreparedStatement preparedStatement = connection.prepareStatement(query);
|
||||
preparedStatement.setString(1, uniqueId);
|
||||
if (DEBUG)
|
||||
@ -653,18 +653,18 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
// Run through them one by one
|
||||
while (resultSet.next()) {
|
||||
// Create a new instance of this type
|
||||
T instance = type.newInstance();
|
||||
T instance = dataObject.newInstance();
|
||||
// Get the unique ID from the results
|
||||
String uniqueId = resultSet.getString("uniqueId");
|
||||
if (uniqueId == null) {
|
||||
throw new SQLException("No unique ID in the results!");
|
||||
}
|
||||
// Use introspection to run through all the fields in this type class
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
/* We assume the table-column-names exactly match the variable-names of T */
|
||||
Object value = resultSet.getObject(field.getName());
|
||||
// Get the property descriptor of this type
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
// Get the write method for this field, because we are going to use it to write the value
|
||||
// once we get the value from the database
|
||||
Method method = propertyDescriptor.getWriteMethod();
|
||||
@ -677,7 +677,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
String setSql = "SELECT ";
|
||||
// Get the columns, just the names of them, no ?'s or types
|
||||
setSql += getCollectionColumnString(method, false, false) + " ";
|
||||
setSql += "FROM `" + type.getCanonicalName() + "." + field.getName() + "` ";
|
||||
setSql += "FROM `" + dataObject.getCanonicalName() + "." + field.getName() + "` ";
|
||||
// We will need to fill in the ? later with the unique id of the class from the database
|
||||
setSql += "WHERE uniqueId = ?";
|
||||
// Prepare the statement
|
||||
@ -832,7 +832,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
// Try to connect to the database
|
||||
connection = databaseConnecter.createConnection();
|
||||
// Get the uniqueId. As each class extends DataObject, it must have this method in it.
|
||||
Method getUniqueId = type.getMethod("getUniqueId");
|
||||
Method getUniqueId = dataObject.getMethod("getUniqueId");
|
||||
String uniqueId = (String) getUniqueId.invoke(instance);
|
||||
//plugin.getLogger().info("DEBUG: Unique Id = " + uniqueId);
|
||||
if (uniqueId.isEmpty()) {
|
||||
@ -841,7 +841,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
// Delete from the main table
|
||||
// First substitution is the table name
|
||||
// deleteQuery is created in super from the createInsertQuery() method
|
||||
preparedStatement = connection.prepareStatement(deleteQuery.replace("[table_name]", "`" + type.getCanonicalName() + "`"));
|
||||
preparedStatement = connection.prepareStatement(deleteQuery.replace("[table_name]", "`" + dataObject.getCanonicalName() + "`"));
|
||||
// Second is the unique ID
|
||||
preparedStatement.setString(1, uniqueId);
|
||||
preparedStatement.addBatch();
|
||||
@ -850,16 +850,16 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
preparedStatement.executeBatch();
|
||||
// Delete from any sub tables created from the object
|
||||
// Run through the fields in the class using introspection
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
for (Field field : dataObject.getDeclaredFields()) {
|
||||
// Get the field's property descriptor
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), type);
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(field.getName(), dataObject);
|
||||
// Delete Collection tables
|
||||
if (propertyDescriptor.getPropertyType().equals(Set.class) ||
|
||||
propertyDescriptor.getPropertyType().equals(Map.class) ||
|
||||
propertyDescriptor.getPropertyType().equals(HashMap.class) ||
|
||||
propertyDescriptor.getPropertyType().equals(ArrayList.class)) {
|
||||
// First substitution is the table name
|
||||
preparedStatement = connection.prepareStatement(deleteQuery.replace("[table_name]", "`" + type.getCanonicalName() + "." + field.getName() + "`"));
|
||||
preparedStatement = connection.prepareStatement(deleteQuery.replace("[table_name]", "`" + dataObject.getCanonicalName() + "." + field.getName() + "`"));
|
||||
// Second is the unique ID
|
||||
preparedStatement.setString(1, uniqueId);
|
||||
preparedStatement.addBatch();
|
||||
@ -886,7 +886,7 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
|
||||
Connection connection = null;
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
String query = "SELECT IF ( EXISTS( SELECT * FROM `" + type.getCanonicalName() + "` WHERE `uniqueId` = ?), 1, 0)";
|
||||
String query = "SELECT IF ( EXISTS( SELECT * FROM `" + dataObject.getCanonicalName() + "` WHERE `uniqueId` = ?), 1, 0)";
|
||||
//String query = "SELECT * FROM `" + type.getCanonicalName() + "` WHERE uniqueId = ?";
|
||||
try {
|
||||
connection = databaseConnecter.createConnection();
|
||||
|
@ -16,9 +16,9 @@ import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.material.Chest;
|
||||
|
||||
import us.tastybento.bskyblock.api.commands.User;
|
||||
import us.tastybento.bskyblock.Settings;
|
||||
import us.tastybento.bskyblock.Settings.GameType;
|
||||
import us.tastybento.bskyblock.api.commands.User;
|
||||
import us.tastybento.bskyblock.api.configuration.ConfigEntry.GameType;
|
||||
import us.tastybento.bskyblock.database.objects.Island;
|
||||
import us.tastybento.bskyblock.generators.IslandWorld;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user