Added saveSettings and loadSettings methods.

These methods are used specifically for loading and saving settings
classes (those use the ISettings interface). The saving saves a copy of
any settings class in the database for future reference. The loading
loads a copy from the database if it exists and checks if any fields are
different from the config file. If they are different and some action
needs to be taken, the action is taken. This is still be to be coded.

In other news, the saving of arrays is unsupported and currently should
be avoided. Use Lists or Sets instead.
This commit is contained in:
Tastybento 2018-01-07 11:56:43 -08:00
parent 2765e5f3ab
commit 16bcb90127
12 changed files with 124 additions and 31 deletions

View File

@ -1,5 +1,7 @@
package us.tastybento.bskyblock;
import java.util.Arrays;
import org.bukkit.Material;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
@ -51,7 +53,7 @@ public class BSkyBlock extends JavaPlugin {
settings = new Settings();
// Load config - EXPERIMENTAL
try {
//settings.saveConfig(); -- doesn't work completely yet
settings.saveSettings(); //doesn't work completely yet
settings = settings.loadSettings();
getLogger().info("DEBUG: island distance = " + settings.getIslandDistance());
} catch (Exception e) {
@ -88,14 +90,14 @@ public class BSkyBlock extends JavaPlugin {
islandsManager.load();
// TODO: load these from config.yml
getSettings().setChestItems(new ItemStack[] {
getSettings().setChestItems(Arrays.asList(
new ItemStack(Material.LAVA_BUCKET,1),
new ItemStack(Material.ICE,2),
new ItemStack(Material.MELON_SEEDS,1),
new ItemStack(Material.BONE,2),
new ItemStack(Material.COBBLESTONE,5),
new ItemStack(Material.SAPLING,2)
});
));
//getSettings().setDefaultLanguage("en-US");
plugin.getLogger().info("DEBUG: ************************** Loading Locales **************************");

View File

@ -214,7 +214,7 @@ public class Settings implements ISettings<Settings> {
/* SCHEMATICS */
private List<String> companionNames = new ArrayList<>();
private ItemStack[] chestItems = {};
private List<ItemStack> chestItems = new ArrayList<>();
private EntityType companionType = EntityType.COW;
private boolean useOwnGenerator;
@ -222,7 +222,7 @@ public class Settings implements ISettings<Settings> {
private HashMap<String,Integer> limitedBlocks;
private boolean teamJoinDeathReset;
private String uniqueId = "";
private String uniqueId = "config";
/**
* @return the uniqueId
@ -1055,13 +1055,13 @@ public class Settings implements ISettings<Settings> {
/**
* @return the chestItems
*/
public ItemStack[] getChestItems() {
public List<ItemStack> getChestItems() {
return chestItems;
}
/**
* @param chestItems the chestItems to set
*/
public void setChestItems(ItemStack[] chestItems) {
public void setChestItems(List<ItemStack> chestItems) {
this.chestItems = chestItems;
}
/**

View File

@ -6,7 +6,7 @@ import java.sql.SQLException;
import org.bukkit.Bukkit;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.database.BSBDatabase;
import us.tastybento.bskyblock.database.flatfile.FlatFileDatabase;
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
@ -20,22 +20,47 @@ public interface ISettings<T> {
// ----------------Saver-------------------
@SuppressWarnings("unchecked")
default void saveConfig() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
default void saveSettings() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException {
// Get the handler
AbstractDatabaseHandler<T> configHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), getInstance().getClass());
AbstractDatabaseHandler<T> settingsHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(getInstance().getClass());
// Load every field in the config class
Bukkit.getLogger().info("DEBUG: configHandler = " + configHandler);
Bukkit.getLogger().info("DEBUG: settingsHandler = " + settingsHandler);
Bukkit.getLogger().info("DEBUG: instance = " + getInstance());
configHandler.saveObject(getInstance()); // The string parameter can be anything
settingsHandler.saveSettings(getInstance());
// Save backup in real database
AbstractDatabaseHandler<T> dbhandler = (AbstractDatabaseHandler<T>) BSBDatabase.getDatabase().getHandler(getInstance().getClass());
dbhandler.saveObject(getInstance());
}
// --------------- Loader ------------------
@SuppressWarnings("unchecked")
default T loadSettings() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, ClassNotFoundException, IntrospectionException, SQLException {
// See if this settings object already exists in the database
AbstractDatabaseHandler<T> dbhandler = (AbstractDatabaseHandler<T>) BSBDatabase.getDatabase().getHandler(this.getClass());
T dbConfig = null;
if (dbhandler.objectExits(this.getUniqueId())) {
// Load it
dbConfig = dbhandler.loadObject(getUniqueId());
}
// Get the handler
AbstractDatabaseHandler<T> configHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(BSkyBlock.getInstance(), getInstance().getClass());
AbstractDatabaseHandler<T> configHandler = (AbstractDatabaseHandler<T>) new FlatFileDatabase().getHandler(getInstance().getClass());
// Load every field in the config class
return configHandler.loadObject("config");
return configHandler.loadSettings(getUniqueId(), dbConfig);
}
/**
* @return instance of the implementing class, i.e., return this.
*/
T getInstance();
/**
* @return the uniqueId
*/
String getUniqueId();
/**
* @param uniqueId the uniqueId to set
*/
void setUniqueId(String uniqueId);
}

View File

@ -36,6 +36,6 @@ public abstract class BSBDatabase {
* @param dataObjectClass
* @return database handler
*/
public abstract AbstractDatabaseHandler<?> getHandler(BSkyBlock plugin, Class<?> dataObjectClass);
public abstract AbstractDatabaseHandler<?> getHandler(Class<?> dataObjectClass);
}

View File

@ -7,8 +7,8 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
public class FlatFileDatabase extends BSBDatabase{
@Override
public AbstractDatabaseHandler<?> getHandler(BSkyBlock plugin, Class<?> type) {
return new FlatFileDatabaseHandler<>(plugin, type, new FlatFileDatabaseConnecter(plugin, null));
public AbstractDatabaseHandler<?> getHandler(Class<?> type) {
return new FlatFileDatabaseHandler<>(BSkyBlock.getInstance(), type, new FlatFileDatabaseConnecter(BSkyBlock.getInstance(), null));
}
}

View File

@ -45,6 +45,7 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
private static final String DATABASE_FOLDER_NAME = "database";
private static final boolean DEBUG = false;
private boolean configFlag;
public FlatFileDatabaseHandler(Plugin plugin, Class<T> type, DatabaseConnecter databaseConnecter) {
super(plugin, type, databaseConnecter);
@ -273,9 +274,10 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
plugin.getLogger().info("DEBUG: not a collection");
Object value = config.get(storageLocation);
if (DEBUG) {
plugin.getLogger().info("DEBUG: name = " + field.getName());
plugin.getLogger().info("DEBUG: value = " + value);
plugin.getLogger().info("DEBUG: property type = " + propertyDescriptor.getPropertyType());
plugin.getLogger().info("DEBUG: " + value.getClass());
plugin.getLogger().info("DEBUG: value class " + value.getClass());
}
if (value != null && !value.getClass().equals(MemorySection.class)) {
method.invoke(instance, deserialize(value,propertyDescriptor.getPropertyType()));
@ -287,6 +289,14 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
return instance;
}
/* (non-Javadoc)
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#saveConfig(java.lang.Object)
*/
public void saveSettings(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
configFlag = true;
saveObject(instance);
}
/**
* Inserts T into the corresponding database-table
*
@ -305,12 +315,16 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
// 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();
}
// Only allow storing in an arbitrary place if it is a config object. Otherwise it is in the database
if (configFlag) {
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 : dataObject.getDeclaredFields()) {
@ -484,4 +498,16 @@ public class FlatFileDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
}
}
/* (non-Javadoc)
* @see us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler#loadSettings(java.lang.String, java.lang.Object)
*/
@Override
public T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
if (dbConfig == null) return loadObject(uniqueId);
// TODO: compare the loaded with the database copy
return loadObject(uniqueId);
}
}

View File

@ -132,4 +132,28 @@ public abstract class AbstractDatabaseHandler<T> {
*/
public abstract boolean objectExits(String key);
/**
* Saves a file as settings
* @param instance
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws IntrospectionException
*/
public abstract void saveSettings(T instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException;
/**
* Loads a file as settings
* @param uniqueId
* @param dbConfig - the database mirror of this object. It will be checked against what is loaded to see if any significant changes have been made
* @return
* @throws InstantiationException
* @throws IllegalAccessException
* @throws IllegalArgumentException
* @throws InvocationTargetException
* @throws ClassNotFoundException
* @throws IntrospectionException
*/
public abstract T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException;
}

View File

@ -42,7 +42,7 @@ public class PlayersManager{
this.plugin = plugin;
database = BSBDatabase.getDatabase();
// Set up the database handler to store and retrieve Players classes
handler = (AbstractDatabaseHandler<Players>) database.getHandler(plugin, Players.class);
handler = (AbstractDatabaseHandler<Players>) database.getHandler(Players.class);
playerCache = new HashMap<>();
inTeleport = new HashSet<>();
}

View File

@ -142,7 +142,7 @@ public class IslandsManager {
this.plugin = plugin;
database = BSBDatabase.getDatabase();
// Set up the database handler to store and retrieve Island classes
handler = (AbstractDatabaseHandler<Island>) database.getHandler(plugin, Island.class);
handler = (AbstractDatabaseHandler<Island>) database.getHandler(Island.class);
islandCache = new IslandCache();
spawn = null;
}

View File

@ -8,7 +8,8 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
public class MySQLDatabase extends BSBDatabase{
@Override
public AbstractDatabaseHandler<?> getHandler(BSkyBlock plugin, Class<?> type) {
public AbstractDatabaseHandler<?> getHandler(Class<?> type) {
BSkyBlock plugin = BSkyBlock.getInstance();
return new MySQLDatabaseHandler<>(plugin, type, new MySQLDatabaseConnecter(new DatabaseConnectionSettingsImpl(
plugin.getSettings().getDbHost(),
plugin.getSettings().getDbPort(),

View File

@ -910,4 +910,18 @@ public class MySQLDatabaseHandler<T> extends AbstractDatabaseHandler<T> {
return false;
}
@Override
public void saveSettings(T instance)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, IntrospectionException {
plugin.getLogger().severe("This method should not be used because configs are not stored in MySQL");
}
@Override
public T loadSettings(String uniqueId, T dbConfig) throws InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException {
plugin.getLogger().severe("This method should not be used because configs are not stored in MySQL");
return null;
}
}

View File

@ -1,5 +1,6 @@
package us.tastybento.bskyblock.island.builders;
import java.util.List;
import java.util.UUID;
import org.bukkit.Location;
@ -40,7 +41,7 @@ public class IslandBuilder {
private World world;
private IslandType type = IslandType.ISLAND;
//private List<String> companionNames = new ArrayList<>();
private ItemStack[] chestItems;
private List<ItemStack> chestItems;
//private List<Entity> companions = new ArrayList<>();
private UUID playerUUID;
private String playerName;
@ -89,10 +90,10 @@ public class IslandBuilder {
/**
* @param chestItems the default chestItems to set
* @param list the default chestItems to set
*/
public IslandBuilder setChestItems(ItemStack[] chestItems) {
this.chestItems = chestItems;
public IslandBuilder setChestItems(List<ItemStack> list) {
this.chestItems = list;
return this;
}
@ -496,7 +497,7 @@ public class IslandBuilder {
Chest chest = new Chest(BlockFace.SOUTH);
state.setData(chest);
state.update();
if (chestItems.length > 0) {
if (!chestItems.isEmpty()) {
InventoryHolder chestBlock = (InventoryHolder) state;
for (ItemStack item: chestItems) {
chestBlock.getInventory().addItem(item);