From dec3c10ec11dd045c5c7a79c861788be531d1b9b Mon Sep 17 00:00:00 2001 From: NuclearW Date: Wed, 20 Feb 2013 13:11:06 -0500 Subject: [PATCH] As seen on TV: ConfigLoader v2 ConfigLoader will now read the internal and external versions of files it is loading to: - Prune old keys in the external not in the internal - Add new keys to the external from the internal Additionally, while order is not presently preserved, all comments will be copied out, even for new keys. Old keys will retain their values in the external if they differ from the internal. Also changed the config.yml to say the version on which the config was last updated, not first generated as this will be updated as part of copying out comments. Known issue: Extra spacing in the internal config files will not be copied out. Closes #629 --- .../gmail/nossr50/config/ConfigLoader.java | 91 +++++++++++++++++++ src/main/resources/config.yml | 2 +- 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/gmail/nossr50/config/ConfigLoader.java b/src/main/java/com/gmail/nossr50/config/ConfigLoader.java index d12968216..ceb305d54 100644 --- a/src/main/java/com/gmail/nossr50/config/ConfigLoader.java +++ b/src/main/java/com/gmail/nossr50/config/ConfigLoader.java @@ -1,9 +1,16 @@ package com.gmail.nossr50.config; +import java.io.BufferedReader; +import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; +import java.io.FileWriter; import java.io.InputStream; +import java.io.InputStreamReader; import java.io.OutputStream; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -38,6 +45,90 @@ public abstract class ConfigLoader { } config = YamlConfiguration.loadConfiguration(configFile); + FileConfiguration internalConfig = YamlConfiguration.loadConfiguration(plugin.getResource(fileName)); + + Set configKeys = config.getKeys(true); + Set internalConfigKeys = internalConfig.getKeys(true); + + boolean needSave = false; + + Set oldKeys = new HashSet(configKeys); + oldKeys.removeAll(internalConfigKeys); + + Set newKeys = new HashSet(internalConfigKeys); + newKeys.removeAll(configKeys); + + // Don't need a re-save if we have old keys sticking around? + // Would be less saving, but less... correct? + if (!newKeys.isEmpty() || !oldKeys.isEmpty()) { + needSave = true; + } + + for (String key : oldKeys) { + plugin.debug("Removing unused key: " + key); + config.set(key, null); + } + + for (String key : newKeys) { + plugin.debug("Adding new key: " + key + " = " + internalConfig.get(key)); + config.set(key, internalConfig.get(key)); + } + + if (needSave) { + // Get Bukkit's version of an acceptable config with new keys, and no old keys + String output = config.saveToString(); + + // Convert to the superior 4 space indentation + output = output.replace(" ", " "); + + // Rip out Bukkit's attempt to save comments at the top of the file + while (output.indexOf('#') != -1) { + output = output.substring(output.indexOf('\n', output.indexOf('#'))+1); + } + + // Read the internal config to get comments, then put them in the new one + try { + // Read internal + BufferedReader reader = new BufferedReader(new InputStreamReader(plugin.getResource(fileName))); + HashMap comments = new HashMap(); + String temp = ""; + + String line; + while ((line = reader.readLine()) != null) { + if (line.contains("#")) { + temp += line + "\n"; + } + else if (line.contains(":")) { + line = line.substring(0, line.indexOf(":") + 1); + if(!temp.isEmpty()) { + comments.put(line, temp); + temp = ""; + } + } + } + + // Dump to the new one + for (String key : comments.keySet()) { + if (output.indexOf(key) != -1) { + output = output.substring(0, output.indexOf(key)) + comments.get(key) + output.substring(output.indexOf(key)); + } + } + } + catch (Exception e) { + e.printStackTrace(); + } + + // Save it + try { + BufferedWriter writer = new BufferedWriter(new FileWriter(new File(plugin.getDataFolder(), fileName))); + writer.write(output); + writer.flush(); + writer.close(); + } + catch (Exception e) { + e.printStackTrace(); + } + } } protected abstract void loadKeys(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 2799f196d..d027dc6fd 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,6 +1,6 @@ # # mcMMO configuration -# First generated on ${project.version}-b${BUILD_NUMBER} +# Last updated on ${project.version}-b${BUILD_NUMBER} # #####