I created a Simple Config Manager

Hello all, while working on my plugins I noticed that creating and accessing default configuration files can be a bit of a bear at times. To that end I created this simple configManager class to handle creating and maintaining a config file. I thought it might be of use to some people here. You can grab it from my github here! Basically the way it works is you grab an instance of the config manager then set it up with a path to the config file, a config loader to handle loading and saving it, a logger to handle error messages, and finally a builder for the default config file. The default builder will only be executed when the config file does not yet exist, preserving any edits made by your users.

##Example

@Plugin(id = "ConfigExample", name = "ConfigExample", version = "1.0.0")
public class ConfigExample {

    @Inject
    private Logger logger;

    public Logger getLogger() {
        return logger;
    }


    @Inject
    @DefaultConfig(sharedRoot = true)
    private Path defaultConfig;

    @Inject
    @DefaultConfig(sharedRoot = true)
    private ConfigurationLoader<CommentedConfigurationNode> configLoader;

    private ConfigManager configManager;

    @Listener
    public void onServerStart(GameStartedServerEvent event) {

        //Grab Instance of Config Manager
        configManager = ConfigManager.getInstance();

        //Setup the config, passing in the default config format builder
        configManager.setup(defaultConfig, configLoader, getLogger(), new ConfigManager.DefaultConfigBuilder() {
            @Override
            public void build(CommentedConfigurationNode config) {
                config.getNode("sampleNode").setComment("This is a sample boolean node.").setValue(true);
                config.getNode("samples", "sampleNode2").setComment("This is a sample string node.").setValue("Hello World!");
            }
        });

        //Alternative method of setup using Lambda Expressions
        configManager.setup(defaultConfig, configLoader, getLogger(), config -> {
            config.getNode("sampleNode").setComment("This is a sample boolean node.").setValue(true);
            config.getNode("samples", "sampleNode2").setComment("This is a sample string node.").setValue("Hello World!");
        });

        //Get the config file!
        CommentedConfigurationNode config = configManager.getConfig();
    }
} 

##Output Config File
# This is a sample boolean node.
sampleNode=true
samples {
# This is a sample string node.
sampleNode2=“Hello World!”
}

Hopefully this can be of use to someone. Let me know what you all think! :grinning:

I personally find that the ObjectMapper that comes with Configurate is a really fluid way of creating a config and its defaults. It does require a bit of boilerplate to save/load the config (which could be done with a library API :wink:).

So a sample config class, including the save/load boiler plate is like so:

public class MyConfig {
    @Setting
    public boolean enabled = true;

    @Setting("flard-amount")
    public int flardAmount = Integer.MAX_VALUE;

    private ObjectMapper<MyConfig>.BoundInstance configMapper;
    private ConfigurationLoader<CommentedConfigurationNode> loader;

    public MyConfig(ConfigurationLoader<CommentedConfigurationNode> loader) {
        this.loader = loader;
        try {
            this.configMapper = ObjectMapper.forObject(this);
        } catch (ObjectMappingException e) {
            e.printStackTrace();
        }

        this.load();
    }

    public void save() {
        try {
            SimpleConfigurationNode out = SimpleConfigurationNode.root();
            this.configMapper.serialize(out);
            this.loader.save(out);
        } catch (ObjectMappingException | IOException e) {
            e.printStackTrace();
        }
    }

    public void load() {
        try {
            this.configMapper.populate(this.loader.load());
        } catch (ObjectMappingException | IOException e) {
            e.printStackTrace();
        }
    }
}

Note the code was mostly based off sponge’s own more complex configuration manager that also includes multiple level configs and getter/setters, which can be found here: https://github.com/SpongePowered/SpongeCommon/blob/master/src/main/java/org/spongepowered/common/config/SpongeConfig.java