From f0f7e229ea4ae10b982f87195bfc769061abd0a7 Mon Sep 17 00:00:00 2001 From: Auxilor Date: Wed, 23 Mar 2022 12:28:34 +0000 Subject: [PATCH] Began complete config rewrite --- .../java/com/willfp/eco/core/EcoPlugin.java | 2 +- .../willfp/eco/core/config/ConfigType.java | 24 +- .../eco/core/config/TransientConfig.java | 10 +- .../config/interfaces/LoadableConfig.java | 21 +- .../core/config/wrapper/ConfigFactory.java | 4 +- .../config/wrapper/LoadableConfigWrapper.java | 5 +- .../eco/internal/config/ConfigTypeHandlers.kt | 68 ++++++ .../willfp/eco/internal/config/ConfigUtils.kt | 20 -- .../EcoJSONConfigWrapper.kt => EcoConfig.kt} | 88 ++++--- .../eco/internal/config/EcoConfigFactory.kt | 100 +++----- .../eco/internal/config/EcoConfigSection.kt | 16 ++ ...ableJSONConfig.kt => EcoLoadableConfig.kt} | 30 +-- ...bleJSONConfig.kt => EcoUpdatableConfig.kt} | 22 +- .../config/json/EcoJSONConfigSection.kt | 11 - .../config/updating/EcoConfigHandler.kt | 15 +- .../updating/InvalidUpdateMethodException.kt | 3 + .../InvalidUpdateMethodException.kt | 3 - .../config/yaml/EcoLoadableYamlConfig.kt | 79 ------- .../config/yaml/EcoUpdatableYamlConfig.kt | 59 ----- .../config/yaml/EcoYamlConfigSection.kt | 11 - .../config/yaml/EcoYamlConfigWrapper.kt | 215 ------------------ 21 files changed, 257 insertions(+), 549 deletions(-) create mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/ConfigTypeHandlers.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/ConfigUtils.kt rename eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/{json/EcoJSONConfigWrapper.kt => EcoConfig.kt} (65%) create mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt rename eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/{json/EcoLoadableJSONConfig.kt => EcoLoadableConfig.kt} (81%) rename eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/{json/EcoUpdatableJSONConfig.kt => EcoUpdatableConfig.kt} (77%) delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigSection.kt create mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/InvalidUpdateMethodException.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/exceptions/InvalidUpdateMethodException.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoLoadableYamlConfig.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoUpdatableYamlConfig.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigSection.kt delete mode 100644 eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigWrapper.kt diff --git a/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java b/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java index 5c8c5fba..fed6d3ca 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java +++ b/eco-api/src/main/java/com/willfp/eco/core/EcoPlugin.java @@ -694,7 +694,7 @@ public abstract class EcoPlugin extends JavaPlugin implements PluginLike { public final FileConfiguration getConfig() { this.getLogger().warning("Call to default config method in eco plugin!"); - return Objects.requireNonNull(this.getConfigYml().getBukkitHandle()); + return Objects.requireNonNull(this.getConfigYml().toBukkit()); } /** diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/ConfigType.java b/eco-api/src/main/java/com/willfp/eco/core/config/ConfigType.java index 2721144e..603a2010 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/ConfigType.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/ConfigType.java @@ -1,5 +1,7 @@ package com.willfp.eco.core.config; +import org.jetbrains.annotations.NotNull; + /** * Config types, classified by file extension. */ @@ -7,10 +9,28 @@ public enum ConfigType { /** * .json config. */ - JSON, + JSON("json"), /** * .yml config. */ - YAML + YAML("yml"); + + /** + * The file extension. + */ + private final String extension; + + ConfigType(@NotNull final String extension) { + this.extension = extension; + } + + /** + * Get the file extension. + * + * @return The extension. + */ + public String getExtension() { + return extension; + } } diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java b/eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java index c0dfd1e6..f9a6074c 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/TransientConfig.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.file.Files; +import java.util.HashMap; import java.util.Map; /** @@ -71,7 +72,7 @@ public class TransientConfig extends ConfigWrapper { * @param values The values. */ public TransientConfig(@NotNull final Map values) { - super(Eco.getHandler().getConfigFactory().createConfig(values)); + super(Eco.getHandler().getConfigFactory().createConfig(values, ConfigType.YAML)); } /** @@ -82,17 +83,14 @@ public class TransientConfig extends ConfigWrapper { */ public TransientConfig(@NotNull final Map values, @NotNull final ConfigType type) { - super( - type == ConfigType.JSON ? Eco.getHandler().getConfigFactory().createConfig(values) - : new TransientConfig(Eco.getHandler().getConfigFactory().createConfig(values).toBukkit()) - ); + super(Eco.getHandler().getConfigFactory().createConfig(values, type)); } /** * Create a new empty transient config. */ public TransientConfig() { - super(Eco.getHandler().getConfigFactory().createConfig("", ConfigType.YAML)); + this(new HashMap<>(), ConfigType.JSON); } /** diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/LoadableConfig.java b/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/LoadableConfig.java index d2c59dd3..7259a9b9 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/LoadableConfig.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/interfaces/LoadableConfig.java @@ -1,7 +1,7 @@ package com.willfp.eco.core.config.interfaces; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.java.JavaPlugin; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.File; @@ -47,14 +47,21 @@ public interface LoadableConfig extends Config { /** * Get bukkit {@link YamlConfiguration}. *

- * This method is not recommended unless absolutely required as it - * only returns true if the type of config is {@link com.willfp.eco.core.config.ConfigType#YAML}, - * and if the handle is an {@link YamlConfiguration} specifically. This depends on the internals - * and the implementation, and so may cause problems - it exists mostly for parity with - * {@link JavaPlugin#getConfig()}. + * This used to represent the underlying config, but since 6.30.0 configs use + * their own implementations internally, without relying on bukkit. * * @return The config, or null if config is not yaml-based. + * @deprecated Use toBukkit() instead. */ @Nullable - YamlConfiguration getBukkitHandle(); + @Deprecated(since = "6.30.0", forRemoval = true) + default YamlConfiguration getBukkitHandle() { + return this.toBukkit(); + } + + /** + * Convert the config to a bukkit {@link YamlConfiguration}. + */ + @NotNull + YamlConfiguration toBukkit(); } diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/ConfigFactory.java b/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/ConfigFactory.java index 6d01e988..033e7e32 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/ConfigFactory.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/ConfigFactory.java @@ -65,9 +65,11 @@ public interface ConfigFactory { * Create config. * * @param values The values. + * @param type The config type. * @return The config implementation. */ - Config createConfig(@NotNull Map values); + Config createConfig(@NotNull Map values, + @NotNull ConfigType type); /** * Create config. diff --git a/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/LoadableConfigWrapper.java b/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/LoadableConfigWrapper.java index 73b308e8..c95457f3 100644 --- a/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/LoadableConfigWrapper.java +++ b/eco-api/src/main/java/com/willfp/eco/core/config/wrapper/LoadableConfigWrapper.java @@ -3,7 +3,6 @@ package com.willfp.eco.core.config.wrapper; import com.willfp.eco.core.config.interfaces.LoadableConfig; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import java.io.File; import java.io.IOException; @@ -47,7 +46,7 @@ public abstract class LoadableConfigWrapper extends ConfigWrapper + abstract fun toString(map: Map): String +} + +object YamlConfigTypeHandler : ConfigTypeHandler(ConfigType.YAML) { + private fun newYaml(): Yaml { + val yamlOptions = DumperOptions() + val loaderOptions = LoaderOptions() + val yamlRepresenter = YamlRepresenter() + + loaderOptions.maxAliasesForCollections = Int.MAX_VALUE + yamlOptions.indent = 2 + yamlOptions.defaultFlowStyle = DumperOptions.FlowStyle.BLOCK + yamlRepresenter.defaultFlowStyle = DumperOptions.FlowStyle.BLOCK + + return Yaml( + YamlConstructor(), + yamlRepresenter, + yamlOptions, + loaderOptions, + ) + } + + override fun toMap(input: String?): Map { + if (input == null || input.isBlank()) { + return emptyMap() + } + + return newYaml().load(input) + } + + override fun toString(map: Map): String { + return newYaml().dump(map) + } +} + +object JSONConfigTypeHandler : ConfigTypeHandler(ConfigType.JSON) { + private val gson = GsonBuilder() + .setPrettyPrinting() + .disableHtmlEscaping() + .create() + + override fun toMap(input: String?): Map { + return gson.fromJson(input ?: "{}", Map::class.java) as Map + } + + override fun toString(map: Map): String { + return gson.toJson(map) + } +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/ConfigUtils.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/ConfigUtils.kt deleted file mode 100644 index ca93e9ec..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/ConfigUtils.kt +++ /dev/null @@ -1,20 +0,0 @@ -package com.willfp.eco.internal.config - -import com.willfp.eco.core.config.interfaces.Config - -fun Any.ensureConfigSerializable(): Any = when (this) { - is Config -> this.toMap() - is Collection<*> -> { - val first = this.firstOrNull() - if (first is Config) { - @Suppress("UNCHECKED_CAST") - this as Collection - this.map { it.toMap() }.toMutableList() - } else if (this.isEmpty()) { - mutableListOf() // Don't use EmptyList, causes anchors as they have the same reference - } else { - this.toMutableList() - } - } - else -> this -} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigWrapper.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt similarity index 65% rename from eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigWrapper.kt rename to eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt index 287dd4b7..0530cb13 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigWrapper.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfig.kt @@ -1,23 +1,16 @@ -package com.willfp.eco.internal.config.json +package com.willfp.eco.internal.config -import com.google.gson.Gson -import com.google.gson.GsonBuilder import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.placeholder.StaticPlaceholder -import com.willfp.eco.internal.config.ensureConfigSerializable import com.willfp.eco.util.StringUtils +import org.bukkit.configuration.file.YamlConfiguration import java.util.concurrent.ConcurrentHashMap @Suppress("UNCHECKED_CAST") -open class EcoJSONConfigWrapper : Config { - companion object { - val gson: Gson = GsonBuilder() - .setPrettyPrinting() - .disableHtmlEscaping() - .create() - } - +open class EcoConfig( + private val configType: ConfigType +) : Config { val values = ConcurrentHashMap() var injections = mutableListOf() @@ -31,7 +24,7 @@ open class EcoJSONConfigWrapper : Config { } override fun toPlaintext(): String { - return gson.toJson(this.values) + return configType.handler.toString(this.values) } override fun has(path: String): Boolean { @@ -50,14 +43,16 @@ open class EcoJSONConfigWrapper : Config { } val found = values[nearestPath] ?: return null + return if (found is Map<*, *>) { val rawSection = found as Map - EcoJSONConfigSection(rawSection, injections) as? T? + EcoConfigSection(type, rawSection, injections) as? T? } else if (found is Iterable<*>) { val first = found.firstOrNull() // Type erasure if (first is Map<*, *>) { + println("Amogus? $found") val rawSections = found as Iterable> - rawSections.map { EcoJSONConfigSection(it, injections) } + rawSections.map { EcoConfigSection(type, it, injections) } } else { found } @@ -75,23 +70,38 @@ open class EcoJSONConfigWrapper : Config { if (path.contains(".")) { val remainingPath = path.removePrefix("${nearestPath}.") - val section = getOfKnownType(nearestPath, EcoJSONConfigWrapper::class.java) + val section = getOfKnownType(nearestPath, Any::class.java) if (section == null) { - values[nearestPath] = EcoJSONConfigSection(emptyMap(), injections) + values[nearestPath] = mutableMapOf() return setRecursively(path, obj) + } else if (section is EcoConfig) { + section.setRecursively(remainingPath, obj) } - - section.setRecursively(remainingPath, obj) } - values[nearestPath] = obj?.ensureConfigSerializable() + values[nearestPath] = when (obj) { + is Config -> obj.toMap() + is Collection<*> -> { + val first = obj.firstOrNull() + if (first is Config) { + @Suppress("UNCHECKED_CAST") + obj as Collection + obj.map { it.toMap() }.toMutableList() + } else if (obj.isEmpty()) { + mutableListOf() // Don't use EmptyList, causes anchors as they have the same reference + } else { + obj.toMutableList() + } + } + else -> obj + } } override fun getKeys(deep: Boolean): List { return if (deep) { recurseKeys(mutableSetOf()).toList() } else { - values.keys.toList() + values.keys.filterIsInstance().toList() } } @@ -100,9 +110,9 @@ open class EcoJSONConfigWrapper : Config { root: String = "" ): Set { for (key in getKeys(false)) { - list.add(root + key) + list.add("$root$key") val found = get(key) - if (found is EcoJSONConfigWrapper) { + if (found is EcoConfig) { list.addAll(found.recurseKeys(list, "$root$key.")) } } @@ -122,7 +132,7 @@ open class EcoJSONConfigWrapper : Config { } override fun getSubsection(path: String): Config { - return getSubsectionOrNull(path) ?: EcoJSONConfigSection(mutableMapOf(), injections) + return getSubsectionOrNull(path) ?: EcoConfigSection(type, mutableMapOf(), injections) } override fun getSubsectionOrNull(path: String): Config? { @@ -133,12 +143,16 @@ open class EcoJSONConfigWrapper : Config { return (getOfKnownType(path, Iterable::class.java) as? Iterable)?.toList() } + override fun getType(): ConfigType { + return configType + } + override fun getIntOrNull(path: String): Int? { - return getOfKnownType(path, Double::class.java)?.toInt() + return getOfKnownType(path, Number::class.java)?.toInt() } override fun getIntsOrNull(path: String): MutableList? { - return (getOfKnownType(path, Iterable::class.java) as Iterable?)?.toMutableList() + return (getOfKnownType(path, Iterable::class.java) as? Iterable)?.toMutableList() } override fun getBoolOrNull(path: String): Boolean? { @@ -146,7 +160,7 @@ open class EcoJSONConfigWrapper : Config { } override fun getBoolsOrNull(path: String): MutableList? { - return (getOfKnownType(path, Iterable::class.java) as Iterable?)?.toMutableList() + return (getOfKnownType(path, Iterable::class.java) as? Iterable)?.toMutableList() } override fun getStringOrNull( @@ -163,16 +177,16 @@ open class EcoJSONConfigWrapper : Config { format: Boolean, option: StringUtils.FormatOption ): List? { - val strings = (getOfKnownType(path, Iterable::class.java) as Iterable?)?.toList() ?: return null + val strings = (getOfKnownType(path, Iterable::class.java) as? Iterable)?.toList() ?: return null return if (format) StringUtils.formatList(strings, option) else strings } override fun getDoubleOrNull(path: String): Double? { - return getOfKnownType(path, Double::class.java) + return getOfKnownType(path, Number::class.java)?.toDouble() } override fun getDoublesOrNull(path: String): MutableList? { - return (getOfKnownType(path, Iterable::class.java) as Iterable?)?.toMutableList() + return (getOfKnownType(path, Iterable::class.java) as? Iterable)?.toMutableList() } override fun injectPlaceholders(placeholders: Iterable) { @@ -194,11 +208,19 @@ open class EcoJSONConfigWrapper : Config { return values.toMutableMap() } - override fun getType(): ConfigType { - return ConfigType.JSON + override fun toBukkit(): YamlConfiguration { + val temp = YamlConfiguration() + temp.createSection("temp", this.values.toMap()) + val section = temp.getConfigurationSection("temp")!! + + val bukkit = YamlConfiguration() + for (key in section.getKeys(true)) { + bukkit.set(key, section.get(key)) + } + return bukkit } override fun clone(): Config { - return EcoJSONConfigSection(this.values.toMutableMap(), injections) + return EcoConfigSection(type, this.values.toMutableMap(), injections) } } diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigFactory.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigFactory.kt index 9ff6730f..6f952068 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigFactory.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigFactory.kt @@ -5,38 +5,19 @@ import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.interfaces.Config import com.willfp.eco.core.config.interfaces.LoadableConfig import com.willfp.eco.core.config.wrapper.ConfigFactory -import com.willfp.eco.internal.config.json.EcoJSONConfigSection -import com.willfp.eco.internal.config.json.EcoJSONConfigWrapper -import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig -import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig -import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig -import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig -import com.willfp.eco.internal.config.yaml.EcoYamlConfigSection import org.bukkit.configuration.ConfigurationSection -import org.bukkit.configuration.file.YamlConfiguration -import java.io.StringReader +import java.io.BufferedReader +import java.io.Reader object EcoConfigFactory : ConfigFactory { - override fun createConfig(config: ConfigurationSection): Config { - return EcoYamlConfigSection(config) - } + override fun createConfig(config: ConfigurationSection): Config = + createConfig(config.getValues(true), ConfigType.YAML) - override fun createConfig(values: MutableMap): Config { - return EcoJSONConfigSection(values) - } + override fun createConfig(values: Map, type: ConfigType): Config = + EcoConfigSection(type, values) - override fun createConfig(contents: String, type: ConfigType): Config { - return if (type == ConfigType.JSON) { - @Suppress("UNCHECKED_CAST") - EcoJSONConfigSection( - EcoJSONConfigWrapper.gson.fromJson( - StringReader(contents), Map::class.java - ) as MutableMap - ) - } else { - EcoYamlConfigSection(YamlConfiguration.loadConfiguration(StringReader(contents))) - } - } + override fun createConfig(contents: String, type: ConfigType): Config = + EcoConfigSection(type, type.handler.toMap(contents)) override fun createLoadableConfig( configName: String, @@ -44,23 +25,13 @@ object EcoConfigFactory : ConfigFactory { subDirectoryPath: String, source: Class<*>, type: ConfigType - ): LoadableConfig { - return if (type == ConfigType.JSON) { - EcoLoadableJSONConfig( - configName, - plugin, - subDirectoryPath, - source - ) - } else { - EcoLoadableYamlConfig( - configName, - plugin, - subDirectoryPath, - source - ) - } - } + ): LoadableConfig = EcoLoadableConfig( + type, + configName, + plugin, + subDirectoryPath, + source + ) override fun createUpdatableConfig( configName: String, @@ -70,25 +41,28 @@ object EcoConfigFactory : ConfigFactory { removeUnused: Boolean, type: ConfigType, vararg updateBlacklist: String - ): LoadableConfig { - return if (type == ConfigType.JSON) { - EcoUpdatableJSONConfig( - configName, - plugin, - subDirectoryPath, - source, - removeUnused, - *updateBlacklist - ) - } else { - EcoUpdatableYamlConfig( - configName, - plugin, - subDirectoryPath, - source, - removeUnused, - *updateBlacklist - ) + ): LoadableConfig = EcoUpdatableConfig( + type, + configName, + plugin, + subDirectoryPath, + source, + removeUnused, + *updateBlacklist + ) +} + +fun Reader.readToString(): String { + val input = this as? BufferedReader ?: BufferedReader(this) + val builder = StringBuilder() + + var line: String? + input.use { + while (it.readLine().also { read -> line = read } != null) { + builder.append(line) + builder.append('\n') } } + + return builder.toString() } \ No newline at end of file diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt new file mode 100644 index 00000000..aa5daece --- /dev/null +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoConfigSection.kt @@ -0,0 +1,16 @@ +package com.willfp.eco.internal.config + +import com.willfp.eco.core.config.ConfigType +import com.willfp.eco.core.placeholder.StaticPlaceholder + +@Suppress("UNCHECKED_CAST") +class EcoConfigSection( + type: ConfigType, + values: Map, + injections: Collection = emptyList() +) : EcoConfig(type) { + init { + this.init(values) + this.injections = injections.toMutableList() + } +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoLoadableJSONConfig.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoLoadableConfig.kt similarity index 81% rename from eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoLoadableJSONConfig.kt rename to eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoLoadableConfig.kt index 8ce3963a..a220e2aa 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoLoadableJSONConfig.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoLoadableConfig.kt @@ -1,27 +1,28 @@ -package com.willfp.eco.internal.config.json +package com.willfp.eco.internal.config import com.willfp.eco.core.PluginLike +import com.willfp.eco.core.config.ConfigType import com.willfp.eco.core.config.interfaces.LoadableConfig -import org.bukkit.configuration.file.YamlConfiguration import java.io.File -import java.io.FileNotFoundException +import java.io.FileInputStream import java.io.FileOutputStream -import java.io.FileReader import java.io.IOException +import java.io.InputStreamReader import java.io.OutputStream +import java.io.Reader import java.nio.file.Files import java.nio.file.StandardOpenOption @Suppress("UNCHECKED_CAST") -open class EcoLoadableJSONConfig( +open class EcoLoadableConfig( + type: ConfigType, configName: String, private val plugin: PluginLike, private val subDirectoryPath: String, val source: Class<*> -) : EcoJSONConfigWrapper(), LoadableConfig { - +) : EcoConfig(type), LoadableConfig { private val configFile: File - private val name: String = "$configName.json" + private val name: String = "$configName.${type.extension}" fun reloadFromFile() { runCatching { init(configFile) }.onFailure { it.printStackTrace() } @@ -64,9 +65,12 @@ open class EcoLoadableJSONConfig( } } - @Throws(FileNotFoundException::class) + protected fun init(reader: Reader) { + super.init(type.handler.toMap(reader.readToString())) + } + fun init(file: File) { - super.init(gson.fromJson(FileReader(file), Map::class.java) as MutableMap) + init(InputStreamReader(FileInputStream(file), Charsets.UTF_8)) } override fun getName(): String { @@ -77,10 +81,6 @@ open class EcoLoadableJSONConfig( return configFile } - override fun getBukkitHandle(): YamlConfiguration? { - return null - } - init { val directory = File(this.plugin.dataFolder, subDirectoryPath) if (!directory.exists()) { @@ -93,4 +93,4 @@ open class EcoLoadableJSONConfig( init(configFile) plugin.configHandler.addConfig(this) } -} \ No newline at end of file +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoUpdatableJSONConfig.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoUpdatableConfig.kt similarity index 77% rename from eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoUpdatableJSONConfig.kt rename to eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoUpdatableConfig.kt index ee0fe1ec..0606dbcc 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoUpdatableJSONConfig.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/EcoUpdatableConfig.kt @@ -1,20 +1,21 @@ -package com.willfp.eco.internal.config.json +package com.willfp.eco.internal.config import com.willfp.eco.core.PluginLike -import org.bukkit.configuration.file.YamlConfiguration +import com.willfp.eco.core.config.ConfigType +import com.willfp.eco.core.config.interfaces.Config import java.io.BufferedReader import java.io.InputStreamReader import java.nio.charset.StandardCharsets -open class EcoUpdatableJSONConfig( +open class EcoUpdatableConfig( + type: ConfigType, configName: String, plugin: PluginLike, subDirectoryPath: String, source: Class<*>, private val removeUnused: Boolean, vararg updateBlacklist: String -) : EcoLoadableJSONConfig(configName, plugin, subDirectoryPath, source) { - +) : EcoLoadableConfig(type, configName, plugin, subDirectoryPath, source) { private val updateBlacklist: MutableList = mutableListOf(*updateBlacklist) fun update() { @@ -43,13 +44,14 @@ open class EcoUpdatableJSONConfig( this.save() } - private val configInJar: YamlConfiguration? + private val configInJar: Config? get() { val newIn = this.source.getResourceAsStream(resourcePath) ?: return null val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8)) - val newConfig = YamlConfiguration() - newConfig.load(reader) - return newConfig + + val config = EcoConfigSection(type, emptyMap()) + config.init(type.handler.toMap(reader.readToString())) + return config } init { @@ -57,4 +59,4 @@ open class EcoUpdatableJSONConfig( plugin.configHandler.addConfig(this) update() } -} \ No newline at end of file +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigSection.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigSection.kt deleted file mode 100644 index 71c62498..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/json/EcoJSONConfigSection.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.willfp.eco.internal.config.json - -import com.willfp.eco.core.placeholder.StaticPlaceholder - -@Suppress("UNCHECKED_CAST") -class EcoJSONConfigSection(values: Map, injections: Collection = emptyList()) : EcoJSONConfigWrapper() { - init { - init(values) - this.injections = injections.toMutableList() - } -} \ No newline at end of file diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/EcoConfigHandler.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/EcoConfigHandler.kt index bec20dc8..8cd16b57 100644 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/EcoConfigHandler.kt +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/EcoConfigHandler.kt @@ -4,11 +4,8 @@ import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.config.interfaces.LoadableConfig import com.willfp.eco.core.config.updating.ConfigHandler import com.willfp.eco.core.config.updating.ConfigUpdater -import com.willfp.eco.internal.config.json.EcoLoadableJSONConfig -import com.willfp.eco.internal.config.json.EcoUpdatableJSONConfig -import com.willfp.eco.internal.config.updating.exceptions.InvalidUpdateMethodException -import com.willfp.eco.internal.config.yaml.EcoLoadableYamlConfig -import com.willfp.eco.internal.config.yaml.EcoUpdatableYamlConfig +import com.willfp.eco.internal.config.EcoLoadableConfig +import com.willfp.eco.internal.config.EcoUpdatableConfig import org.reflections.Reflections import org.reflections.scanners.MethodAnnotationsScanner @@ -50,11 +47,9 @@ class EcoConfigHandler( override fun updateConfigs() { for (config in configs) { when (config) { - is EcoUpdatableYamlConfig -> config.update() - is EcoUpdatableJSONConfig -> config.update() - is EcoLoadableYamlConfig -> config.reloadFromFile() - is EcoLoadableJSONConfig -> config.reloadFromFile() + is EcoUpdatableConfig -> config.update() + is EcoLoadableConfig -> config.reloadFromFile() } } } -} \ No newline at end of file +} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/InvalidUpdateMethodException.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/InvalidUpdateMethodException.kt new file mode 100644 index 00000000..79dbbaad --- /dev/null +++ b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/InvalidUpdateMethodException.kt @@ -0,0 +1,3 @@ +package com.willfp.eco.internal.config.updating + +class InvalidUpdateMethodException(message: String) : RuntimeException(message) diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/exceptions/InvalidUpdateMethodException.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/exceptions/InvalidUpdateMethodException.kt deleted file mode 100644 index 38389347..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/updating/exceptions/InvalidUpdateMethodException.kt +++ /dev/null @@ -1,3 +0,0 @@ -package com.willfp.eco.internal.config.updating.exceptions - -class InvalidUpdateMethodException(message: String) : RuntimeException(message) \ No newline at end of file diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoLoadableYamlConfig.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoLoadableYamlConfig.kt deleted file mode 100644 index ab7a3c04..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoLoadableYamlConfig.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.willfp.eco.internal.config.yaml - -import com.willfp.eco.core.PluginLike -import com.willfp.eco.core.config.interfaces.LoadableConfig -import org.bukkit.configuration.file.YamlConfiguration -import java.io.File -import java.io.FileOutputStream -import java.io.IOException -import java.io.OutputStream - -open class EcoLoadableYamlConfig( - configName: String, - private val plugin: PluginLike, - private val subDirectoryPath: String, - val source: Class<*> -) : EcoYamlConfigWrapper(), LoadableConfig { - - private val configFile: File - private val name: String = "$configName.yml" - - fun reloadFromFile() { - handle.load(getConfigFile()) - } - - final override fun createFile() { - val inputStream = source.getResourceAsStream(resourcePath)!! - val outFile = File(this.plugin.dataFolder, resourcePath) - val lastIndex = resourcePath.lastIndexOf('/') - val outDir = File(this.plugin.dataFolder, resourcePath.substring(0, lastIndex.coerceAtLeast(0))) - if (!outDir.exists()) { - outDir.mkdirs() - } - if (!outFile.exists()) { - val out: OutputStream = FileOutputStream(outFile) - inputStream.copyTo(out) - out.close() - inputStream.close() - } - } - - override fun getResourcePath(): String { - val resourcePath: String = if (subDirectoryPath.isEmpty()) { - name - } else { - subDirectoryPath + name - } - return "/$resourcePath" - } - - @Throws(IOException::class) - override fun save() { - handle.save(getConfigFile()) - } - - override fun getName(): String { - return name - } - - override fun getConfigFile(): File { - return configFile - } - - override fun getBukkitHandle(): YamlConfiguration? { - return handle - } - - init { - val directory = File(this.plugin.dataFolder, subDirectoryPath) - if (!directory.exists()) { - directory.mkdirs() - } - if (!File(directory, name).exists()) { - createFile() - } - configFile = File(directory, name) - this.plugin.configHandler.addConfig(this) - init(YamlConfiguration.loadConfiguration(configFile)) - } -} diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoUpdatableYamlConfig.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoUpdatableYamlConfig.kt deleted file mode 100644 index 4fa4dd03..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoUpdatableYamlConfig.kt +++ /dev/null @@ -1,59 +0,0 @@ -package com.willfp.eco.internal.config.yaml - -import com.willfp.eco.core.PluginLike -import org.bukkit.configuration.file.YamlConfiguration -import java.io.BufferedReader -import java.io.InputStreamReader -import java.nio.charset.StandardCharsets - -class EcoUpdatableYamlConfig( - configName: String, - plugin: PluginLike, - subDirectoryPath: String, - source: Class<*>, - private val removeUnused: Boolean, - vararg updateBlacklist: String -) : EcoLoadableYamlConfig(configName, plugin, subDirectoryPath, source) { - private val updateBlacklist: MutableList = mutableListOf(*updateBlacklist) - - fun update() { - super.clearCache() - this.handle.load(configFile) - val newConfig = configInJar ?: return - if (newConfig.getKeys(true) == this.handle.getKeys(true)) { - return - } - newConfig.getKeys(true).forEach { key -> - if (!this.handle.getKeys(true).contains(key)) { - if (updateBlacklist.stream().noneMatch { key.contains(it) }) { - this.handle.set(key, newConfig[key]) - } - } - } - if (removeUnused) { - this.handle.getKeys(true).forEach { s -> - if (!newConfig.getKeys(true).contains(s)) { - if (updateBlacklist.stream().noneMatch(s::contains)) { - this.handle.set(s, null) - } - } - } - } - this.handle.save(configFile) - } - - private val configInJar: YamlConfiguration? - get() { - val newIn = source.getResourceAsStream(resourcePath) ?: return null - val reader = BufferedReader(InputStreamReader(newIn, StandardCharsets.UTF_8)) - val newConfig = YamlConfiguration() - newConfig.load(reader) - return newConfig - } - - init { - this.updateBlacklist.removeIf { it.isEmpty() } - plugin.configHandler.addConfig(this) - update() - } -} \ No newline at end of file diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigSection.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigSection.kt deleted file mode 100644 index 3efeec7e..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigSection.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.willfp.eco.internal.config.yaml - -import com.willfp.eco.core.placeholder.StaticPlaceholder -import org.bukkit.configuration.ConfigurationSection - -class EcoYamlConfigSection(section: ConfigurationSection, injections: Collection = emptyList()) : EcoYamlConfigWrapper() { - init { - init(section) - this.injections = injections.toMutableList() - } -} \ No newline at end of file diff --git a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigWrapper.kt b/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigWrapper.kt deleted file mode 100644 index 1e20538a..00000000 --- a/eco-core/core-backend/src/main/kotlin/com/willfp/eco/internal/config/yaml/EcoYamlConfigWrapper.kt +++ /dev/null @@ -1,215 +0,0 @@ -package com.willfp.eco.internal.config.yaml - -import com.github.benmanes.caffeine.cache.Cache -import com.github.benmanes.caffeine.cache.Caffeine -import com.willfp.eco.core.config.ConfigType -import com.willfp.eco.core.config.interfaces.Config -import com.willfp.eco.core.placeholder.StaticPlaceholder -import com.willfp.eco.internal.config.ensureConfigSerializable -import com.willfp.eco.util.StringUtils -import org.bukkit.configuration.ConfigurationSection -import org.bukkit.configuration.file.YamlConfiguration -import java.io.StringReader -import java.util.Optional - -@Suppress("UNCHECKED_CAST") -open class EcoYamlConfigWrapper : Config { - lateinit var handle: T - var injections = mutableListOf() - - private val cache: Cache> = Caffeine.newBuilder() - .build() - - protected fun init(config: T): Config { - handle = config - return this - } - - override fun toPlaintext(): String { - val temp = YamlConfiguration() - for (key in handle.getKeys(true)) { - temp[key] = handle[key] - } - return temp.saveToString() - } - - override fun clearCache() { - cache.invalidateAll() - } - - override fun has(path: String): Boolean { - return handle.contains(path) - } - - override fun getKeys(deep: Boolean): List { - return ArrayList(handle.getKeys(deep)) - } - - override fun get(path: String): Any? { - return handle[path] - } - - override fun set( - path: String, - obj: Any? - ) { - this.clearCache() - handle[path] = obj?.ensureConfigSerializable() - } - - override fun getSubsectionOrNull(path: String): Config? { - return cache.get(path) { - val raw = handle.getConfigurationSection(it) - if (raw == null) { - return@get Optional.empty() - } else { - return@get Optional.of(EcoYamlConfigSection(raw, injections)) - } - }.orElse(null) as? Config - } - - override fun getIntOrNull(path: String): Int? { - return (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getDouble(it).toInt() - Optional.of(raw) - }.orElse(null) as? Number)?.toInt() - } - - override fun getIntsOrNull(path: String): List? { - return (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getIntegerList(it) - Optional.of(raw) - }.orElse(null) as? Iterable)?.toList()?.map { it.toInt() } - } - - override fun getBoolOrNull(path: String): Boolean? { - return cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getBoolean(it) - Optional.of(raw) - }.orElse(null) as? Boolean - } - - override fun getBoolsOrNull(path: String): List? { - return (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getBooleanList(it) - Optional.of(raw) - }.orElse(null) as? Iterable)?.toList() - } - - override fun getStringOrNull( - path: String, - format: Boolean, - option: StringUtils.FormatOption - ): String? { - val string = cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getString(it) - Optional.ofNullable(raw) - }.orElse(null) as? String ?: return null - - return if (format) StringUtils.format(string, option) else string - } - - override fun getStringsOrNull( - path: String, - format: Boolean, - option: StringUtils.FormatOption - ): List? { - val strings = (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getStringList(it) - Optional.of(raw) - }.orElse(null) as? Iterable)?.toList() ?: return null - - return if (format) StringUtils.formatList(strings, option) else strings - } - - override fun getDoubleOrNull(path: String): Double? { - return (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getDouble(it) - Optional.of(raw) - }.orElse(null) as? Number)?.toDouble() - } - - override fun getDoublesOrNull(path: String): List? { - return (cache.get(path) { - if (!handle.contains(it)) { - return@get Optional.empty() - } - val raw = handle.getIntegerList(it) - Optional.of(raw) - }.orElse(null) as? Iterable)?.toList()?.map { it.toDouble() } - } - - override fun getSubsectionsOrNull(path: String): List? { - return (cache.get(path) { - val raw = handle.getMapList(it) - val configs = mutableListOf() - - for (map in raw) { - val temp = YamlConfiguration() // Empty config - temp.createSection("temp", map) - configs.add(EcoYamlConfigSection(temp.getConfigurationSection("temp")!!, injections)) - } - - if (configs.isEmpty()) { - return@get Optional.empty() - } else { - return@get Optional.of(configs) - } - }.orElse(null) as? Iterable)?.toList() - } - - override fun injectPlaceholders(placeholders: Iterable) { - injections.removeIf { placeholders.any { placeholder -> it.identifier == placeholder.identifier } } - injections.addAll(placeholders) - this.clearCache() - } - - override fun getInjectedPlaceholders(): List { - return injections.toList() - } - - override fun clearInjectedPlaceholders() { - injections.clear() - this.clearCache() - } - - override fun getType(): ConfigType { - return ConfigType.JSON - } - - override fun toMap(): MutableMap { - return handle.getValues(true) - } - - override fun clone(): Config { - return EcoYamlConfigSection( - YamlConfiguration.loadConfiguration( - StringReader( - toPlaintext() - ) - ), - injections - ) - } -}