Adds code for config migration with comment retaining
All checks were successful
KnarCraft/KnarLib/pipeline/head This commit looks good
All checks were successful
KnarCraft/KnarLib/pipeline/head This commit looks good
This commit is contained in:
162
src/main/java/net/knarcraft/knarlib/util/ConfigHelper.java
Normal file
162
src/main/java/net/knarcraft/knarlib/util/ConfigHelper.java
Normal file
@@ -0,0 +1,162 @@
|
||||
package net.knarcraft.knarlib.util;
|
||||
|
||||
import net.knarcraft.knarlib.config.StargateYamlConfiguration;
|
||||
import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.InvalidConfigurationException;
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with a plugin's configuration file
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class ConfigHelper {
|
||||
|
||||
private static final String CONFIG_FILE = "config.yml";
|
||||
private static final String BACKUP_CONFIG_FILE = "config.yml.old";
|
||||
private static final String MIGRATION_FILE = "config-migrations.txt";
|
||||
|
||||
private ConfigHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative string path of the configuration file
|
||||
*
|
||||
* @return <p>The configuration file path</p>
|
||||
*/
|
||||
public static String getConfigFile() {
|
||||
return CONFIG_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves any missing configuration values to the given plugin's configuration
|
||||
*
|
||||
* @param plugin <p>The plugin to add missing default values to</p>
|
||||
*/
|
||||
public static void saveDefaults(@NotNull Plugin plugin) {
|
||||
plugin.saveDefaultConfig();
|
||||
plugin.getConfig().options().copyDefaults(true);
|
||||
plugin.reloadConfig();
|
||||
plugin.saveConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes all configuration values from the old name to the new name
|
||||
*
|
||||
* <p>Note: This method expects a file "config-migrations.txt" in the resources directory that contains mappings:
|
||||
* oldKey=replacementKey in order to migrate from old to new configuration values.
|
||||
* The old configuration file will be saved to config.yml.old</p>
|
||||
*
|
||||
* @param plugin <p>The plugin to migrate the configuration for</p>
|
||||
* @return <p>True if the migration succeeded without any issues</p>
|
||||
*/
|
||||
public static boolean migrateConfig(@NotNull Plugin plugin) {
|
||||
File dataFolder = plugin.getDataFolder();
|
||||
//Save the old config just in case something goes wrong
|
||||
try {
|
||||
StargateYamlConfiguration currentConfiguration = new StargateYamlConfiguration();
|
||||
currentConfiguration.load(new File(dataFolder, CONFIG_FILE));
|
||||
currentConfiguration.save(new File(dataFolder, BACKUP_CONFIG_FILE));
|
||||
} catch (IOException | InvalidConfigurationException exception) {
|
||||
plugin.getLogger().log(Level.WARNING, "Unable to save old backup and do migration");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Load old and new configuration
|
||||
plugin.reloadConfig();
|
||||
FileConfiguration oldConfiguration = plugin.getConfig();
|
||||
InputStream configStream = FileHelper.getInputStreamForInternalFile("/" + CONFIG_FILE);
|
||||
if (configStream == null) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Could not migrate the configuration, as the internal " +
|
||||
"configuration could not be read!");
|
||||
return false;
|
||||
}
|
||||
YamlConfiguration newConfiguration = StargateYamlConfiguration.loadConfiguration(
|
||||
FileHelper.getBufferedReaderFromInputStream(configStream));
|
||||
|
||||
//Read all available config migrations
|
||||
Map<String, String> migrationFields;
|
||||
try {
|
||||
InputStream migrationStream = FileHelper.getInputStreamForInternalFile("/" + MIGRATION_FILE);
|
||||
if (migrationStream == null) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Could not migrate the configuration, as the internal " +
|
||||
"migration paths could not be read!");
|
||||
return false;
|
||||
}
|
||||
migrationFields = FileHelper.readKeyValuePairs(FileHelper.getBufferedReaderFromInputStream(migrationStream),
|
||||
"=", ColorConversion.NONE);
|
||||
} catch (IOException exception) {
|
||||
plugin.getLogger().log(Level.WARNING, "Unable to load config migration file");
|
||||
return false;
|
||||
}
|
||||
|
||||
//Replace old config names with the new ones
|
||||
for (String key : migrationFields.keySet()) {
|
||||
if (oldConfiguration.contains(key)) {
|
||||
migrateProperty(migrationFields, key, oldConfiguration);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all keys to the new config
|
||||
for (String key : StargateYamlConfiguration.getKeysWithoutComments(oldConfiguration, true)) {
|
||||
if (oldConfiguration.get(key) instanceof MemorySection) {
|
||||
continue;
|
||||
}
|
||||
newConfiguration.set(key, oldConfiguration.get(key));
|
||||
}
|
||||
|
||||
try {
|
||||
newConfiguration.save(new File(dataFolder, CONFIG_FILE));
|
||||
} catch (IOException exception) {
|
||||
plugin.getLogger().log(Level.WARNING, "Unable to save migrated config");
|
||||
return false;
|
||||
}
|
||||
|
||||
plugin.reloadConfig();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates one configuration property
|
||||
*
|
||||
* @param migrationFields <p>The configuration fields to be migrated</p>
|
||||
* @param key <p>The key/path of the property to migrate</p>
|
||||
* @param oldConfiguration <p>The original pre-migration configuration</p>
|
||||
*/
|
||||
private static void migrateProperty(@NotNull Map<String, String> migrationFields, @NotNull String key,
|
||||
@NotNull FileConfiguration oldConfiguration) {
|
||||
String newPath = migrationFields.get(key);
|
||||
Object oldValue = oldConfiguration.get(key);
|
||||
if (!newPath.trim().isEmpty()) {
|
||||
if (oldConfiguration.isConfigurationSection(key)) {
|
||||
// Copy each value of a configuration section
|
||||
ConfigurationSection sourceSection = oldConfiguration.getConfigurationSection(key);
|
||||
ConfigurationSection destinationSection = oldConfiguration.createSection(newPath);
|
||||
if (sourceSection == null) {
|
||||
return;
|
||||
}
|
||||
for (String path : StargateYamlConfiguration.getKeysWithoutComments(sourceSection, true)) {
|
||||
destinationSection.set(path, sourceSection.get(path));
|
||||
}
|
||||
} else {
|
||||
// Copy the value to the new path
|
||||
oldConfiguration.set(newPath, oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the old path's value
|
||||
oldConfiguration.set(key, null);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user