diff --git a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java index d69f316e..2d6f0899 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java +++ b/src/main/java/com/onarandombox/MultiverseCore/MultiverseCore.java @@ -358,7 +358,8 @@ public class MultiverseCore extends JavaPlugin implements MVCore { */ @Override public boolean saveAllConfigs() { - return configProvider.get().save() + // TODO: Make this all Try + return configProvider.get().save().isSuccess() && worldManagerProvider.get().saveWorldsConfig() && anchorManagerProvider.get().saveAnchors(); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/api/MVConfig.java b/src/main/java/com/onarandombox/MultiverseCore/api/MVConfig.java index 55d11a78..c852a627 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/api/MVConfig.java +++ b/src/main/java/com/onarandombox/MultiverseCore/api/MVConfig.java @@ -12,7 +12,7 @@ public interface MVConfig { * Loads the config from disk. * @return True if the config was loaded successfully. */ - boolean load(); + Try load(); /** * Whether the config has been loaded. @@ -23,7 +23,7 @@ public interface MVConfig { /** * Saves the config to disk. */ - boolean save(); + Try save(); /** * Gets the nodes for the config. diff --git a/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java b/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java index ee269b44..dcee3cd1 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java +++ b/src/main/java/com/onarandombox/MultiverseCore/commands/ReloadCommand.java @@ -50,7 +50,8 @@ public class ReloadCommand extends MultiverseCommand { public void onReloadCommand(@NotNull BukkitCommandIssuer issuer) { issuer.sendInfo(MVCorei18n.RELOAD_RELOADING); try { - this.config.load(); + // TODO: Make this all Try + this.config.load().getOrElseThrow(e -> new RuntimeException("Failed to load config", e)); this.worldManager.initAllWorlds(); this.anchorManager.loadAnchors(); } catch (Exception e) { diff --git a/src/main/java/com/onarandombox/MultiverseCore/config/MVCoreConfig.java b/src/main/java/com/onarandombox/MultiverseCore/config/MVCoreConfig.java index 8afb8a18..1e713b84 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/config/MVCoreConfig.java +++ b/src/main/java/com/onarandombox/MultiverseCore/config/MVCoreConfig.java @@ -89,7 +89,7 @@ public class MVCoreConfig implements MVConfig { } @Override - public boolean load() { + public Try load() { migrateFromOldConfigFile(); return configHandle.load(); } @@ -100,9 +100,8 @@ public class MVCoreConfig implements MVConfig { } @Override - public boolean save() { - configHandle.save(); - return true; + public Try save() { + return configHandle.save(); } @Override diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/CommentedYamlConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/CommentedYamlConfigHandle.java index f43a2a86..b455fa47 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/CommentedYamlConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/CommentedYamlConfigHandle.java @@ -1,5 +1,6 @@ package com.onarandombox.MultiverseCore.configuration.handle; +import java.io.IOException; import java.nio.file.Path; import java.util.logging.Logger; @@ -9,6 +10,7 @@ import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; import com.onarandombox.MultiverseCore.configuration.node.CommentedNode; import com.onarandombox.MultiverseCore.configuration.node.ValueNode; import io.github.townyadvanced.commentedconfiguration.CommentedConfiguration; +import io.vavr.control.Try; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -35,9 +37,12 @@ public class CommentedYamlConfigHandle extends FileConfigHandle save() { + // TODO: There is no way to check if the save was successful. + return Try.run(() -> config.save()); } public static class Builder extends FileConfigHandle.Builder { diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/ConfigurationSectionHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/ConfigurationSectionHandle.java index 6802a166..6a3bf1b4 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/ConfigurationSectionHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/ConfigurationSectionHandle.java @@ -2,6 +2,7 @@ package com.onarandombox.MultiverseCore.configuration.handle; import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; +import io.vavr.control.Try; import org.bukkit.configuration.ConfigurationSection; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -16,7 +17,7 @@ public class ConfigurationSectionHandle extends GenericConfigHandle(configurationSection); } - public ConfigurationSectionHandle(@NotNull ConfigurationSection configurationSection, + protected ConfigurationSectionHandle(@NotNull ConfigurationSection configurationSection, @Nullable Logger logger, @Nullable NodeGroup nodes, @Nullable ConfigMigrator migrator) { @@ -24,6 +25,17 @@ public class ConfigurationSectionHandle extends GenericConfigHandle load(@NotNull ConfigurationSection section) { + this.config = section; + return load(); + } + /** * Builder for {@link ConfigurationSectionHandle}. * diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java index fd0cefb0..82d30dd8 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/FileConfigHandle.java @@ -5,12 +5,11 @@ import java.io.IOException; import java.nio.file.Path; import java.util.logging.Logger; -import com.dumptruckman.minecraft.util.Logging; import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; +import io.vavr.control.Try; +import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,49 +32,43 @@ abstract class FileConfigHandle extends GenericConf * {@inheritDoc} */ @Override - public boolean load() { - boolean newFileCreated; - try { - newFileCreated = createConfigFile(); - } catch (IOException e) { - Logging.severe("Failed to create config file: %s", configFile.getName()); - Logging.severe(e.getMessage()); - return false; - } - if (!loadConfigObject()) { - Logging.severe("Failed to load config file: %s", configFile.getName()); - return false; - } - if (!newFileCreated) { - migrateConfig(); - } - setUpNodes(); - return true; + public Try load() { + boolean isNewFile = !configFile.exists(); + return createConfigFile() + .andThenTry(this::loadConfigObject) + .andThenTry(() -> { + if (!isNewFile) { + migrateConfig(); + } + setUpNodes(); + }); } /** - * Create a new config file if file does not exist + * Create a new config file if file does not exist. * - * @return True if file exist or created successfully, otherwise false. + * @return Whether the file was created or its given error. */ - protected boolean createConfigFile() throws IOException { - if (configFile.exists()) { - return false; - } - return configFile.createNewFile(); + protected Try createConfigFile() { + return Try.run(() -> { + if (configFile.exists()) { + return; + } + if (!configFile.createNewFile()) { + throw new IOException("Failed to create config file: " + configFile.getName()); + } + }); } /** * Loads the configuration object. - * - * @return True if the configuration was loaded successfully, false otherwise. */ - protected abstract boolean loadConfigObject(); + protected abstract void loadConfigObject() throws IOException, InvalidConfigurationException; /** * Saves the configuration. */ - public abstract boolean save(); + public abstract Try save(); /** * Checks if the configuration is loaded. diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java index 1ba4c7f0..6644f4aa 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/GenericConfigHandle.java @@ -3,9 +3,7 @@ package com.onarandombox.MultiverseCore.configuration.handle; import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator; import com.onarandombox.MultiverseCore.configuration.node.ConfigNodeNotFoundException; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; -import com.onarandombox.MultiverseCore.configuration.node.NodeSerializer; import com.onarandombox.MultiverseCore.configuration.node.ValueNode; -import io.vavr.control.Option; import io.vavr.control.Try; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.plugin.Plugin; @@ -24,7 +22,7 @@ public abstract class GenericConfigHandle { protected C config; - public GenericConfigHandle(@Nullable Logger logger, @Nullable NodeGroup nodes, @Nullable ConfigMigrator migrator) { + protected GenericConfigHandle(@Nullable Logger logger, @Nullable NodeGroup nodes, @Nullable ConfigMigrator migrator) { this.logger = logger; this.nodes = nodes; this.migrator = migrator; @@ -33,12 +31,13 @@ public abstract class GenericConfigHandle { /** * Loads the configuration. * - * @return True if the configuration was loaded successfully, false otherwise. + * @return Whether the configuration was loaded or its given error. */ - public boolean load() { - migrateConfig(); - setUpNodes(); - return true; + public Try load() { + return Try.run(() -> { + migrateConfig(); + setUpNodes(); + }); } /** diff --git a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/YamlConfigHandle.java b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/YamlConfigHandle.java index 0a6e2cbe..edbfc82f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/YamlConfigHandle.java +++ b/src/main/java/com/onarandombox/MultiverseCore/configuration/handle/YamlConfigHandle.java @@ -6,7 +6,7 @@ import java.util.logging.Logger; import com.onarandombox.MultiverseCore.configuration.migration.ConfigMigrator; import com.onarandombox.MultiverseCore.configuration.node.NodeGroup; -import com.onarandombox.MultiverseCore.configuration.node.ValueNode; +import io.vavr.control.Try; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; @@ -35,27 +35,17 @@ public class YamlConfigHandle extends FileConfigHandle { * {@inheritDoc} */ @Override - protected boolean loadConfigObject() { + protected void loadConfigObject() throws IOException, InvalidConfigurationException { config = new YamlConfiguration(); - try { - config.load(configFile); - } catch (IOException | InvalidConfigurationException e) { - return false; - } - return true; + config.load(configFile); } /** * {@inheritDoc} */ @Override - public boolean save() { - try { - config.save(configFile); - } catch (IOException e) { - return false; - } - return true; + public Try save() { + return Try.run(() -> config.save(configFile)); } /** diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java index 55830293..c66dcd5f 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/WorldManager.java @@ -95,7 +95,9 @@ public class WorldManager { * Loads all worlds from the worlds config. */ public void initAllWorlds() { - populateWorldFromConfig(); + if (!populateWorldFromConfig()) { + return; + } loadDefaultWorlds(); autoLoadOfflineWorlds(); saveWorldsConfig(); @@ -104,8 +106,13 @@ public class WorldManager { /** * Generate offline worlds from the worlds config. */ - private void populateWorldFromConfig() { - worldsConfigManager.load(); + private boolean populateWorldFromConfig() { + Try load = worldsConfigManager.load(); + if (load.isFailure()) { + Logging.severe("Failed to load worlds config: " + load.getCause().getMessage()); + load.getCause().printStackTrace(); + return false; + } worldsConfigManager.getAllWorldConfigs().forEach(worldConfig -> { getMVWorld(worldConfig.getWorldName()) .peek(mvWorld -> mvWorld.setWorldConfig(worldConfig)); @@ -116,6 +123,7 @@ public class WorldManager { offlineWorldsMap.put(offlineWorld.getName(), offlineWorld); }); }); + return true; } /** @@ -785,6 +793,11 @@ public class WorldManager { * @return true if it had successfully saved the file. */ public boolean saveWorldsConfig() { - return worldsConfigManager.save(); + return worldsConfigManager.save() + .onFailure(failure -> { + Logging.severe("Failed to save worlds config: %s", failure); + failure.printStackTrace(); + }) + .isSuccess(); } } diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java index 2c1a116e..478457f9 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldConfig.java @@ -35,7 +35,7 @@ public class WorldConfig { load(); } - public boolean load() { + public Try load() { return configHandle.load(); } diff --git a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigManager.java b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigManager.java index 74e1d694..bc0d642e 100644 --- a/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigManager.java +++ b/src/main/java/com/onarandombox/MultiverseCore/worldnew/config/WorldsConfigManager.java @@ -1,6 +1,7 @@ package com.onarandombox.MultiverseCore.worldnew.config; import com.onarandombox.MultiverseCore.MultiverseCore; +import io.vavr.control.Try; import jakarta.inject.Inject; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; @@ -8,7 +9,6 @@ import org.jetbrains.annotations.NotNull; import org.jvnet.hk2.annotations.Service; import java.io.File; -import java.io.IOException; import java.util.Collection; import java.util.HashMap; import java.util.Map; @@ -23,32 +23,36 @@ public class WorldsConfigManager { private YamlConfiguration worldsConfig; @Inject - public WorldsConfigManager(@NotNull MultiverseCore core) { + WorldsConfigManager(@NotNull MultiverseCore core) { worldConfigMap = new HashMap<>(); worldConfigFile = core.getDataFolder().toPath().resolve(CONFIG_FILENAME).toFile(); - load(); } - public void load() { - worldsConfig = YamlConfiguration.loadConfiguration(worldConfigFile); + public Try load() { worldConfigMap.clear(); - for (String worldName : getAllWorldsInConfig()) { - worldConfigMap.put(worldName, new WorldConfig(worldName, getWorldConfigSection(worldName))); - } + + return Try.run(() -> { + if (!worldConfigFile.exists()) { + worldConfigFile.createNewFile(); + } + worldsConfig = new YamlConfiguration(); + worldsConfig.load(worldConfigFile); + }).andThenTry(() -> { + for (String worldName : getAllWorldsInConfig()) { + worldConfigMap.put(worldName, new WorldConfig(worldName, getWorldConfigSection(worldName))); + } + }).onFailure(e -> { + worldsConfig = null; + worldConfigMap.clear(); + }); } public boolean isLoaded() { return worldsConfig != null; } - public boolean save() { - try { - worldsConfig.save(worldConfigFile); - return true; - } catch (IOException e) { - e.printStackTrace(); - } - return false; + public Try save() { + return Try.run(() -> worldsConfig.save(worldConfigFile)); } public Set getAllWorldsInConfig() { diff --git a/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt index f8253bce..32d0d4b4 100644 --- a/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/config/ConfigTest.kt @@ -26,8 +26,8 @@ class ConfigTest : TestWithMockBukkit() { assertNotNull(defaultConfig) File(Path.of(multiverseCore.dataFolder.absolutePath, "config.yml").absolutePathString()).writeText(defaultConfig) - assertTrue(config.load()) - assertTrue(config.save()) + assertTrue(config.load().isSuccess) + assertTrue(config.save().isSuccess) } @Test @@ -40,8 +40,8 @@ class ConfigTest : TestWithMockBukkit() { val oldConfig = getResourceAsText("/old_config.yml") assertNotNull(oldConfig) multiverseCore.dataFolder.toPath().resolve("config.yml").toFile().writeText(oldConfig) - assertTrue(config.load()) - assertTrue(config.save()) + assertTrue(config.load().isSuccess) + assertTrue(config.save().isSuccess) assertEquals(true, config.enforceAccess) assertEquals(false, config.isEnablePrefixChat) diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt index d59994ed..822c1ac8 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigMangerTest.kt @@ -22,8 +22,10 @@ class WorldConfigMangerTest : TestWithMockBukkit() { assertNotNull(defaultConfig) File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) - worldConfigManager = - WorldsConfigManager(multiverseCore) + worldConfigManager = multiverseCore.getService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { + throw IllegalStateException("WorldsConfigManager is not available as a service") } + + assertTrue(worldConfigManager.load().isSuccess) } @Test diff --git a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt index 2c646c4d..113ab3c3 100644 --- a/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt +++ b/src/test/java/org/mvplugins/multiverse/core/world/WorldConfigTest.kt @@ -3,6 +3,7 @@ package org.mvplugins.multiverse.core.world import com.onarandombox.MultiverseCore.worldnew.config.WorldConfig import com.onarandombox.MultiverseCore.worldnew.config.WorldsConfigManager import org.bukkit.Location +import org.junit.jupiter.api.Assertions import org.mvplugins.multiverse.core.TestWithMockBukkit import java.io.File import java.nio.file.Path @@ -15,7 +16,7 @@ import kotlin.test.assertTrue class WorldConfigTest : TestWithMockBukkit() { - private lateinit var worldConfigFile : WorldsConfigManager + private lateinit var worldConfigManager : WorldsConfigManager private lateinit var worldConfig : WorldConfig @BeforeTest @@ -24,9 +25,12 @@ class WorldConfigTest : TestWithMockBukkit() { assertNotNull(defaultConfig) File(Path.of(multiverseCore.dataFolder.absolutePath, "worlds2.yml").absolutePathString()).writeText(defaultConfig) - worldConfigFile = - WorldsConfigManager(multiverseCore) - worldConfig = worldConfigFile.getWorldConfig("world") + worldConfigManager = multiverseCore.getService(WorldsConfigManager::class.java).takeIf { it != null } ?: run { + throw IllegalStateException("WorldsConfigManager is not available as a service") } + + assertTrue(worldConfigManager.load().isSuccess) + worldConfig = worldConfigManager.getWorldConfig("world") + assertNotNull(worldConfig); } @Test