From 77258b277020975917bf4e3471e48ce381da2542 Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Sun, 28 Oct 2018 15:28:43 +0100 Subject: [PATCH] Added AbstractJSONDatabaseHandler --- .../database/AbstractJSONDatabaseHandler.java | 52 +++++++++++++++++++ .../mongodb/MongoDBDatabaseHandler.java | 41 +++------------ .../database/mysql/MySQLDatabaseHandler.java | 26 ++-------- 3 files changed, 64 insertions(+), 55 deletions(-) create mode 100644 src/main/java/world/bentobox/bentobox/database/AbstractJSONDatabaseHandler.java diff --git a/src/main/java/world/bentobox/bentobox/database/AbstractJSONDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/AbstractJSONDatabaseHandler.java new file mode 100644 index 000000000..0f4a58eaa --- /dev/null +++ b/src/main/java/world/bentobox/bentobox/database/AbstractJSONDatabaseHandler.java @@ -0,0 +1,52 @@ +package world.bentobox.bentobox.database; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.potion.PotionEffectType; +import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.api.flags.Flag; +import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter; +import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter; +import world.bentobox.bentobox.database.mysql.adapters.PotionEffectTypeAdapter; +import world.bentobox.bentobox.database.mysql.adapters.WorldAdapter; + +/** + * Abstract class that handles insert/select-operations into/from a database. + * It also provides {@link #getGson()}. + * + * @author Poslovitch + * + * @param + */ +public abstract class AbstractJSONDatabaseHandler extends AbstractDatabaseHandler { + + /** + * Constructor + * + * @param plugin + * @param type The type of the objects that should be created and filled with + * values from the database or inserted into the database + * @param databaseConnector Contains the settings to create a connection to the database + */ + protected AbstractJSONDatabaseHandler(BentoBox plugin, Class type, DatabaseConnector databaseConnector) { + super(plugin, type, databaseConnector); + } + + protected Gson getGson() { + // excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose + // enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys + GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization(); + // Register adapters + builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ; + builder.registerTypeAdapter(World.class, new WorldAdapter(plugin)); + builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin)); + builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter()); + // Keep null in the database + builder.serializeNulls(); + // Allow characters like < or > without escaping them + builder.disableHtmlEscaping(); + return builder.create(); + } +} diff --git a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java index 1694b6dc1..44b7106b9 100644 --- a/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/mongodb/MongoDBDatabaseHandler.java @@ -5,12 +5,8 @@ import java.util.List; import org.bson.Document; import org.bson.conversions.Bson; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.potion.PotionEffectType; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.FindOneAndReplaceOptions; @@ -19,13 +15,8 @@ import com.mongodb.client.model.Indexes; import com.mongodb.util.JSON; import world.bentobox.bentobox.BentoBox; -import world.bentobox.bentobox.api.flags.Flag; -import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.AbstractJSONDatabaseHandler; import world.bentobox.bentobox.database.DatabaseConnector; -import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter; -import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter; -import world.bentobox.bentobox.database.mysql.adapters.PotionEffectTypeAdapter; -import world.bentobox.bentobox.database.mysql.adapters.WorldAdapter; import world.bentobox.bentobox.database.objects.DataObject; /** @@ -37,7 +28,7 @@ import world.bentobox.bentobox.database.objects.DataObject; * @param */ @SuppressWarnings("deprecation") -public class MongoDBDatabaseHandler extends AbstractDatabaseHandler { +public class MongoDBDatabaseHandler extends AbstractJSONDatabaseHandler { private static final String UNIQUEID = "uniqueId"; private static final String MONGO_ID = "_id"; @@ -56,36 +47,18 @@ public class MongoDBDatabaseHandler extends AbstractDatabaseHandler { public MongoDBDatabaseHandler(BentoBox plugin, Class type, DatabaseConnector dbConnecter) { super(plugin, type, dbConnecter); this.dbConnecter = dbConnecter; - /* - Connection to the database - */ + + // Connection to the database MongoDatabase database = (MongoDatabase) dbConnecter.createConnection(); collection = database.getCollection(dataObject.getCanonicalName()); IndexOptions indexOptions = new IndexOptions().unique(true); collection.createIndex(Indexes.text(UNIQUEID), indexOptions); } - // Gets the GSON builder - private Gson getGSON() { - // excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose - // enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys - GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization(); - // Register adapters - builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ; - builder.registerTypeAdapter(World.class, new WorldAdapter(plugin)); - builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin)); - builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter()); - // Keep null in the database - builder.serializeNulls(); - // Allow characters like < or > without escaping them - builder.disableHtmlEscaping(); - return builder.create(); - } - @Override public List loadObjects() { List list = new ArrayList<>(); - Gson gson = getGSON(); + Gson gson = getGson(); for (Document document : collection.find(new Document())) { // The deprecated serialize option does not have a viable alternative without involving a huge amount of custom code String json = JSON.serialize(document); @@ -98,7 +71,7 @@ public class MongoDBDatabaseHandler extends AbstractDatabaseHandler { @Override public T loadObject(String uniqueId) { Document doc = collection.find(new Document(MONGO_ID, uniqueId)).limit(1).first(); - Gson gson = getGSON(); + Gson gson = getGson(); String json = JSON.serialize(doc).replaceFirst(MONGO_ID, UNIQUEID); // load single object return gson.fromJson(json, dataObject); @@ -112,7 +85,7 @@ public class MongoDBDatabaseHandler extends AbstractDatabaseHandler { } DataObject dataObj = (DataObject)instance; try { - Gson gson = getGSON(); + Gson gson = getGson(); String toStore = gson.toJson(instance); // Change uniqueId to _id toStore = toStore.replaceFirst(UNIQUEID, MONGO_ID); diff --git a/src/main/java/world/bentobox/bentobox/database/mysql/MySQLDatabaseHandler.java b/src/main/java/world/bentobox/bentobox/database/mysql/MySQLDatabaseHandler.java index 72627fd7e..7243ce3cb 100644 --- a/src/main/java/world/bentobox/bentobox/database/mysql/MySQLDatabaseHandler.java +++ b/src/main/java/world/bentobox/bentobox/database/mysql/MySQLDatabaseHandler.java @@ -19,6 +19,7 @@ import com.google.gson.GsonBuilder; import world.bentobox.bentobox.BentoBox; import world.bentobox.bentobox.api.flags.Flag; import world.bentobox.bentobox.database.AbstractDatabaseHandler; +import world.bentobox.bentobox.database.AbstractJSONDatabaseHandler; import world.bentobox.bentobox.database.DatabaseConnector; import world.bentobox.bentobox.database.mysql.adapters.FlagAdapter; import world.bentobox.bentobox.database.mysql.adapters.LocationAdapter; @@ -34,7 +35,7 @@ import world.bentobox.bentobox.database.objects.DataObject; * * @param */ -public class MySQLDatabaseHandler extends AbstractDatabaseHandler { +public class MySQLDatabaseHandler extends AbstractJSONDatabaseHandler { /** * Connection to the database @@ -71,23 +72,6 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { } } - // Gets the GSON builder - private Gson getGSON() { - // excludeFieldsWithoutExposeAnnotation - this means that every field to be stored should use @Expose - // enableComplexMapKeySerialization - forces GSON to use TypeAdapters even for Map keys - GsonBuilder builder = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().enableComplexMapKeySerialization(); - // Register adapters - builder.registerTypeAdapter(Location.class, new LocationAdapter(plugin)) ; - builder.registerTypeAdapter(World.class, new WorldAdapter(plugin)); - builder.registerTypeAdapter(Flag.class, new FlagAdapter(plugin)); - builder.registerTypeAdapter(PotionEffectType.class, new PotionEffectTypeAdapter()); - // Keep null in the database - builder.serializeNulls(); - // Allow characters like < or > without escaping them - builder.disableHtmlEscaping(); - return builder.create(); - } - @Override public List loadObjects() { List list = new ArrayList<>(); @@ -98,7 +82,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { try (Statement preparedStatement = connection.createStatement()) { try (ResultSet resultSet = preparedStatement.executeQuery(sb.toString())) { // Load all the results - Gson gson = getGSON(); + Gson gson = getGson(); while (resultSet.next()) { list.add(gson.fromJson(resultSet.getString("json"), dataObject)); } @@ -120,7 +104,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { // If there is a result, we only want/need the first one - Gson gson = getGSON(); + Gson gson = getGson(); return gson.fromJson(resultSet.getString("json"), dataObject); } } @@ -143,7 +127,7 @@ public class MySQLDatabaseHandler extends AbstractDatabaseHandler { // Replace into is used so that any data in the table will be replaced with updated data // The table name is the canonical name, so that add-ons can be sure of a unique table in the database try (PreparedStatement preparedStatement = connection.prepareStatement(sb)) { - Gson gson = getGSON(); + Gson gson = getGson(); String toStore = gson.toJson(instance); preparedStatement.setString(1, toStore); preparedStatement.setString(2, toStore);