{8.1.0-updated} Imports

Configurations can import values from other configurations using the following syntax:

# Import values from configuration 'ParentConfig' <ParentConfig> # Our normal section [Section1] ...

A configuration can contain zero or more imports anywhere in the file. However, for clarity, imports should normally be placed in the default section of the configuration file. The resolved configuration is retrieved from the configuration store used for the child configuration.

Configuration imports can be nested arbitrarily deep.

##### Example:

# MyConfig contents <ParentConfig1>

# ParentConfig1 contents <ParentConfig2>

# ParentConfig2 contents [Foo] bar = baz

// Java code Config config = ConfigBuilder.create("MyConfig").build(); String foo = config.getString("Foo/bar"); // == "baz"

Values can be overridden by child configurations.

##### Example:

# MyConfig contents <ParentConfig1> [Foo] bar = baz

# ParentConfig1 contents <ParentConfig2> [Foo] bar = qux

# ParentConfig2 contents [Foo] bar = quux

Config config = ConfigBuilder.create("MyConfig").build(); String foo = config.getString("Foo/bar"); // == "baz"

Changes made to imported configurations are automatically reflected in the child configuration and partake in the listener API as if the entries were part of the child configuration. Only non-overridden values trigger listener events. For example, if an imported configuration defines a value for "Foo/bar" and the child configuration does not, modifications to "Foo/bar" value in the parent configuration will trigger a listener event in the child config. However, if the child configuration does also specify a value for "Foo/bar", a change to the parent "Foo/bar" will NOT trigger a listener event because the value ends up not being changed from the perspective of the child configuration.

Values can be overwritten in child configurations, but the values will only be set in that configuration and not the imported configuration.

Dynamically adding an import will cause change events to be generated for imported values.

# MyConfig contents starting empty

# ParentConfig contents [Foo] bar = baz

// Create our configuration. Config config = ConfigBuilder.create("MyConfig").build(); // Create a listener that sets a flag if "Foo/bar" is set. final boolean[] triggered = new boolean[1]; ConfigEventListener listener = new ConfigEventListener() { public void onConfigChange(ConfigEvents events) { triggered[0] = events.isKeyModified("Foo", "bar")); } }; config.addListener(listener); // Dynamically add an import to ParentConfig in the default section. config.setImport("", "ParentConfig"); config.commit(); // The new import statement should have triggered a config changes for imported values. assertTrue(triggered[0]);

Dynamically removing an import has the same effect as removing keys and generates REMOVE_ENTRY events.

Note that when dynamically adding or removing imports, overridden keys in the child config will be filtered from the change events.