Util Comment-supporting configs!

Discussion in 'Resources' started by AlvinB, Feb 16, 2017.

Thread Status:
Not open for further replies.
  1. Aren't we all tired of the fact that configs don't keep comments? Well, I decided to make a little util class to fix this problem. All you need to do is add the below class to your project, and use
    Code:java
    1. CommentYamlConfiguration.loadConfiguration(File file);
    The class also includes a JavaPlugin which uses the comment-supporting configs, all you need to do is extend CommentYamlConfiguration.JavaPlugin instead of JavaPlugin.

    Here's the class:
    Code:java
    1. import com.google.common.base.Charsets;
    2. import com.google.common.collect.Maps;
    3. import com.google.common.io.Files;
    4. import org.apache.commons.lang.Validate;
    5. import org.bukkit.Bukkit;
    6. import org.bukkit.configuration.InvalidConfigurationException;
    7. import org.bukkit.configuration.file.FileConfiguration;
    8. import org.bukkit.configuration.file.YamlConfiguration;
    9.  
    10. import java.io.*;
    11. import java.util.*;
    12. import java.util.logging.Level;
    13.  
    14. public class CommentYamlConfiguration extends YamlConfiguration {
    15. private Map<Integer, String> comments = Maps.newHashMap();
    16. @Override
    17. public void load(Reader reader) throws IOException, InvalidConfigurationException {
    18. StringBuilder builder = new StringBuilder();
    19.  
    20. String line;
    21. try (BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader)) {
    22. int index = 0;
    23. while ((line = input.readLine()) != null) {
    24. if (line.startsWith("#") || line.isEmpty()) {
    25. comments.put(index, line);
    26. }
    27. builder.append(line);
    28. builder.append(System.lineSeparator());
    29. index++;
    30. }
    31. }
    32. this.loadFromString(builder.toString());
    33. }
    34.  
    35. @Override
    36. public void save(File file) throws IOException {
    37. Validate.notNull(file, "File cannot be null");
    38. Files.createParentDirs(file);
    39. String data = this.saveToString();
    40. if (comments.size() != 0) {
    41. String[] stringArray = data.split(System.lineSeparator());
    42. StringBuilder stringBuilder = new StringBuilder();
    43. int arrayIndex = 0;
    44. for (int i = 0; i < stringArray.length + comments.size(); i++) {
    45. if (comments.containsKey(i)) {
    46. stringBuilder.append(System.lineSeparator()).append(comments.get(i));
    47. } else {
    48. if (arrayIndex >= stringArray.length) {
    49. stringBuilder.append(System.lineSeparator());
    50. } else {
    51. stringBuilder.append(System.lineSeparator()).append(stringArray[arrayIndex++]);
    52. }
    53. }
    54. }
    55. data = stringBuilder.toString().substring(1);
    56. }
    57.  
    58. try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) {
    59. writer.write(data);
    60. }
    61. }
    62.  
    63. @Override
    64. protected String buildHeader() {
    65. return "";
    66. }
    67.  
    68. @Override
    69. protected String parseHeader(String input) {
    70. return "";
    71. }
    72.  
    73. public static YamlConfiguration loadConfiguration(File file) {
    74. Validate.notNull(file, "File cannot be null");
    75. YamlConfiguration config = new CommentYamlConfiguration();
    76. try {
    77. config.load(file);
    78. } catch (FileNotFoundException e) {
    79. e.printStackTrace();
    80. } catch (IOException | InvalidConfigurationException var4) {
    81. Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, var4);
    82. }
    83.  
    84. return config;
    85. }
    86.  
    87. public static class JavaPlugin extends org.bukkit.plugin.java.JavaPlugin {
    88. private File configFile;
    89. private FileConfiguration config;
    90.  
    91. @Override
    92. public void reloadConfig() {
    93. if (configFile == null) {
    94. configFile = new File(this.getDataFolder(), "config.yml");
    95. }
    96. config = loadConfiguration(configFile);
    97. InputStream defConfigStream = this.getResource("config.yml");
    98. if(defConfigStream != null) {
    99. config.setDefaults(loadConfiguration(new InputStreamReader(defConfigStream, Charsets.UTF_8)));
    100. }
    101. }
    102.  
    103. @Override
    104. public FileConfiguration getConfig() {
    105. if(this.config == null) {
    106. this.reloadConfig();
    107. }
    108. return this.config;
    109. }
    110. }
    111. }


    Also, please note that this might not work as you expect if the amount of lines above the comments changes. I'd recommend keeping anything that might be an unpredictable amount of lines at the bottom with no comments below it.
     
    Last edited: May 28, 2017
  2. Offline

    pretocki3

  3. Offline

    Tecno_Wizard

    @AlvinB, that's really funny. I was thinking about working on the same thing and realized I'd have the same limitation you ran into.

    Nice extending JavaPlugin though. That's how all my own libraries work now in addition to reading additional data off the plugin.yml, an idea @I Al Istannen has begun to shamelessly steal (not that I care). lol
     
  4. Offline

    PhantomUnicorns

    Instead of hard coding
    Code:
    "\n"
    
    Isn't System.lineSeperator better? I was just wondering and I personally don't know, but to my insight it is better.
     
    Last edited: Feb 18, 2017
  5. Offline

    Tecno_Wizard

    @PhantomUnicorns, yeah. It is. Java is an architecture neutral language, and not all systems will use that character to break the end of the line.
     
  6. @PhantomUnicorns @Tecno_Wizard
    Fixed. Although I'm not sure it's entirely needed as System.lineSeperator() returns "\r\n" for my windows machine, but "\n" appears to be working just fine.
     
  7. Offline

    Tecno_Wizard

    @AlvinB Odd. Are you using the BASH shell?
     
  8. Offline

    Tecno_Wizard

    @AlvinB That. That is idiotic. #WindowsProblems.

    I can imagine the conversation between the engineers.
    "Should we check to make sure the \r isn't already there?"
    "Nah. Too much effort."
    "Sounds good."
     
  9. Offline

    PhantomUnicorns

    Hmm I know why but it's still pretty weird that the most people do # for comments in config.yml, I know Ruby uses it (And a bunch others) but I'm use to seeing // :p
     
  10. @PhantomUnicorns
    I think // or # is just fine as a comment character. What annoys me is batch where you have to use the REM command. If you don't know that REM stood for reminder it's almost impossible to guess that it's a comment. (I know there's the "::" to comment out lines, but that doesn't work properly in all cases....)
     
Thread Status:
Not open for further replies.

Share This Page