From d583427f790c75aed265b5f9a569c6c6683f4bea Mon Sep 17 00:00:00 2001 From: Spexx Date: Sun, 5 Apr 2026 12:03:11 +0200 Subject: [PATCH 1/2] feat: add safe typed access methods to YamlConfig --- .../configurationAPI/config/YamlConfig.java | 155 ++++++++++++------ 1 file changed, 108 insertions(+), 47 deletions(-) diff --git a/src/main/java/dev/spexx/configurationAPI/config/YamlConfig.java b/src/main/java/dev/spexx/configurationAPI/config/YamlConfig.java index 50c72a0..1987621 100644 --- a/src/main/java/dev/spexx/configurationAPI/config/YamlConfig.java +++ b/src/main/java/dev/spexx/configurationAPI/config/YamlConfig.java @@ -4,6 +4,8 @@ import org.jetbrains.annotations.NotNull; import java.io.File; +import java.util.List; +import java.util.Optional; /** * Immutable snapshot of a YAML configuration file. @@ -28,73 +30,132 @@ * cache instances long-term if they require access to the most up-to-date * configuration state.

* - * @apiNote - * To obtain the latest configuration, retrieve a new instance from the managing - * component instead of reusing previously obtained references. - * - * @implSpec - * Thread-safety is achieved through immutability and atomic replacement of - * instances at a higher level (for example, by the configuration manager). - * - * @implNote - * The underlying {@link FileConfiguration} instance is assumed to be used in a - * read-only manner. Modifying it directly may lead to inconsistent behavior. - * - * @since 1.0.0 + * @since 1.1.0 */ -public final class YamlConfig { +public record YamlConfig(@NotNull File file, @NotNull FileConfiguration config) { /** - * The underlying configuration file on disk. + * Returns the underlying configuration file. */ - private final @NotNull File file; + @Override + public @NotNull File file() { + return file; + } /** - * Parsed configuration snapshot. + * Returns the parsed configuration snapshot. + * + *

This object should be treated as read-only.

*/ - private final @NotNull FileConfiguration config; + @Override + public @NotNull FileConfiguration config() { + return config; + } + + // ========================================================= + // Optional-based getters (safe access) + // ========================================================= /** - * Constructs a new {@code YamlConfig} instance. - * - *

The provided {@link FileConfiguration} is assumed to represent a fully - * parsed and valid snapshot of the given file.

+ * Returns a string value at the given path. * - * @param file the configuration file, must not be {@code null} - * @param config the parsed configuration snapshot, must not be {@code null} + * @param path config path + * @return Optional containing the value, or empty if not present */ - public YamlConfig( - @NotNull File file, - @NotNull FileConfiguration config - ) { - this.file = file; - this.config = config; + public @NotNull Optional getString(@NotNull String path) { + return Optional.ofNullable(config.getString(path)); } /** - * Returns the underlying configuration file. - * - *

This refers to the physical file on disk from which this snapshot - * was created.

+ * Returns an integer value at the given path. * - * @return the configuration file, never {@code null} + *

This method avoids Bukkit's default fallback (0) by checking presence.

*/ - public @NotNull File file() { - return file; + public @NotNull Optional getInt(@NotNull String path) { + return config.contains(path) + ? Optional.of(config.getInt(path)) + : Optional.empty(); } /** - * Returns the parsed configuration snapshot. - * - *

The returned {@link FileConfiguration} represents a stable, immutable - * view of the configuration at the time this {@code YamlConfig} instance - * was created.

- * - *

This object should be treated as read-only.

+ * Returns a boolean value at the given path. + */ + public @NotNull Optional getBoolean(@NotNull String path) { + return config.contains(path) + ? Optional.of(config.getBoolean(path)) + : Optional.empty(); + } + + /** + * Returns a double value at the given path. + */ + public @NotNull Optional getDouble(@NotNull String path) { + return config.contains(path) + ? Optional.of(config.getDouble(path)) + : Optional.empty(); + } + + /** + * Returns a float value at the given path. + */ + public @NotNull Optional getFloat(@NotNull String path) { + return config.contains(path) + ? Optional.of((float) config.getDouble(path)) + : Optional.empty(); + } + + /** + * Returns a string list at the given path. + */ + public @NotNull Optional> getStringList(@NotNull String path) { + return config.contains(path) + ? Optional.of(config.getStringList(path)) + : Optional.empty(); + } + + /** + * Returns a raw object at the given path. + */ + public @NotNull Optional get(@NotNull String path) { + return Optional.ofNullable(config.get(path)); + } + + // ========================================================= + // Default-based getters (most commonly used) + // ========================================================= + + public @NotNull String getStringOrDefault(@NotNull String path, @NotNull String def) { + String value = config.getString(path); + return value != null ? value : def; + } + + public int getIntOrDefault(@NotNull String path, int def) { + return config.getInt(path, def); + } + + public boolean getBooleanOrDefault(@NotNull String path, boolean def) { + return config.getBoolean(path, def); + } + + public double getDoubleOrDefault(@NotNull String path, double def) { + return config.getDouble(path, def); + } + + public float getFloatOrDefault(@NotNull String path, float def) { + return (float) config.getDouble(path, def); + } + + // ========================================================= + // Utility + // ========================================================= + + /** + * Checks whether a value exists at the given path. * - * @return the configuration snapshot, never {@code null} + * @param path config path + * @return true if present */ - public @NotNull FileConfiguration config() { - return config; + public boolean has(@NotNull String path) { + return config.contains(path); } } \ No newline at end of file From 90aeb916e22ebb7217627ca13651be3e76776954 Mon Sep 17 00:00:00 2001 From: Spexx Date: Sun, 5 Apr 2026 12:04:16 +0200 Subject: [PATCH 2/2] chore: bump version to 1.1 --- pom.xml | 2 +- src/main/resources/paper-plugin.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index dec1722..0b25067 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ dev.spexx ConfigurationAPI - 1.0.6 + 1.1 jar ConfigurationAPI diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml index 9c44f3b..fbd112a 100644 --- a/src/main/resources/paper-plugin.yml +++ b/src/main/resources/paper-plugin.yml @@ -1,6 +1,6 @@ name: ConfigurationAPI description: $description -version: '1.0.6' +version: '1.1' main: dev.spexx.configurationAPI.ConfigurationAPI api-version: '1.21.11'