Configuration Manager

Discussion in 'Resources' started by foodyling, Jul 4, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    foodyling

    I'm not sure if this will help anyone, but it's really helped me out creating plugins that need multiple configuration files with ease. (Sorry if someone else has posted something similar to this recently!). Class:
    Code:
    import java.io.File;
    import java.io.InputStream;
    import java.util.Iterator;
    import java.util.TreeMap;
    import java.util.logging.Level;
     
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.plugin.Plugin;
     
    /**
    * You're free to modify and redistribute this as long as some credit is given to me
    * @author Foodyling
    */
    public class ConfigManager {
        public static class ConfigPath {
            private final String configName;
            private final String resourcePath;
            private final String outputPath;
     
            public ConfigPath(String configName, String resourcePath, String outputPath) {
                this.configName = configName;
                this.resourcePath = resourcePath;
                this.outputPath = outputPath;
            }
     
            public String getName() {
                return configName;
            }
     
            public String getResourcePath() {
                return resourcePath;
            }
     
            public String getOutputPath() {
                return outputPath;
            }
        }
        public static class Configuration {
            private final File configFile;
            private FileConfiguration config;
     
            public Configuration (File configFile, FileConfiguration config) {
                this.configFile = configFile;
                this.config = config;
            }
     
            public FileConfiguration getConfig() {
                return config;
            }
     
            public File getFile() {
                return configFile;
            }
     
            public boolean reloadConfig() {
                try {
                    config = YamlConfiguration.loadConfiguration(configFile);
                    return true;
                } catch (Exception erorr) {
                    return false;
                }
            }
     
            public boolean saveConfig() {
                if (configFile != null) {
                    try {
                        config.save(configFile);
                        return true;
                    } catch (Throwable error) {
               
                    }
                }
                return false;
            }
        }
     
        private Plugin caller;
        private File configFolder;
        private final TreeMap<String, Configuration> configurations = new TreeMap<String, Configuration>(String.CASE_INSENSITIVE_ORDER);
     
        /**
        * Create a new instance of a ConfigManager for a specific plugin
        * @param pluginInstance Plugin that calls the ConfigManager
        */
        public ConfigManager(Plugin pluginInstance) {
            if (pluginInstance != null) {
                this.caller = pluginInstance;
                this.configFolder = pluginInstance.getDataFolder();
                if (!configFolder.exists()) {
                    configFolder.mkdirs();
                }
                caller.getLogger().log(Level.INFO, "Configuration Manager for plugin {0} successfully initialized", pluginInstance.getName());
            } else {
                Bukkit.getLogger().log(Level.SEVERE, "Configuration Manager failed to initialize");
            }
        }
     
        /**
        * Load all configuration files
        * @param configPaths Collection of configuration files to load
        */
        public void loadConfigFiles(ConfigPath... configPaths) {
            for (ConfigPath path : configPaths) {
                try {
                    String resourcePath = path.getResourcePath(),
                            outputPath = path.getOutputPath();
                    FileConfiguration config = null;
                    File configFile = null;
                    if (outputPath != null) {
                        configFile = new File(configFolder, outputPath);
                        if (configFile.exists()) {
                            config = YamlConfiguration.loadConfiguration(configFile);
                        } else {
                            if (resourcePath == null) {
                                configFile.mkdirs();
                                configFile.createNewFile();
                                config = YamlConfiguration.loadConfiguration(configFile);
                            } else {
                                InputStream inputStream = caller.getResource(resourcePath);
                                if (inputStream != null) {
                                    config = YamlConfiguration.loadConfiguration(inputStream);
                                    config.save(configFile);
                                }
                            }
                        }
                    } else {
                        InputStream inputStream = caller.getResource(resourcePath);
                        if (inputStream != null) {
                            config = YamlConfiguration.loadConfiguration(inputStream);
                        }
                    }
                    if (resourcePath != null && outputPath != null) {
                        try {
                            config.setDefaults(YamlConfiguration.loadConfiguration(caller.getResource(resourcePath)));
                        } catch (Throwable error) {
                            caller.getLogger().log(Level.SEVERE, "Failed to set defaults of config: " + path.getName());
                        }
                    }
                    if (config != null) {
                        configurations.put(path.getName(), new Configuration(configFile, config));
                    } else {
                        caller.getLogger().log(Level.SEVERE, "Error loading configuration: " + path.getName());
                    }
                } catch (Throwable error) {
                    error.printStackTrace();
                    caller.getLogger().log(Level.SEVERE, "Error loading configuration: " + path.getName());
                }
            }
        }
     
        /**
        *
        * @param configName Configuration name to save
        * @return Whether configuration saved successfully
        */
        public boolean saveConfig(String configName, boolean logError) {
            if (configurations.containsKey(configName)) {
                Configuration config = configurations.get(configName);
                if (config != null) {
                    boolean saved = config.saveConfig();
                    if (logError && !saved) {
                        caller.getLogger().log(Level.SEVERE, "Failed to save configuration: " + configName);
                    }
                    return saved;
                }
            }
            return false;
        }
     
        public boolean saveConfig(String configName) {
            return saveConfig(configName, false);
        }
     
        /**
        * Saves all configuration files
        */
        public void saveAllConfigs(boolean logError) {
            for (String configName : configurations.keySet()) {
                if (logError && !saveConfig(configName, logError)) {
                    caller.getLogger().log(Level.SEVERE, "Failed to save configuration: " + configName);
                }
            }
        }
     
        /**
        *
        * @param configName
        * @return Whether configuration was reloaded succesfully
        */
        public boolean reloadConfig(String configName) {
            if (configurations.containsKey(configName)) {
                Configuration config = configurations.get(configName);
                if (config != null) {
                    return config.reloadConfig();
                }
            }
            return false;
        }
     
        /**
        * Reloads all registered configuration manager
        */
        public void reloadAllConfigs() {
            for (String configName : configurations.keySet()) {
                reloadConfig(configName);
            }
        }
        
        /**
         *
         * @param configName Config to unload
         */
        public void unloadConfig(String configName) {
            configurations.remove(configName);
        }
        
        /**
         * Unloads all configuration files in memory
         */
        public void unloadAllConfigs() {
            for (Iterator<Configuration> iterator = configurations.values().iterator(); iterator.hasNext();) {
                iterator.next();
                iterator.remove();
            }
        }
     
     
        /**
        *
        * @param configName Configuration name
        * @return Configuration interface, returns null if not found
        */
        public Configuration getConfig(String configName) {
            if (configurations.containsKey(configName)) {
                return configurations.get(configName);
            } else {
                return null;
            }
        }
     
        /**
        *
        * @param configName Configuration name
        * @return FileConfiguration, returns null if not found
        */
        public FileConfiguration getFileConfig(String configName) {
            Configuration config = getConfig(configName);
            if (config != null) {
                return config.getConfig();
            } else {
                return null;
            }
        }
    }
    
    Any feedback/errors with the code are appreciated!
     
    Xeiotos and Ultimate_n00b like this.
  2. Offline

    Virgoth098

    Nice work, but how would I go about saving things into the config file? usually I would do getConfig().set("soandso", 5); how would i do it with this? foodyling

    EDIT: Nevermind, configManager.getFileConfig("data").set();
     
  3. Offline

    foodyling

    For future refence, configManager.getConfig() returns the "Configuration" object which allows you to do reloadConfig(), if you just want the FileConfiguration object, do getFileConfig, and the return acts like a regular configuration object.
     
    drtshock likes this.
  4. Offline

    Xeiotos

    Very nice work! A blessing for beginning plugin developers like me :D

    I have one question, and I hope this will not sound like total gibberish, since I started writing plugins and learning java just today:
    It seems I can only run loadConfigFiles(...) once per configManager object? I have to create a new object each time I want to use the method again, or it throws NPE's, like the object somehow removes itself after running getFileConfig?
    I don't think that's what you intended, so I must be doing something wrong :'(
     
  5. Offline

    foodyling

    Xeiotos It should be able to be ran multiple times, can you give me a specific line of the error?
     
  6. Offline

    Xeiotos

    Nevermind, I made the mistake of using it before making a reference to the object once. It was a little more complicated than this, so I didn't notice, but basically, I was doing this:

    Code:java
    1. //do something with configManager.
    2. configManager = new ConfigManager(this);
    3. //do something with configManager.


    EDIT: And I also tried to use getFileConfig(String) on a field which refered to the FileConfiguration I loaded, instead of on the configManager object. Sigh...
     
  7. Offline

    foodyling

  8. Offline

    Xeiotos

    Could you please provide an example of reloadConfig? I seem to be having difficulties reloading a config from disk :p
     
  9. Offline

    foodyling

    Code:
    configManager.reloadConfig(configName);
    // or
    configManager.reloadAllConfigs();
    Edit: Make sure you don't store it as a variable then reload, and still use the variable
    eg. dont do this:
    Code:
    FileConfiguration config = configManager.getFileConfig("config1");
    configManager.reloadConfig("config1");
    config.set("path", "value");
    You need to set the variable config as the new config by redoing configManager.getFileConfig("config1");
     
  10. Offline

    Xeiotos

    Ahaa, I thought reloadConfig took care of re-setting the variable. So now I have this working re-config code:

    Code:java
    1. public void reConfig(String name) {
    2. plugin.configManager.saveConfig(name, true);
    3. plugin.configManager.getConfig(name).reloadConfig();
    4. plugin.configManager.getFileConfig(name);
    5. }


    ^_^

    By the way, I'm loading each player's config when they enter/are already entered and the plugin loads. However, I can imagine that this would produce a memory leak because of the configs staying in configmanager's variables. Is this true, and if yes: How do I unload a config?
     
  11. Offline

    foodyling

    Xeiotos If you do configManager.getConfig(configName) it returns the "Configuration" object, which you can use getConfig() and it will return the reloaded config

    I updated the code in my first post, you can use configManager.unloadConfig(configName), it removes it from the TreeMap
     
    Xeiotos likes this.
Thread Status:
Not open for further replies.

Share This Page