From ce7fb46820f479e6ccc84e203bf5807d73874755 Mon Sep 17 00:00:00 2001 From: avaerian <55154263+avaerian@users.noreply.github.com> Date: Mon, 18 Sep 2023 19:04:56 -0400 Subject: [PATCH] Push config management work so far (#32) --- .../org/minerift/ether/config/Config.java | 36 ++++++++++ .../minerift/ether/config/ConfigFileView.java | 54 +++++++++++++++ .../minerift/ether/config/ConfigLoader.java | 11 --- .../minerift/ether/config/ConfigRegistry.java | 67 +++++++++++++++++++ .../ether/config/MainConfiguration.java | 16 ----- .../DeprecatedConfigurationFile.java} | 5 +- .../DeprecatedYamlPath.java} | 5 +- .../ether/config/deprecated/MainConfig.java | 21 ++++++ .../config/exceptions/ConfigException.java | 11 +++ .../exceptions/ConfigFileReadException.java | 15 +++++ .../exceptions/ConfigFileWriteException.java | 6 ++ .../exceptions/ConfigNotFoundException.java | 14 ++++ .../ether/config/readers/IConfigReader.java | 14 ++++ .../config/readers/MainConfigReader.java | 34 ++++++++++ .../config/readers/SchematicConfigReader.java | 14 ++++ .../ether/config/types/ConfigType.java | 67 +++++++++++++++++++ .../ether/config/types/MainConfig.java | 20 ++++++ .../ether/config/types/SchematicConfig.java | 30 +++++++++ .../ether/config/writers/IConfigWriter.java | 8 +++ .../config/writers/SchematicConfigWriter.java | 10 +++ 20 files changed, 427 insertions(+), 31 deletions(-) create mode 100644 main/src/main/java/org/minerift/ether/config/Config.java create mode 100644 main/src/main/java/org/minerift/ether/config/ConfigFileView.java delete mode 100644 main/src/main/java/org/minerift/ether/config/ConfigLoader.java create mode 100644 main/src/main/java/org/minerift/ether/config/ConfigRegistry.java delete mode 100644 main/src/main/java/org/minerift/ether/config/MainConfiguration.java rename main/src/main/java/org/minerift/ether/config/{ConfigurationFile.java => deprecated/DeprecatedConfigurationFile.java} (69%) rename main/src/main/java/org/minerift/ether/config/{YamlPath.java => deprecated/DeprecatedYamlPath.java} (71%) create mode 100644 main/src/main/java/org/minerift/ether/config/deprecated/MainConfig.java create mode 100644 main/src/main/java/org/minerift/ether/config/exceptions/ConfigException.java create mode 100644 main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileReadException.java create mode 100644 main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileWriteException.java create mode 100644 main/src/main/java/org/minerift/ether/config/exceptions/ConfigNotFoundException.java create mode 100644 main/src/main/java/org/minerift/ether/config/readers/IConfigReader.java create mode 100644 main/src/main/java/org/minerift/ether/config/readers/MainConfigReader.java create mode 100644 main/src/main/java/org/minerift/ether/config/readers/SchematicConfigReader.java create mode 100644 main/src/main/java/org/minerift/ether/config/types/ConfigType.java create mode 100644 main/src/main/java/org/minerift/ether/config/types/MainConfig.java create mode 100644 main/src/main/java/org/minerift/ether/config/types/SchematicConfig.java create mode 100644 main/src/main/java/org/minerift/ether/config/writers/IConfigWriter.java create mode 100644 main/src/main/java/org/minerift/ether/config/writers/SchematicConfigWriter.java diff --git a/main/src/main/java/org/minerift/ether/config/Config.java b/main/src/main/java/org/minerift/ether/config/Config.java new file mode 100644 index 0000000..54e92be --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/Config.java @@ -0,0 +1,36 @@ +package org.minerift.ether.config; + +import org.minerift.ether.Ether; +import org.minerift.ether.EtherPlugin; +import org.minerift.ether.config.exceptions.ConfigFileReadException; +import org.minerift.ether.config.types.ConfigType; + +import java.io.File; +import java.util.logging.Level; + +public abstract class Config> { + + public File getPluginDirectory() { + return EtherPlugin.getInstance().getDataFolder(); + } + + public void save() { + getType().getWriter().write((T) this); + } + + public void reload() { + // Loads from file again + try { + T reload = getType().getReader().read(getType()); + copyFrom(reload); + } catch (ConfigFileReadException ex) { + Ether.getLogger().log(Level.SEVERE, String.format("Failed to read %s", getType().getName())); + ex.printStackTrace(); + } + } + + // Copies data from a similar config over to this config + protected abstract void copyFrom(T other); + + public abstract ConfigType getType(); +} diff --git a/main/src/main/java/org/minerift/ether/config/ConfigFileView.java b/main/src/main/java/org/minerift/ether/config/ConfigFileView.java new file mode 100644 index 0000000..44bec1e --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/ConfigFileView.java @@ -0,0 +1,54 @@ +package org.minerift.ether.config; + +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.YamlConfiguration; +import org.minerift.ether.util.Result; + +import java.io.File; +import java.io.IOException; +import java.util.Optional; + +// Wrapper class for the YamlConfiguration Bukkit API +public class ConfigFileView { + + private final ConfigurationSection head; + + public static Result from(File file) { + + final Result result = new Result<>(); + + // Attempt to load config file + final YamlConfiguration bukkitView = new YamlConfiguration(); + try { + bukkitView.load(file); + result.ok(new ConfigFileView(bukkitView)); + } catch (IOException ex) { + result.err(ex); + } catch (InvalidConfigurationException ex) { + result.err(new IOException(ex.getMessage())); + } + + return result; + } + + private ConfigFileView(ConfigurationSection head) { + this.head = head; + } + + public Optional get(String path) { + return Optional.ofNullable(head.get(path, null)); + } + + public Optional getSectionView(String path) { + final ConfigurationSection section = head.getConfigurationSection(path); + return Optional.ofNullable(section == null ? null : new ConfigFileView(section)); + } + + // TODO: create get() method with an adapter parameter + + public ConfigurationSection getBukkitView() { + return head; + } + +} diff --git a/main/src/main/java/org/minerift/ether/config/ConfigLoader.java b/main/src/main/java/org/minerift/ether/config/ConfigLoader.java deleted file mode 100644 index 2f891c3..0000000 --- a/main/src/main/java/org/minerift/ether/config/ConfigLoader.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.minerift.ether.config; - -/** - * Handles the loading of data from a configuration file into the proper class - * @author Avaerian - */ -public class ConfigLoader { - - // Get class to load from file - -} diff --git a/main/src/main/java/org/minerift/ether/config/ConfigRegistry.java b/main/src/main/java/org/minerift/ether/config/ConfigRegistry.java new file mode 100644 index 0000000..97e2836 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/ConfigRegistry.java @@ -0,0 +1,67 @@ +package org.minerift.ether.config; + +import org.minerift.ether.config.exceptions.ConfigFileReadException; +import org.minerift.ether.config.types.ConfigType; + +import java.io.IOException; +import java.util.*; + +// TODO: ConfigRegistry should only handle registry operations (registering + loading/reading, unloading/writing, unregistering) +public class ConfigRegistry { + + /** + * For reading configs: + * If a config file exists, attempt to read and log exceptions (if any) + * If a config file doesn't exist, return default config object + * + * For writing configs: + * write() should handle all data dumping to storage + * It will always "create a new file" (replacing old configs) to store the data. + * + * + * + * FOR REGISTERING: + * If a config file doesn't exist, load defined default (into memory) + * After loading, write to file for users to interact with + * + * If a config file does exist, attempt to load file. + */ + + private final Map, Config> configs; + + public ConfigRegistry() { + this.configs = new HashMap<>(); + } + + // Register and load a config + // Returns the config read from the file + // If a config cannot be read, return the default config + public > T register(ConfigType type) { + T config; + try { + config = type.getReader().read(type); + } catch (ConfigFileReadException ex) { + // TODO: change this to throw the error and set the default config only if config doesn't exist + config = type.getDefaultConfig(); + } + configs.putIfAbsent(type, config); + return config; + } + + public > T get(ConfigType type) { + final T config = (T) configs.get(type); + if(config == null) { + throw new IllegalArgumentException(String.format("Config type %s was not found!", type.getName())); + } + return config; + } + + public Collection getAll() { + return configs.values(); + } + + public Set> getAllTypes() { + return configs.keySet(); + } + +} diff --git a/main/src/main/java/org/minerift/ether/config/MainConfiguration.java b/main/src/main/java/org/minerift/ether/config/MainConfiguration.java deleted file mode 100644 index 4fa78ca..0000000 --- a/main/src/main/java/org/minerift/ether/config/MainConfiguration.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.minerift.ether.config; - -/** - * Represents the config.yml that is loaded into memory for ease-of-use - * @author Avaerian - */ -@ConfigurationFile(name = "config.yml") -public class MainConfiguration { - - @YamlPath(path = "island.tile.size") - public final static int TILE_SIZE = 200; // default value for now - - @YamlPath(path = "island.tile.height") - public final static int TILE_HEIGHT = 90; // default value for now - -} diff --git a/main/src/main/java/org/minerift/ether/config/ConfigurationFile.java b/main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedConfigurationFile.java similarity index 69% rename from main/src/main/java/org/minerift/ether/config/ConfigurationFile.java rename to main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedConfigurationFile.java index 30e6eb4..548e08c 100644 --- a/main/src/main/java/org/minerift/ether/config/ConfigurationFile.java +++ b/main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedConfigurationFile.java @@ -1,4 +1,4 @@ -package org.minerift.ether.config; +package org.minerift.ether.config.deprecated; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -7,6 +7,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) -public @interface ConfigurationFile { +@Deprecated +public @interface DeprecatedConfigurationFile { String name(); } \ No newline at end of file diff --git a/main/src/main/java/org/minerift/ether/config/YamlPath.java b/main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedYamlPath.java similarity index 71% rename from main/src/main/java/org/minerift/ether/config/YamlPath.java rename to main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedYamlPath.java index 8445a69..d8e4825 100644 --- a/main/src/main/java/org/minerift/ether/config/YamlPath.java +++ b/main/src/main/java/org/minerift/ether/config/deprecated/DeprecatedYamlPath.java @@ -1,4 +1,4 @@ -package org.minerift.ether.config; +package org.minerift.ether.config.deprecated; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -7,6 +7,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) -public @interface YamlPath { +@Deprecated +public @interface DeprecatedYamlPath { String path(); } diff --git a/main/src/main/java/org/minerift/ether/config/deprecated/MainConfig.java b/main/src/main/java/org/minerift/ether/config/deprecated/MainConfig.java new file mode 100644 index 0000000..ce1880c --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/deprecated/MainConfig.java @@ -0,0 +1,21 @@ +package org.minerift.ether.config.deprecated; + +/** + * Represents the config.yml that is loaded into memory for ease-of-use + * @author Avaerian + */ +@Deprecated +@DeprecatedConfigurationFile(name = "config.yml") +public class MainConfig { + + @DeprecatedYamlPath(path = "island.tile.size") + public final static int TILE_SIZE = 200; // default value for now + + @DeprecatedYamlPath(path = "island.tile.height") + public final static int TILE_HEIGHT = 90; + + // I plan on adding permissions to this and allowing for different tiers + @DeprecatedYamlPath(path = "island.tile.height") + public final static int TILE_ACCESSIBLE_AREA = 150; // default value for now; this is subject to change + +} diff --git a/main/src/main/java/org/minerift/ether/config/exceptions/ConfigException.java b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigException.java new file mode 100644 index 0000000..2bf81f1 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigException.java @@ -0,0 +1,11 @@ +package org.minerift.ether.config.exceptions; + +public class ConfigException extends Exception { + public ConfigException() { + super(); + } + + public ConfigException(String message) { + super(message); + } +} diff --git a/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileReadException.java b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileReadException.java new file mode 100644 index 0000000..009df5c --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileReadException.java @@ -0,0 +1,15 @@ +package org.minerift.ether.config.exceptions; + +import java.io.IOException; + +/** + * An exception for any config reading error that occurs when parsing + * @author Avaerian + */ +public class ConfigFileReadException extends IOException { + public ConfigFileReadException() {} + + public ConfigFileReadException(String message) { + super(message); + } +} diff --git a/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileWriteException.java b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileWriteException.java new file mode 100644 index 0000000..cb6f59f --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigFileWriteException.java @@ -0,0 +1,6 @@ +package org.minerift.ether.config.exceptions; + +import java.io.IOException; + +public class ConfigFileWriteException extends IOException { +} diff --git a/main/src/main/java/org/minerift/ether/config/exceptions/ConfigNotFoundException.java b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigNotFoundException.java new file mode 100644 index 0000000..0a17e41 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/exceptions/ConfigNotFoundException.java @@ -0,0 +1,14 @@ +package org.minerift.ether.config.exceptions; + +import java.io.IOException; + +// TODO: reconsider +public class ConfigNotFoundException extends IOException { + public ConfigNotFoundException() { + super(); + } + + public ConfigNotFoundException(String message) { + super(message); + } +} diff --git a/main/src/main/java/org/minerift/ether/config/readers/IConfigReader.java b/main/src/main/java/org/minerift/ether/config/readers/IConfigReader.java new file mode 100644 index 0000000..8da5bed --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/readers/IConfigReader.java @@ -0,0 +1,14 @@ +package org.minerift.ether.config.readers; + +import org.minerift.ether.config.Config; +import org.minerift.ether.config.exceptions.ConfigFileReadException; +import org.minerift.ether.config.types.ConfigType; + +// Reads a file into a Config object +public interface IConfigReader> { + + // Reads a config as an object + // Throws an IOException if there are any issues with file access/IO + // Throws a ConfigFileReadException if the config fails to read/parse + T read(ConfigType type) throws ConfigFileReadException; +} diff --git a/main/src/main/java/org/minerift/ether/config/readers/MainConfigReader.java b/main/src/main/java/org/minerift/ether/config/readers/MainConfigReader.java new file mode 100644 index 0000000..fbb6c90 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/readers/MainConfigReader.java @@ -0,0 +1,34 @@ +package org.minerift.ether.config.readers; + +import org.minerift.ether.config.ConfigFileView; +import org.minerift.ether.config.exceptions.ConfigFileReadException; +import org.minerift.ether.config.types.ConfigType; +import org.minerift.ether.config.types.MainConfig; +import org.minerift.ether.util.Result; + +public class MainConfigReader implements IConfigReader { + + @Override + public MainConfig read(ConfigType type) throws ConfigFileReadException { + + final Result result = new Result<>(); + + // TODO + ConfigFileView.from(type.getFile()).handle((view) -> { + + // Read islands as an example + view.getSectionView("user.islands").ifPresent((section) -> { + //section.get(""); + }); + + }, + // Delegate ConfigFileView error to result + (ex) -> result.err((ConfigFileReadException) ex)); + + if(result.isErr()) { + throw result.getErr(); + } + + return result.getOk(); + } +} diff --git a/main/src/main/java/org/minerift/ether/config/readers/SchematicConfigReader.java b/main/src/main/java/org/minerift/ether/config/readers/SchematicConfigReader.java new file mode 100644 index 0000000..9113bd2 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/readers/SchematicConfigReader.java @@ -0,0 +1,14 @@ +package org.minerift.ether.config.readers; + +import org.minerift.ether.config.exceptions.ConfigFileReadException; +import org.minerift.ether.config.types.ConfigType; +import org.minerift.ether.config.types.SchematicConfig; + +import java.io.IOException; + +public class SchematicConfigReader implements IConfigReader { + @Override + public SchematicConfig read(ConfigType type) throws ConfigFileReadException { + return null; + } +} diff --git a/main/src/main/java/org/minerift/ether/config/types/ConfigType.java b/main/src/main/java/org/minerift/ether/config/types/ConfigType.java new file mode 100644 index 0000000..12ec171 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/types/ConfigType.java @@ -0,0 +1,67 @@ +package org.minerift.ether.config.types; + +import org.minerift.ether.config.Config; +import org.minerift.ether.config.readers.IConfigReader; +import org.minerift.ether.config.readers.MainConfigReader; +import org.minerift.ether.config.readers.SchematicConfigReader; +import org.minerift.ether.config.writers.IConfigWriter; +import org.minerift.ether.config.writers.SchematicConfigWriter; + +import java.io.File; +import java.util.function.Supplier; + +public class ConfigType> { + + public static final ConfigType MAIN; + public static final ConfigType SCHEM_LIST; + + static { + MAIN = new ConfigType<>("MainConfig (config.yml)", MainConfig.class, new MainConfigReader(), null, MainConfig::new, null); + SCHEM_LIST = new ConfigType<>("Schematic List (schems.yml)", SchematicConfig.class, new SchematicConfigReader(), new SchematicConfigWriter(), SchematicConfig::new, null); + } + + private final String name; + private final Class typeClazz; + private final IConfigReader reader; + private final IConfigWriter writer; + private final Supplier defaultConfig; + private final File file; + + private ConfigType(String name, Class typeClazz, IConfigReader reader, IConfigWriter writer, Supplier defaultConfig, File file) { + this.name = name; + this.typeClazz = typeClazz; + this.reader = reader; + this.writer = writer; + this.defaultConfig = defaultConfig; + this.file = file; + } + + public String getName() { + return name; + } + + public Class getTypeClass() { + return typeClazz; + } + + public T getDefaultConfig() { + return defaultConfig.get(); + } + + public IConfigReader getReader() { + return reader; + } + + public IConfigWriter getWriter() { + return writer; + } + + public File getFile() { + return file; + } + + public

> P getReader(Class

clazz) { + final IConfigReader reader = getReader(); + return reader == null ? null : clazz.cast(reader); + } +} diff --git a/main/src/main/java/org/minerift/ether/config/types/MainConfig.java b/main/src/main/java/org/minerift/ether/config/types/MainConfig.java new file mode 100644 index 0000000..7506100 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/types/MainConfig.java @@ -0,0 +1,20 @@ +package org.minerift.ether.config.types; + +import org.minerift.ether.config.Config; + +public class MainConfig extends Config { + + public MainConfig() { + //this.file = new File(getPluginDirectory(), "config.yml"); + } + + @Override + protected void copyFrom(MainConfig other) { + + } + + @Override + public ConfigType getType() { + return ConfigType.MAIN; + } +} diff --git a/main/src/main/java/org/minerift/ether/config/types/SchematicConfig.java b/main/src/main/java/org/minerift/ether/config/types/SchematicConfig.java new file mode 100644 index 0000000..f49a444 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/types/SchematicConfig.java @@ -0,0 +1,30 @@ +package org.minerift.ether.config.types; + +import org.minerift.ether.config.Config; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +public class SchematicConfig extends Config { + + private final List schemFiles; + + public SchematicConfig() { + this.schemFiles = new ArrayList<>(); + } + + public List getSchematicFiles() { + return schemFiles; + } + + @Override + protected void copyFrom(SchematicConfig other) { + + } + + @Override + public ConfigType getType() { + return ConfigType.SCHEM_LIST; + } +} diff --git a/main/src/main/java/org/minerift/ether/config/writers/IConfigWriter.java b/main/src/main/java/org/minerift/ether/config/writers/IConfigWriter.java new file mode 100644 index 0000000..299d03a --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/writers/IConfigWriter.java @@ -0,0 +1,8 @@ +package org.minerift.ether.config.writers; + +import org.minerift.ether.config.Config; + +// Writes a Config object to its file +public interface IConfigWriter> { + void write(T config); +} diff --git a/main/src/main/java/org/minerift/ether/config/writers/SchematicConfigWriter.java b/main/src/main/java/org/minerift/ether/config/writers/SchematicConfigWriter.java new file mode 100644 index 0000000..acb0401 --- /dev/null +++ b/main/src/main/java/org/minerift/ether/config/writers/SchematicConfigWriter.java @@ -0,0 +1,10 @@ +package org.minerift.ether.config.writers; + +import org.minerift.ether.config.types.SchematicConfig; + +public class SchematicConfigWriter implements IConfigWriter { + @Override + public void write(SchematicConfig config) { + + } +}