From bdca10636ed68c2a9d2fd6096d118702ca2771d1 Mon Sep 17 00:00:00 2001 From: Tastybento Date: Sun, 25 Feb 2018 22:44:22 -0800 Subject: [PATCH] Added Config comment capability. See the challenges addon for examples. --- .../api/configuration/ConfigComment.java | 23 +++++++++ .../bskyblock/database/DatabaseConnecter.java | 14 +++--- .../flatfile/FlatFileDatabaseConnecter.java | 50 ++++++++++++++++++- .../flatfile/FlatFileDatabaseHandler.java | 22 ++++++-- .../mysql/MySQLDatabaseConnecter.java | 16 +++--- .../objects/adapters/FlagSerializer.java | 3 -- 6 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 src/main/java/us/tastybento/bskyblock/api/configuration/ConfigComment.java diff --git a/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigComment.java b/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigComment.java new file mode 100644 index 000000000..f758483b1 --- /dev/null +++ b/src/main/java/us/tastybento/bskyblock/api/configuration/ConfigComment.java @@ -0,0 +1,23 @@ +/** + * + */ +package us.tastybento.bskyblock.api.configuration; + +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Retention(RUNTIME) +@Target({ FIELD, METHOD }) +/** + * @author tastybento + * + */ +public @interface ConfigComment { + + String value(); + +} diff --git a/src/main/java/us/tastybento/bskyblock/database/DatabaseConnecter.java b/src/main/java/us/tastybento/bskyblock/database/DatabaseConnecter.java index ae6f0b986..e2670e8a1 100644 --- a/src/main/java/us/tastybento/bskyblock/database/DatabaseConnecter.java +++ b/src/main/java/us/tastybento/bskyblock/database/DatabaseConnecter.java @@ -1,6 +1,7 @@ package us.tastybento.bskyblock.database; import java.sql.Connection; +import java.util.Map; import org.bukkit.configuration.file.YamlConfiguration; @@ -16,21 +17,21 @@ public interface DatabaseConnecter { * * @return A new connection to the database using the settings provided */ - public Connection createConnection(); + Connection createConnection(); /** * Returns the connection url * * @return the connector's URL */ - public String getConnectionUrl(); + String getConnectionUrl(); /** * Looks through the database (or files) and returns a known unique key * @param tableName - name of the table * @return a unique key for this record */ - public String getUniqueId(String tableName); + String getUniqueId(String tableName); /** * Check if a key exists in the database in this table or not @@ -38,7 +39,7 @@ public interface DatabaseConnecter { * @param key - key to check * @return true if it exists */ - public boolean uniqueIdExists(String tableName, String key); + boolean uniqueIdExists(String tableName, String key); /** * Loads a YAML file. Used by the flat file database @@ -46,15 +47,16 @@ public interface DatabaseConnecter { * @param fileName - the filename * @return Yaml Configuration */ - public YamlConfiguration loadYamlFile(String tableName, String fileName); + YamlConfiguration loadYamlFile(String tableName, String fileName); /** * Save the Yaml Config * @param yamlFile - the YAML config * @param tableName - analogous to a table in a database * @param fileName - the name of the record. Must be unique. + * @param commentMap - map of comments, may be empty */ - public void saveYamlFile(YamlConfiguration yamlFile, String tableName, String fileName); + void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName, Map commentMap); } diff --git a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseConnecter.java b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseConnecter.java index a0360f3e9..f8c8ed67d 100644 --- a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseConnecter.java +++ b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseConnecter.java @@ -1,7 +1,15 @@ package us.tastybento.bskyblock.database.flatfile; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Scanner; import java.util.UUID; import org.bukkit.Bukkit; @@ -76,7 +84,7 @@ public class FlatFileDatabaseConnecter implements DatabaseConnecter { * @see us.tastybento.bskyblock.database.DatabaseConnecter#saveYamlFile(org.bukkit.configuration.file.YamlConfiguration, java.lang.String, java.lang.String) */ @Override - public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName) { + public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName, Map commentMap) { if (!fileName.endsWith(".yml")) { fileName = fileName + ".yml"; } @@ -89,7 +97,47 @@ public class FlatFileDatabaseConnecter implements DatabaseConnecter { yamlConfig.save(file); } catch (Exception e) { Bukkit.getLogger().severe("Could not save yaml file to database " + tableName + " " + fileName + " " + e.getMessage()); + return; } + if (commentMap != null && !commentMap.isEmpty()) { + commentFile(file, commentMap); + } + } + + /** + * Adds comments to a YAML file + * @param file + * @param commentMap + */ + private void commentFile(File file, Map commentMap) { + // Run through the file and add in the comments + File commentedFile = new File(file.getPath() + ".tmp"); + List newFile = new ArrayList<>(); + try (Scanner scanner = new Scanner(file)) { + while (scanner.hasNextLine()) { + String nextLine = scanner.nextLine(); + // See if there are any comments in this line + for (Entry e : commentMap.entrySet()) { + if (nextLine.contains(e.getKey())) { + // We want the comment to start at the same level as the entry + StringBuilder commentLine = new StringBuilder(); + for (int i = 0; i < nextLine.indexOf(e.getKey()); i++){ + commentLine.append(' '); + } + commentLine.append(e.getValue()); + nextLine = commentLine.toString(); + break; + } + } + newFile.add(nextLine); + } + Files.write(commentedFile.toPath(), (Iterable)newFile.stream()::iterator); + Files.move(commentedFile.toPath(), file.toPath(), StandardCopyOption.REPLACE_EXISTING); + } catch (IOException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } /* (non-Javadoc) 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 d7053d798..65ae4f3a4 100644 --- a/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java +++ b/src/main/java/us/tastybento/bskyblock/database/flatfile/FlatFileDatabaseHandler.java @@ -28,6 +28,7 @@ import org.bukkit.plugin.Plugin; import us.tastybento.bskyblock.Constants; import us.tastybento.bskyblock.Constants.GameType; +import us.tastybento.bskyblock.api.configuration.ConfigComment; import us.tastybento.bskyblock.api.configuration.ConfigEntry; import us.tastybento.bskyblock.api.configuration.StoreAt; import us.tastybento.bskyblock.database.DatabaseConnecter; @@ -301,6 +302,8 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // The file name of the Yaml file. String filename = ""; String path = DATABASE_FOLDER_NAME + File.separator + dataObject.getSimpleName(); + // Comments for the file + Map yamlComments = new HashMap<>(); // Only allow storing in an arbitrary place if it is a config object. Otherwise it is in the database if (configFlag) { @@ -342,7 +345,19 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // TODO: add in game-specific saving } + + // Comments + ConfigComment comment = field.getAnnotation(ConfigComment.class); + if (comment != null) { + // Create a random placeholder string + String random = "comment-" + UUID.randomUUID().toString(); + // Store placeholder + config.set(random, " "); + // Create comment + yamlComments.put(random, "# " + comment.value()); + } + // Adapter Adapter adapterNotation = field.getAnnotation(Adapter.class); if (adapterNotation != null && AdapterInterface.class.isAssignableFrom(adapterNotation.value())) { if (DEBUG) { @@ -357,13 +372,11 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { // We are done here continue fields; } - - plugin.getLogger().info("DEBUG: property desc = " + propertyDescriptor.getPropertyType().getTypeName()); + // Depending on the vale type, it'll need serializing differently // Check if this field is the mandatory UniqueId field. This is used to identify this instantiation of the class if (method.getName().equals("getUniqueId")) { // If the object does not have a unique name assigned to it already, one is created at random - plugin.getLogger().info("DEBUG: flat file db uniqueId = " + value); String id = (String)value; if (value == null || id.isEmpty()) { id = databaseConnecter.getUniqueId(dataObject.getSimpleName()); @@ -407,10 +420,11 @@ public class FlatFileDatabaseHandler extends AbstractDatabaseHandler { if (filename.isEmpty()) { throw new IllegalArgumentException("No uniqueId in class"); } + if (DEBUG) { plugin.getLogger().info("DEBUG: Saving YAML file : " + path + " " + filename); } - databaseConnecter.saveYamlFile(config, path, filename); + databaseConnecter.saveYamlFile(config, path, filename, yamlComments); } /** diff --git a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseConnecter.java b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseConnecter.java index b18d5707c..30fd17d92 100644 --- a/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseConnecter.java +++ b/src/main/java/us/tastybento/bskyblock/database/mysql/MySQLDatabaseConnecter.java @@ -3,6 +3,7 @@ package us.tastybento.bskyblock.database.mysql; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.configuration.file.YamlConfiguration; @@ -59,15 +60,16 @@ public class MySQLDatabaseConnecter implements DatabaseConnecter { } @Override - public void saveYamlFile(YamlConfiguration yamlFile, String tableName, String fileName) { - // Not used - - } - - @Override - public boolean uniqueIdExists(String simpleName, String key) { + public boolean uniqueIdExists(String tableName, String key) { // Not used return false; } + @Override + public void saveYamlFile(YamlConfiguration yamlConfig, String tableName, String fileName, + Map commentMap) { + // Not used + + } + } diff --git a/src/main/java/us/tastybento/bskyblock/database/objects/adapters/FlagSerializer.java b/src/main/java/us/tastybento/bskyblock/database/objects/adapters/FlagSerializer.java index 4f9cfdb60..027d1b832 100644 --- a/src/main/java/us/tastybento/bskyblock/database/objects/adapters/FlagSerializer.java +++ b/src/main/java/us/tastybento/bskyblock/database/objects/adapters/FlagSerializer.java @@ -4,7 +4,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; -import org.bukkit.Bukkit; import org.bukkit.configuration.MemorySection; import us.tastybento.bskyblock.BSkyBlock; @@ -30,8 +29,6 @@ public class FlagSerializer implements AdapterInterface, Map< 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 {