From fa1ccd0c99cd217e657d7743d2cb9cdca2722da9 Mon Sep 17 00:00:00 2001 From: Tastybento Date: Sun, 4 Feb 2018 12:53:17 -0800 Subject: [PATCH] Fixed bugs with MySQL saving and loading. Added the adapter annotation to MySQL and fixed issues with empty hashmaps causing null errors. Added a flag serializer adapter for the protection flags so that flags are saved and loaded correctly. Renamed the Adapter notation class to be clearer about what it is doing. --- .../us/tastybento/bskyblock/BSkyBlock.java | 1 - .../us/tastybento/bskyblock/Settings.java | 1 - .../bskyblock/api/configuration/Adapter.java | 14 +++-- .../api/configuration/ISettings.java | 7 +-- .../PotionEffectListAdpater.java | 4 +- .../flatfile/FlatFileDatabaseHandler.java | 4 +- .../database/managers/island/IslandCache.java | 4 ++ .../managers/island/IslandsManager.java | 5 +- .../database/mysql/MySQLDatabaseHandler.java | 54 ++++++++++++++++--- .../database/objects/FlagSerializer.java | 27 +++++++--- .../bskyblock/database/objects/Island.java | 16 +++--- .../bskyblock/managers/FlagsManager.java | 2 +- 12 files changed, 102 insertions(+), 37 deletions(-) diff --git a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java index b2ed664d9..a0f98fe13 100755 --- a/src/main/java/us/tastybento/bskyblock/BSkyBlock.java +++ b/src/main/java/us/tastybento/bskyblock/BSkyBlock.java @@ -98,7 +98,6 @@ public class BSkyBlock extends JavaPlugin { islandsManager.load(); localesManager = new LocalesManager(plugin); - //TODO localesManager.registerLocales(plugin); // Register Listeners registerListeners(); diff --git a/src/main/java/us/tastybento/bskyblock/Settings.java b/src/main/java/us/tastybento/bskyblock/Settings.java index 7a4505770..ad73bf43e 100644 --- a/src/main/java/us/tastybento/bskyblock/Settings.java +++ b/src/main/java/us/tastybento/bskyblock/Settings.java @@ -367,7 +367,6 @@ public class Settings implements ISettings { } @Override public Settings getInstance() { - // TODO Auto-generated method stub return this; } /** diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java b/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java index fd2d14c6b..d87f26531 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/Adapter.java @@ -11,10 +11,16 @@ package us.tastybento.bskyblock.api.configuration; public interface Adapter { /** - * Convert from to something - * @param from + * Serialize object + * @param object - object + * @return serialized object */ - S convertFrom(Object from); + S serialize(Object object); - V convertTo(Object to); + /** + * Deserialize object + * @param object + * @return deserialized object + */ + V deserialize(Object object); } diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java b/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java index f619c7b1f..82d43387b 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/ISettings.java @@ -14,6 +14,7 @@ import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; * Simple interface for tagging all classes containing ConfigEntries. * * @author Poslovitch + * @author tastybento * @param */ public interface ISettings { @@ -30,10 +31,10 @@ public interface ISettings { } default void saveBackup() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException, InstantiationException, NoSuchMethodException, IntrospectionException, SQLException { - // Save backup in real database + // Save backup @SuppressWarnings("unchecked") - AbstractDatabaseHandler dbhandler = (AbstractDatabaseHandler) BSBDatabase.getDatabase().getHandler(getInstance().getClass()); - dbhandler.saveObject(getInstance()); + AbstractDatabaseHandler backupHandler = (AbstractDatabaseHandler) new FlatFileDatabase().getHandler(getInstance().getClass()); + backupHandler.saveObject(getInstance()); } // --------------- Loader ------------------ diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java b/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java index d79263028..2abe0e836 100644 --- a/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/PotionEffectListAdpater.java @@ -9,7 +9,7 @@ public class PotionEffectListAdpater implements Adapter, @SuppressWarnings("unchecked") @Override - public List convertFrom(Object from) { + public List serialize(Object from) { List result = new ArrayList<>(); if (from instanceof ArrayList) { for (String type: (ArrayList)from) { @@ -21,7 +21,7 @@ public class PotionEffectListAdpater implements Adapter, @SuppressWarnings("unchecked") @Override - public List convertTo(Object to) { + public List deserialize(Object to) { List result = new ArrayList<>(); if (to instanceof ArrayList) { for (PotionEffectType type: (ArrayList)to) { diff --git a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java index 1838dda5d..9695a7468 100644 --- a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java @@ -182,7 +182,7 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { if (!configEntry.adapter().equals(Adapter.class)) { // A conversion adapter has been defined Object value = config.get(storageLocation); - method.invoke(instance, ((Adapter)configEntry.adapter().newInstance()).convertFrom(value)); + method.invoke(instance, ((Adapter)configEntry.adapter().newInstance()).serialize(value)); if (DEBUG) { plugin.getLogger().info("DEBUG: value = " + value); plugin.getLogger().info("DEBUG: property type = " + propertyDescriptor.getPropertyType()); @@ -355,7 +355,7 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { if (!configEntry.adapter().equals(Adapter.class)) { // A conversion adapter has been defined try { - config.set(storageLocation, ((Adapter)configEntry.adapter().newInstance()).convertTo(value)); + config.set(storageLocation, ((Adapter)configEntry.adapter().newInstance()).deserialize(value)); } catch (InstantiationException e) { e.printStackTrace(); } diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java index 463a1f2f3..13dd1e32a 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandCache.java @@ -37,6 +37,10 @@ public class IslandCache { islandsByUUID = new HashMap<>(); } + /** + * Adds an island to the grid + * @param island + */ public void addIsland(Island island) { islandsByLocation.put(island.getCenter(), island); if (DEBUG) diff --git a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java index ff4531a1f..e9e4bb2c3 100644 --- a/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java +++ b/src/main/java/us/tastybento/bskyblock/database/managers/island/IslandsManager.java @@ -40,7 +40,6 @@ import us.tastybento.bskyblock.util.Util; public class IslandsManager { private static final boolean DEBUG = false; - private static final boolean DEBUG2 = false; /** * Checks if this location is safe for a player to teleport to. Used by * warps and boat exits Unsafe is any liquid or air and also if there's no @@ -713,12 +712,14 @@ public class IslandsManager { plugin.getLogger().info("DEBUG: loading grid"); for (Island island : handler.loadObjects()) { if (DEBUG) - plugin.getLogger().info("DEBUG: addin island at "+ island.getCenter()); + plugin.getLogger().info("DEBUG: adding island at "+ island.getCenter()); islandCache.addIsland(island); } } catch (Exception e) { e.printStackTrace(); } + if (DEBUG) + plugin.getLogger().info("DEBUG: islands loaded"); } /** diff --git a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java index 1c26bf128..c5631e76a 100644 --- a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseHandler.java @@ -32,6 +32,8 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.plugin.Plugin; +import us.tastybento.bskyblock.api.configuration.Adapter; +import us.tastybento.bskyblock.api.configuration.ConfigEntry; import us.tastybento.bskyblock.database.DatabaseConnecter; import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler; import us.tastybento.bskyblock.util.Util; @@ -271,7 +273,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { if (DEBUG) plugin.getLogger().info("DEBUG: collection columns = " + col); } - + return columns; } @@ -414,6 +416,22 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { Object value = method.invoke(instance); if (DEBUG) plugin.getLogger().info("DEBUG: value = " + value); + // Adapter + // 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 (DEBUG) + plugin.getLogger().info("DEBUG: there is a configEntry"); + if (!configEntry.adapter().equals(Adapter.class)) { + if (DEBUG) + plugin.getLogger().info("DEBUG: there is an adapter"); + // A conversion adapter has been defined + value = ((Adapter)configEntry.adapter().newInstance()).deserialize(value); + if (DEBUG) + plugin.getLogger().info("DEBUG: value now after deserialization = " + value); + } + } // Create set and map table inserts if this is a Collection if (propertyDescriptor.getPropertyType().equals(Set.class) || propertyDescriptor.getPropertyType().equals(Map.class) || @@ -465,6 +483,9 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { Iterator it = collection.entrySet().iterator(); while (it.hasNext()) { Entry en = (Entry) it.next(); + if (DEBUG) + plugin.getLogger().info("DEBUG: entry ket = " + en.getKey()); + // Get the key and serialize it Object key = serialize(en.getKey(), en.getKey().getClass()); if (DEBUG) @@ -668,10 +689,14 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // 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(); + if (DEBUG) + plugin.getLogger().info("DEBUG: propertyDescriptor.getPropertyType() = " + propertyDescriptor.getPropertyType()); // If the type is a Collection, then we need to deal with set and map tables - if (Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType())) { + if (Collection.class.isAssignableFrom(propertyDescriptor.getPropertyType()) + || Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) { // Collection - //plugin.getLogger().info("DEBUG: Collection"); + if (DEBUG) + plugin.getLogger().info("DEBUG: Collection or Map"); // TODO Get the values from the subsidiary tables. // value is just of type boolean right now String setSql = "SELECT "; @@ -720,7 +745,8 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { //plugin.getLogger().info("DEBUG: collectionResultSet size = " + collectionResultSet.getFetchSize()); ((List) value).add(deserialize(collectionResultSet.getObject(1),Class.forName(setType.getTypeName()))); } - } else if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType())) { + } else if (Map.class.isAssignableFrom(propertyDescriptor.getPropertyType()) || + HashMap.class.isAssignableFrom(propertyDescriptor.getPropertyType())) { if (DEBUG) plugin.getLogger().info("DEBUG: Adding a map "); // Loop through the collection resultset @@ -756,6 +782,22 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { plugin.getLogger().info("DEBUG: regular type"); value = deserialize(value, propertyDescriptor.getPropertyType()); } + // Adapter + // 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 (DEBUG) + plugin.getLogger().info("DEBUG: there is a configEntry"); + if (!configEntry.adapter().equals(Adapter.class)) { + if (DEBUG) + plugin.getLogger().info("DEBUG: there is an adapter"); + // A conversion adapter has been defined + value = ((Adapter)configEntry.adapter().newInstance()).serialize(value); + if (DEBUG) + plugin.getLogger().info("DEBUG: value now after serialization = " + value); + } + } if (DEBUG) { plugin.getLogger().info("DEBUG: invoking method " + method.getName()); if (value == null) { @@ -914,12 +956,12 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { 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 { + IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IntrospectionException { plugin.getLogger().severe("This method should not be used because configs are not stored in MySQL"); return null; } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/FlagSerializer.java b/src/main/java/us/tastybento/bskyblock/database/objects/FlagSerializer.java index bbd692dad..c3b2db36f 100644 --- a/src/main/java/us/tastybento/bskyblock/database/objects/FlagSerializer.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/FlagSerializer.java @@ -20,21 +20,32 @@ import us.tastybento.bskyblock.api.flags.Flag; public class FlagSerializer implements Adapter, HashMap> { @Override - public HashMap convertFrom(Object from) { + public HashMap serialize(Object object) { HashMap result = new HashMap<>(); - MemorySection section = (MemorySection) from; - for (String key : section.getKeys(false)) { - Bukkit.getLogger().info("DEBUG: " + key + " = " + section.getInt(key)); - - result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(key), section.getInt(key)); + if (object == null) + return result; + // For YAML + if (object instanceof MemorySection) { + MemorySection section = (MemorySection) object; + for (String key : section.getKeys(false)) { + Bukkit.getLogger().info("DEBUG: " + key + " = " + section.getInt(key)); + + result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(key), section.getInt(key)); + } + } else { + for (Entry en : ((HashMap)object).entrySet()) { + result.put(BSkyBlock.getInstance().getFlagsManager().getFlagByID(en.getKey()), en.getValue()); + } } return result; } @Override - public HashMap convertTo(Object to) { + public HashMap deserialize(Object object) { HashMap result = new HashMap<>(); - HashMap flags = (HashMap)to; + if (object == null) + return result; + HashMap flags = (HashMap)object; for (Entry en: flags.entrySet()) { result.put(en.getKey().getID(), en.getValue()); } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java index 6ac43d5bf..eae614cdb 100755 --- a/src/main/java/us/tastybento/bskyblock/database/objects/Island.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/Island.java @@ -89,8 +89,7 @@ public class Island implements DataObject { public Island() {} public Island(Location location, UUID owner, int protectionRange) { - this.owner = owner; - this.members.put(owner, RanksManager.OWNER_RANK); + setOwner(owner); this.createdDate = System.currentTimeMillis(); this.updatedDate = System.currentTimeMillis(); this.world = location.getWorld(); @@ -108,7 +107,8 @@ public class Island implements DataObject { * @param playerUUID */ public void addMember(UUID playerUUID) { - members.put(playerUUID, RanksManager.MEMBER_RANK); + if (playerUUID != null) + members.put(playerUUID, RanksManager.MEMBER_RANK); } /** @@ -119,7 +119,8 @@ public class Island implements DataObject { */ public boolean addToBanList(UUID targetUUID) { // TODO fire ban event - members.put(targetUUID, RanksManager.BANNED_RANK); + if (targetUUID != null) + members.put(targetUUID, RanksManager.BANNED_RANK); return true; } @@ -282,7 +283,7 @@ public class Island implements DataObject { * @return rank integer */ public int getRank(User user) { - Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId()); + //Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId()); return members.containsKey(user.getUniqueId()) ? members.get(user.getUniqueId()) : RanksManager.VISITOR_RANK; } @@ -426,7 +427,7 @@ public class Island implements DataObject { * @return true if allowed, false if not */ public boolean isAllowed(User user, Flag flag) { - Bukkit.getLogger().info("DEBUG: " + flag.getID() + " user score = " + getRank(user) + " flag req = "+ this.getFlagReq(flag)); + //Bukkit.getLogger().info("DEBUG: " + flag.getID() + " user score = " + getRank(user) + " flag req = "+ this.getFlagReq(flag)); return (this.getRank(user) >= this.getFlagReq(flag)) ? true : false; } @@ -601,6 +602,7 @@ public class Island implements DataObject { */ public void setOwner(UUID owner){ this.owner = owner; + if (owner == null) return; // Defensive code: demote any previous owner for (Entry en : members.entrySet()) { if (en.getValue().equals(RanksManager.OWNER_RANK)) { @@ -637,7 +639,7 @@ public class Island implements DataObject { * @param rank */ public void setRank(User user, int rank) { - members.put(user.getUniqueId(), rank); + if (user.getUniqueId() != null) members.put(user.getUniqueId(), rank); } /** diff --git a/src/main/java/us/tastybento/bskyblock/managers/FlagsManager.java b/src/main/java/us/tastybento/bskyblock/managers/FlagsManager.java index 8b5884de9..9ad9f3e87 100644 --- a/src/main/java/us/tastybento/bskyblock/managers/FlagsManager.java +++ b/src/main/java/us/tastybento/bskyblock/managers/FlagsManager.java @@ -19,7 +19,7 @@ public class FlagsManager { public void registerFlag(Flag flag) { //TODO all the security checks - plugin.getLogger().info("DEBUG: registering flag " + flag.getID()); + //plugin.getLogger().info("DEBUG: registering flag " + flag.getID()); flags.add(flag); // If there is a listener, register it into Bukkit. flag.getListener().ifPresent(l -> plugin.getServer().getPluginManager().registerEvents(l, plugin));