Properties files
Properties files are a popular means of configuring applications. Of course, Commons Configuration
supports this format and enhances significantly the basic Using PropertiesConfiguration
Let's start with a simple properties file named
# Properties definining the GUI colors.background = #FFFFFF colors.foreground = #000080 window.width = 500 window.height = 300 To load this file, you'll write something like: Parameters params = new Parameters(); FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) .configure(params.properties() .setFileName("usergui.properties")); try { Configuration config = builder.getConfiguration(); ... } catch(ConfigurationException cex) { // loading of the configuration file failed }
As is demonstrated by this example, a configuration object for a
properties file is obtained via a
After the properties file was loaded you can access its content through
the methods of the String backColor = config.getString("colors.background"); Dimension size = new Dimension(config.getInt("window.width"), config.getInt("window.height")); Includes
If a property is named "
The difference between " For example: # usergui.properties include = colors.properties include = sizes.properties # colors.properties colors.background = #FFFFFF Oprional Includes
If a property is named "
The difference between " For example: # usergui.properties includeOptional = colors.properties includeOptional = sizes.properties # colors.properties colors.background = #FFFFFF Lists and arraysAs was already pointed out in the section List handling of Basic features, Commons Configuration has the ability to return easily a list of values. For example, a properties file can contain a list of comma separated values: # chart colors colors.pie = #FF0000, #00FF00, #0000FF
Provided that an appropriate
String[] colors = config.getStringArray("colors.pie"); List<Object> colorList = config.getList("colors.pie");
Splitting of string values at list delimiter characters is disabled
by default. It can be enabled by specifying an instance of
Parameters params = new Parameters(); FileBasedConfigurationBuilder<Configuration> builder = new FileBasedConfigurationBuilder<Configuration>(PropertiesConfiguration.class) .configure(params.properties() .setFileName("usergui.properties") .setListDelimiterHandler(new DefaultListDelimiterHandler(',')); Configuration config = builder.getConfiguration();
Alternatively, you can specify a list of values in your properties file by using
the same key on several lines as shown in the following example. This is an
example of a feature not provided by # chart colors colors.pie = #FF0000; colors.pie = #00FF00; colors.pie = #0000FF;
All of the features related to list handling described for
Saving
To save your configuration, just call the Parameters params = new Parameters(); FileBasedConfigurationBuilder<FileBasedConfiguration> builder = new FileBasedConfigurationBuilder<FileBasedConfiguration>(PropertiesConfiguration.class) .configure(params.properties() .setFileName("usergui.properties") .setListDelimiterHandler(new DefaultListDelimiterHandler(','))); Configuration config = builder.getConfiguration(); config.setProperty("colors.background", "#000000"); builder.save(); More information about saving properties files (and file-based configurations in general) can be found in the section about File-based Configurations. Special Characters and EscapingIf you need a special character in a property like a line feed, a tabulation or an unicode character, you can specify it with the same escaped notation used for Java Strings. The list separator ("," by default), can also be escaped: key = This \n string \t contains \, escaped \\ characters \u0020 When dealing with lists of elements that contain backslash characters (e.g. file paths on Windows systems) escaping rules can become pretty complex. The first thing to keep in mind is that in order to get a single backslash, you have to write two: config.dir = C:\\Temp\\
This issue is not specific to Commons Configuration, but is related to
the standard format for properties files. Refer to the Javadocs of the
# Wrong way to define a list of directories config.dirs = C:\\Temp\\,D:\\data\\ As the comment indicates, this will not work. The trailing backslash of the first directory is interpreted as escape character for the list delimiter. So instead of a list with two elements only a single value of the property is defined - clearly not what was desired. To get a correct list the trailing backslash has to be escaped. This is achieved by duplicating it (yes, in a properties file that means that we now need 4 backslashes): # Correct way to define a list of directories config.dirs = C:\\Temp\\\\,D:\\data\\ So a sequence of 4 backslashes in the value of a property is interpreted as an escaped backslash and eventually results in a single backslash. This creates another problem when a properties file should refer to the names of network shares. Typically these names start with two backslashes, so the obvious way to define such a property is as follows: # Wrong way to define a list of network shares config.dirs = \\\\share1,\\\\share2 Unfortunately, this will not work because the shares contain the reserved sequence of 4 backslashes. So when reading the value of the config.dirs property a list with two elements is returned starting only with a single backslash. To fix the problem the sequence for escaping a backslash has to be duplicated - we are now at 8 backslashes: # Correct way to define a list of network shares config.dirs = \\\\\\\\share1,\\\\\\\\share2 As becomes obvious, escape sequences can become pretty complex and unreadable. In such situations it is recommended to use the alternative way of defining a list: just use the same key multiple times. In this case no additional escaping of backslashes (beyond the usual duplicating required by properties files) is needed because there is no list delimiter character involved. Using this syntax the list of network shares looks like the following: # Straightforward way to define a list of network shares config.dirs = \\\\share1 config.dirs = \\\\share2
Please also refer to the Javadocs of the
Layout Objects
Each Normally a developer does not have to deal with these layout objects. However, there are some methods that might be of interest if enhanced control over the output of properties files is needed. The following list describes these methods (note that corresponding get methods are of course also provided):
PropertiesConfigurationLayout are
chosen in a way that most of the original layout of a properties file
is retained. With the methods listed above specific layout restrictions
can be enforced.
Custom properties readers and writers
There are situations when more control over the process of reading and
writing properties files is needed. For instance, an application might
have to deal with some legacy properties file in a specific format,
which is not supported out of the box by
Per default properties files are read and written by the nested classes
For installing a custom properties reader or writer
The
To make this discussion more concrete we provide an example of how to
inject a custom properties reader. The use case is that we have to load
a properties file that contains keys with whitespace, which is not
supported by Background Color = #800080 Foreground Color = #000080
The first step is to create a custom properties reader implementation
that can deal with such properties. The class is derived from
public class WhitespacePropertiesReader extends PropertiesConfiguration.PropertiesReader { public WhitespacePropertiesReader(Reader in, char delimiter) { super(in, delimiter); } /** * Special algorithm for parsing properties keys with whitespace. This * method is called for each non-comment line read from the properties * file. */ @Override protected void parseProperty(String line) { // simply split the line at the first '=' character // (this should be more robust in production code) int pos = line.indexOf('='); String key = line.substring(0, pos).trim(); String value = line.substring(pos + 1).trim(); // now store the key and the value of the property initPropertyName(key); initPropertyValue(value); } }
Notice the calls to the methods public class WhitespaceIOFactory extends PropertiesConfiguration.DefaultIOFactory { /** * Return our special properties reader. */ @Override public PropertiesReader createPropertiesReader(Reader in, char delimiter) { return new WhitespacePropertiesReader(in, delimiter); } }
Finally an instance of our new Parameters params = new Parameters(); FileBasedConfigurationBuilder<Configuration> builder = new FileBasedConfigurationBuilder<Configuration>(PropertiesConfiguration.class) .configure(params.properties() .setFileName("myfile.properties") .setIOFactory(new WhitespaceIOFactory()); Configuration config = builder.getConfiguration(); Builder Configuration Related to Properties Files
When setting up a configuration builder to produce a
A parameters object for a properties configuration can be obtained using
the |