From 5bed29bb0875d6f794d1f2a7f81a89c17ed536d8 Mon Sep 17 00:00:00 2001 From: Vinrobot Date: Fri, 22 Sep 2023 00:21:56 +0200 Subject: [PATCH] Simplify config Option --- .../net/vinrobot/mcemote/MinecraftEmote.java | 2 +- .../mcemote/config/Configuration.java | 13 ++++- .../mcemote/config/ConfigurationManager.java | 29 +++++------ .../mcemote/config/ConfigurationService.java | 4 +- .../{impl => }/file/FileConfiguration.java | 2 +- .../file/FileConfigurationService.java | 17 ++----- .../mcemote/config/{ => file}/TypedGson.java | 2 +- .../config/impl/ConfigurationImpl.java | 15 ------ .../mcemote/config/impl/OptionImpl.java | 32 ------------ .../mcemote/config/{ => options}/Option.java | 50 +++++++++---------- .../TwitchIdOption.java} | 8 ++- .../ValidationFailedException.java | 2 +- 12 files changed, 63 insertions(+), 113 deletions(-) rename src/main/java/net/vinrobot/mcemote/config/{impl => }/file/FileConfiguration.java (88%) rename src/main/java/net/vinrobot/mcemote/config/{impl => }/file/FileConfigurationService.java (71%) rename src/main/java/net/vinrobot/mcemote/config/{ => file}/TypedGson.java (94%) delete mode 100644 src/main/java/net/vinrobot/mcemote/config/impl/ConfigurationImpl.java delete mode 100644 src/main/java/net/vinrobot/mcemote/config/impl/OptionImpl.java rename src/main/java/net/vinrobot/mcemote/config/{ => options}/Option.java (61%) rename src/main/java/net/vinrobot/mcemote/config/{impl/TwitchIdOptionImpl.java => options/TwitchIdOption.java} (64%) rename src/main/java/net/vinrobot/mcemote/config/{ => options}/ValidationFailedException.java (89%) diff --git a/src/main/java/net/vinrobot/mcemote/MinecraftEmote.java b/src/main/java/net/vinrobot/mcemote/MinecraftEmote.java index 913d967..a98d2bb 100644 --- a/src/main/java/net/vinrobot/mcemote/MinecraftEmote.java +++ b/src/main/java/net/vinrobot/mcemote/MinecraftEmote.java @@ -3,7 +3,7 @@ import net.fabricmc.loader.api.FabricLoader; import net.vinrobot.mcemote.config.ConfigurationManager; import net.vinrobot.mcemote.config.ConfigurationService; -import net.vinrobot.mcemote.config.impl.file.FileConfigurationService; +import net.vinrobot.mcemote.config.file.FileConfigurationService; import java.nio.file.Path; diff --git a/src/main/java/net/vinrobot/mcemote/config/Configuration.java b/src/main/java/net/vinrobot/mcemote/config/Configuration.java index dad9083..18ebb57 100644 --- a/src/main/java/net/vinrobot/mcemote/config/Configuration.java +++ b/src/main/java/net/vinrobot/mcemote/config/Configuration.java @@ -1,5 +1,14 @@ package net.vinrobot.mcemote.config; -public interface Configuration { - Option twitchId(); +import net.vinrobot.mcemote.config.options.Option; +import net.vinrobot.mcemote.config.options.TwitchIdOption; + +public class Configuration { + private static final String SCRAPIE_TWITCH_ID = "40646018"; + + private final Option twitchId = new TwitchIdOption(SCRAPIE_TWITCH_ID); + + public Option twitchId() { + return this.twitchId; + } } diff --git a/src/main/java/net/vinrobot/mcemote/config/ConfigurationManager.java b/src/main/java/net/vinrobot/mcemote/config/ConfigurationManager.java index 33aacac..94f707e 100644 --- a/src/main/java/net/vinrobot/mcemote/config/ConfigurationManager.java +++ b/src/main/java/net/vinrobot/mcemote/config/ConfigurationManager.java @@ -3,18 +3,19 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.NoSuchFileException; -import java.util.LinkedHashSet; -import java.util.Set; +import java.util.Objects; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; import static net.vinrobot.mcemote.MinecraftEmoteMod.LOGGER; public class ConfigurationManager { - private final Set changeCallbacks = new LinkedHashSet<>(); + private final Queue changeCallbacks = new ConcurrentLinkedQueue<>(); private final ConfigurationService configService; private Configuration configuration; public ConfigurationManager(final ConfigurationService configService) { - this.configService = configService; + this.configService = Objects.requireNonNull(configService); } public Configuration getConfig() { @@ -23,28 +24,28 @@ public Configuration getConfig() { } public Configuration load() { - final ConfigurationService service = this.configService; + final Configuration config = new Configuration(); + try { LOGGER.info("Loading config"); - return this.configuration = service.load(); + this.configService.load(config); } catch (final NoSuchFileException e) { LOGGER.warn("Config file not found: {}", e.getFile()); - return this.configuration = service.create(); } catch (final FileNotFoundException e) { LOGGER.warn("Config file not found"); - return this.configuration = service.create(); } catch (final IOException e) { LOGGER.error("Failed to load config", e); - return this.configuration = service.create(); } finally { - this.triggerOnChange(); + this.triggerOnChange(config); } + + return this.configuration = config; } public void save() { final Configuration config = this.configuration; if (config != null) { - this.triggerOnChange(); + this.triggerOnChange(config); try { this.configService.save(config); @@ -55,16 +56,16 @@ public void save() { } public void reset() { - this.configuration = this.configService.create(); + this.configuration = null; } public void onChange(final ChangeCallback callback) { this.changeCallbacks.add(callback); } - public void triggerOnChange() { + private void triggerOnChange(final Configuration config) { for (final ChangeCallback callback : this.changeCallbacks) { - callback.onChange(this.configuration); + callback.onChange(config); } } diff --git a/src/main/java/net/vinrobot/mcemote/config/ConfigurationService.java b/src/main/java/net/vinrobot/mcemote/config/ConfigurationService.java index fd74b60..b38fc40 100644 --- a/src/main/java/net/vinrobot/mcemote/config/ConfigurationService.java +++ b/src/main/java/net/vinrobot/mcemote/config/ConfigurationService.java @@ -3,9 +3,7 @@ import java.io.IOException; public interface ConfigurationService { - Configuration create(); - - Configuration load() throws IOException; + void load(Configuration configuration) throws IOException; void save(Configuration config) throws IOException; } diff --git a/src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfiguration.java b/src/main/java/net/vinrobot/mcemote/config/file/FileConfiguration.java similarity index 88% rename from src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfiguration.java rename to src/main/java/net/vinrobot/mcemote/config/file/FileConfiguration.java index 6a815e7..d33de10 100644 --- a/src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfiguration.java +++ b/src/main/java/net/vinrobot/mcemote/config/file/FileConfiguration.java @@ -1,4 +1,4 @@ -package net.vinrobot.mcemote.config.impl.file; +package net.vinrobot.mcemote.config.file; import net.vinrobot.mcemote.config.Configuration; diff --git a/src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfigurationService.java b/src/main/java/net/vinrobot/mcemote/config/file/FileConfigurationService.java similarity index 71% rename from src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfigurationService.java rename to src/main/java/net/vinrobot/mcemote/config/file/FileConfigurationService.java index f50594f..e3ffc89 100644 --- a/src/main/java/net/vinrobot/mcemote/config/impl/file/FileConfigurationService.java +++ b/src/main/java/net/vinrobot/mcemote/config/file/FileConfigurationService.java @@ -1,9 +1,7 @@ -package net.vinrobot.mcemote.config.impl.file; +package net.vinrobot.mcemote.config.file; import net.vinrobot.mcemote.config.Configuration; import net.vinrobot.mcemote.config.ConfigurationService; -import net.vinrobot.mcemote.config.TypedGson; -import net.vinrobot.mcemote.config.impl.ConfigurationImpl; import java.io.IOException; import java.io.Reader; @@ -20,22 +18,15 @@ public FileConfigurationService(final Path configFile) { } @Override - public Configuration create() { - return new ConfigurationImpl(); - } - - @Override - public Configuration load() throws IOException { - FileConfiguration fileConfiguration; + public void load(final Configuration configuration) throws IOException { + final FileConfiguration fileConfiguration; try (final Reader reader = Files.newBufferedReader(this.configFile)) { fileConfiguration = this.gson.fromJson(reader, FileConfiguration.class); } - final Configuration config = this.create(); if (fileConfiguration != null) { - fileConfiguration.copyTo(config); + fileConfiguration.copyTo(configuration); } - return config; } @Override diff --git a/src/main/java/net/vinrobot/mcemote/config/TypedGson.java b/src/main/java/net/vinrobot/mcemote/config/file/TypedGson.java similarity index 94% rename from src/main/java/net/vinrobot/mcemote/config/TypedGson.java rename to src/main/java/net/vinrobot/mcemote/config/file/TypedGson.java index 19b10a5..beef340 100644 --- a/src/main/java/net/vinrobot/mcemote/config/TypedGson.java +++ b/src/main/java/net/vinrobot/mcemote/config/file/TypedGson.java @@ -1,4 +1,4 @@ -package net.vinrobot.mcemote.config; +package net.vinrobot.mcemote.config.file; import com.google.gson.Gson; import com.google.gson.GsonBuilder; diff --git a/src/main/java/net/vinrobot/mcemote/config/impl/ConfigurationImpl.java b/src/main/java/net/vinrobot/mcemote/config/impl/ConfigurationImpl.java deleted file mode 100644 index 26fe1fc..0000000 --- a/src/main/java/net/vinrobot/mcemote/config/impl/ConfigurationImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.vinrobot.mcemote.config.impl; - -import net.vinrobot.mcemote.config.Configuration; -import net.vinrobot.mcemote.config.Option; - -public final class ConfigurationImpl implements Configuration { - private static final String SCRAPIE_TWITCH_ID = "40646018"; - - private final Option twitchId = new TwitchIdOptionImpl(SCRAPIE_TWITCH_ID); - - @Override - public Option twitchId() { - return this.twitchId; - } -} diff --git a/src/main/java/net/vinrobot/mcemote/config/impl/OptionImpl.java b/src/main/java/net/vinrobot/mcemote/config/impl/OptionImpl.java deleted file mode 100644 index b4b83e6..0000000 --- a/src/main/java/net/vinrobot/mcemote/config/impl/OptionImpl.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.vinrobot.mcemote.config.impl; - -import net.vinrobot.mcemote.config.Option; - -import java.util.Objects; -import java.util.Optional; - -public class OptionImpl implements Option { - private final T defaultValue; - private Optional value = Optional.empty(); - - public OptionImpl(final T defaultValue) { - this.defaultValue = defaultValue; - } - - @Override - public Option set(final Optional value) { - value.ifPresent(this::validate); - this.value = Objects.requireNonNull(value); - return this; - } - - @Override - public Optional getRaw() { - return this.value; - } - - @Override - public T getDefault() { - return this.defaultValue; - } -} diff --git a/src/main/java/net/vinrobot/mcemote/config/Option.java b/src/main/java/net/vinrobot/mcemote/config/options/Option.java similarity index 61% rename from src/main/java/net/vinrobot/mcemote/config/Option.java rename to src/main/java/net/vinrobot/mcemote/config/options/Option.java index 548c393..65c0e80 100644 --- a/src/main/java/net/vinrobot/mcemote/config/Option.java +++ b/src/main/java/net/vinrobot/mcemote/config/options/Option.java @@ -1,25 +1,18 @@ -package net.vinrobot.mcemote.config; - -import net.vinrobot.mcemote.config.impl.OptionImpl; +package net.vinrobot.mcemote.config.options; import java.util.Objects; import java.util.Optional; -public interface Option { +public class Option { static Option of(final T defaultValue) { - return new OptionImpl<>(defaultValue); + return new Option<>(defaultValue); } - static Option of(final T defaultValue, Optional value) { - final Option option = of(defaultValue); - option.set(value); - return option; - } + private final T defaultValue; + private Optional value = Optional.empty(); - static Option of(final T defaultValue, T value) { - final Option option = of(defaultValue); - option.set(value); - return option; + protected Option(final T defaultValue) { + this.defaultValue = defaultValue; } /** @@ -28,7 +21,11 @@ static Option of(final T defaultValue, T value) { * @param value The optional value to set. * @return This option. */ - Option set(Optional value); + public Option set(final Optional value) { + value.ifPresent(this::validate); + this.value = Objects.requireNonNull(value); + return this; + } /** * Set the value of this option. @@ -36,7 +33,7 @@ static Option of(final T defaultValue, T value) { * @param value The value to set. Must not be null. * @return This option. */ - default Option set(T value) { + public Option set(final T value) { return this.set(Optional.of(value)); } @@ -45,17 +42,16 @@ default Option set(T value) { * * @return This option. */ - default Option reset() { + public Option reset() { return this.set(Optional.empty()); } /** - * Get the value of this option. - * Returns the default value if the value is not set. + * Get the value of this option. Returns the default value if the value is not set. * * @return The value of this option. */ - default T get() { + public T get() { return this.getRaw().orElseGet(this::getDefault); } @@ -64,14 +60,18 @@ default T get() { * * @return The raw value of this option. */ - Optional getRaw(); + public Optional getRaw() { + return this.value; + } /** * Get the default value of this option. * * @return The default value of this option. */ - T getDefault(); + public T getDefault() { + return this.defaultValue; + } /** * Validate the value of this option. @@ -79,18 +79,18 @@ default T get() { * @param value The value to validate. * @throws ValidationFailedException If the validation fails. */ - default void validate(final T value) throws ValidationFailedException { + public void validate(final T value) throws ValidationFailedException { Objects.requireNonNull(value); } /** * Check if the value of this option is valid. * - * @see #validate(T) * @param value The value to check. * @return True if the value is valid, false otherwise. + * @see #validate(T) */ - default boolean isValid(final T value) { + public boolean isValid(final T value) { try { this.validate(value); return true; diff --git a/src/main/java/net/vinrobot/mcemote/config/impl/TwitchIdOptionImpl.java b/src/main/java/net/vinrobot/mcemote/config/options/TwitchIdOption.java similarity index 64% rename from src/main/java/net/vinrobot/mcemote/config/impl/TwitchIdOptionImpl.java rename to src/main/java/net/vinrobot/mcemote/config/options/TwitchIdOption.java index 1f82452..fe90ba8 100644 --- a/src/main/java/net/vinrobot/mcemote/config/impl/TwitchIdOptionImpl.java +++ b/src/main/java/net/vinrobot/mcemote/config/options/TwitchIdOption.java @@ -1,9 +1,7 @@ -package net.vinrobot.mcemote.config.impl; +package net.vinrobot.mcemote.config.options; -import net.vinrobot.mcemote.config.ValidationFailedException; - -public class TwitchIdOptionImpl extends OptionImpl { - public TwitchIdOptionImpl(final String defaultValue) { +public class TwitchIdOption extends Option { + public TwitchIdOption(final String defaultValue) { super(defaultValue); } diff --git a/src/main/java/net/vinrobot/mcemote/config/ValidationFailedException.java b/src/main/java/net/vinrobot/mcemote/config/options/ValidationFailedException.java similarity index 89% rename from src/main/java/net/vinrobot/mcemote/config/ValidationFailedException.java rename to src/main/java/net/vinrobot/mcemote/config/options/ValidationFailedException.java index 268c36e..d8ff0b8 100644 --- a/src/main/java/net/vinrobot/mcemote/config/ValidationFailedException.java +++ b/src/main/java/net/vinrobot/mcemote/config/options/ValidationFailedException.java @@ -1,4 +1,4 @@ -package net.vinrobot.mcemote.config; +package net.vinrobot.mcemote.config.options; public class ValidationFailedException extends RuntimeException { private static final long serialVersionUID = 1L;