Skip to content

Configuration Manager

A248 edited this page Mar 10, 2021 · 9 revisions

ConfigurationFactory is the main interface which supports reading and writing from InputStream and OutputStream, as well as NIO's ReadableByteChannel and WritableByteChannel.

How these streams or channels are created is intentionally left to the user. However, for common use cases, ConfigurationHelper exists for single-file configurations and reduces much of the boilerplate which would otherwise be required.

Example Configuration Manager

This example will use the YAML configuration format. The class ConfigManager will support:

  1. Writing YAML comments
  2. Automatically updating old configurations with the latest keys
  3. Informing the user when something goes wrong, and falling back to the default configuration

This example uses System.err, but it may be desirable to use one's preferred logging framework.

public final class ConfigManager<C> {

	private final ConfigurationHelper<C> configHelper;
	private volatile C configData;

	private ConfigManager(ConfigurationHelper<C> configHelper) {
		this.configHelper = configHelper;
	}

	public static <C> ConfigManager<C> create(Path configFolder, String fileName, Class<C> configClass) {
		// SnakeYaml example
		SnakeYamlOptions yamlOptions = new SnakeYamlOptions.Builder()
				.commentMode(CommentMode.alternativeWriter()) // Enables writing YAML comments
				.build();
		ConfigurationFactory<C> configFactory = SnakeYamlConfigurationFactory.create(
				configClass,
				ConfigurationOptions.defaults(), // change this if desired
				yamlOptions);
		return new ConfigManager<>(new ConfigurationHelper<>(configFolder, fileName, configFactory));
	}

	public void reloadConfig() {
		try {
			configData = configHelper.reloadConfigData();
		} catch (IOException ex) {
			throw new UncheckedIOException(ex);

		} catch (ConfigFormatSyntaxException ex) {
			configData = configHelper.getFactory().loadDefaults();
			System.err.println("The yaml syntax in your configuration is invalid. "
					+ "Check your YAML syntax with a tool such as https://yaml-online-parser.appspot.com/");
			ex.printStackTrace();

		} catch (InvalidConfigException ex) {
			configData = configHelper.getFactory().loadDefaults();
			System.err.println("One of the values in your configuration is not valid. "
					+ "Check to make sure you have specified the right data types.");
			ex.printStackTrace();
		}
	}

	public C getConfigData() {
		C configData = this.configData;
		if (configData == null) {
			throw new IllegalStateException("Configuration has not been loaded yet");
		}
		return configData;
	}

}

How to use:

Path configFolder;
String fileName;
ConfigManager<Config> configManager = ConfigManager.create(configFolder, fileName, Config.class);
configManager.reloadConfig();
Config config = configManager.getConfigData();

ConfigManager is responsible for error handling, while delegating the grunt work to ConfigurationHelper.

I can't find the import for ConfigurationHelper?

Make sure you are using the right version. ConfigurationHelper requires 1.2.0 or later.

UTF-8 Encoding - By Default

ConfigurationFactory implementations use a BufferedReader with UTF-8 encoding by default.

This can be changed by setting the relevant charset option on GsonOptions or SnakeYamlOptions, depending on which format you use.