Apache Commons configuration of the three properties file

Source: Internet
Author: User

The properties file is a popular application configuration file. Of course, Commons configuration supports this format and significantly enhances the underlying java.util.Properties class. This article describes the characteristics of the Propertiesconfiguration class. Note that propertiesconfiguration is a very typical example of implementing a configuration interface, and this document describes many of the features (for example, list processing or interpolation) that are supported by other configuration classes. This is because most configuration implementations that come with Commons configurations derive from the common base class abstractconfiguration that implement these attributes.

1 Using Propertiesconfiguration

Let's start with the content of a simple configuration file named Usergui.properties:

# define the properties of the GUI
Colors.background = #FFFFFF
Colors.foreground = #000080

Window.width = 500
Window.height = 300

To load the modified file:

Configuration config = new Propertiesconfiguration ("Usergui.properties");

If you do not specify an absolute path, the file will automatically search for the following location:

    • Current directory

    • User Directory

    • Class path

Instead of using a constructor that requires a file name, you can call one of the load () methods. There are several overloaded variants that allow you to load configurations from various sources.

After the profile is loaded, you can access its contents through the Configuration interface method:

String BackColor = config.getstring ("Colors.background");
Dimension size = new Dimension (Config.getint ("Window.width"), Config.getint ("Window.height"));

2 contains

If a property is named "Include," and the value of the property is a file name on the disk, it is included in the configuration. Here is an example:

# usergui.properties

Include = Colors.properties
Include = Sizes.properties

# colors.properties

Colors.background = #FFFFFF

3 List and array

The Commons configuration has the ability to return a list of values. For example, a configuration file can contain a comma-separated list of values:

# Chart Colors
Colors.pie = #FF0000, #00FF00, #0000FF

You do not need to manually separate the values, you can retrieve an array or java.util.List directly:

string[] colors = Config.getstringarray ("Colors.pie");
list<object> colorlist = config.getlist ("Colors.pie");

Or, you can specify a list of values in your configuration file with the same key in multiple rows:

# Chart Colors
Colors.pie = #FF0000;
Colors.pie = #00FF00;
Colors.pie = #0000FF;

All the About list handling features described in abstractconfiguration also apply to configuration files, including changing the list delimiter or disabling list processing.

4 Save

To save your configuration, simply call the Save () method:

propertiesconfiguration config = new Propertiesconfiguration ("Usergui.properties");
Config.setproperty ("Colors.background", "#000000);
Config.save ();

You can also save the configuration copy to other files:

propertiesconfiguration config = new Propertiesconfiguration ("Usergui.properties");
Config.setproperty ("Colors.background", "#000000);
Config.save ("usergui.backup.properties);//Save to path relative to Usergui.properties

5 special characters and escapes

If you need to include special characters like line breaks, tabs, or Unicode characters in a property, you can specify it with the same escape character as the Java string. The list delimiter (which is comma by default) can also be escaped:

Key = this \ n string \ contains \, escaped \ characters \u0020

Escaping rules can become complex when working with a list of elements that contain backslash characters (for example, a file path on a Windows system). The first thing to remember is that, in order to get a backslash, you have to write two:

Config.dir = c:\\temp\\

This problem is not caused by the Commons configuration, but rather the standard format of the associated profile. Refer to the Javadocs of the Java.util.Properties load () method. Now if you want to use a file path to define a list, you might write:

# How to define the error of the file directory list
Config.dirs = c:\\temp\\,d:\\data\\

As noted in the note, this will not work. The backslash after the first directory is interpreted as the escape character of the list delimiter. So instead of a list with two elements, just a single attribute value is defined-obviously not expected. In order to get the correct list, the backslash must be escaped. By copying it implementation (yes, in the config file, it means, now we need 4 backslashes):

# The correct way to define a directory list
Config.dirs = c:\\temp\\\\,d:\\data\\

Therefore, 4 backslashes in the attribute value are interpreted as a backslash and eventually computed as a single backslash. Other problems arise when a profile references a network share name. Typically these names start with two backslashes, and are defined in such a way that these properties are as follows:

# The wrong way to define a list of network shares
Config.dirs = \\\\share1,\\\\share2

Unfortunately, this will not work because the share contains 4 backslash sequences. So when reading the value of the Config.dirs property a list has two elements that begin with a backslash. To solve this problem, the escape character is duplicated-we now need 8 backslashes:

# The right way to define a network share list
Config.dirs = \\\\\\\\share1,\\\\\\\\share2

It is obvious that the escape sequence becomes very complex and unreadable. In this case, it is recommended to use the alternate way to define list: Use the same key multiple times. In this case, there is no additional backslash escaping (except that it is usually necessary to copy the configuration file) because no list delimiter is parsed.

Using this syntax, the network share list looks like this:

# Direct way to define a network share list
Config.dirs = \\\\share1
Config.dirs = \\\\share2

6 Layout objects

Each Propertiesconfiguration object is associated with a layout object, an instance of the Propertiesconfigurationlayout class. The layout object is responsible for saving most of the structure of the loaded configuration file. This means that a comment or a blank line is similar to the source file when the configuration file is saved (the algorithm is not 100% perfect, but should suffice for most use cases).

Typically, development does not require processing of these layout objects. However, there are some methods that may be interested in whether the enhanced output control in the profile is required. These methods are described in the following list:

    • Setcomment (): Use this method to specify that the comment for the property is set. When you store a configuration note, the Output property is preceded by a newline character. Comments can span multiple lines in a field, in which case the newline character "\ n" must be a row delimiter.

    • Setheadercomment (): A global comment using the setheadercomment () configuration file is set. The comment is written at the beginning of the file, followed by a blank line.

    • Setblanklinesbefore (): This method allows you to define the number of empty lines before the specified property is written. For example, it can be used to split a property file into multiple logical blocks.

    • Setsingleline (): If the attribute has more than one value, use Setsingleline () it can specify that all these values should be written as a single row of the default list split. It may also write multiple definitions of the attribute (for example, multiline form of property=value1,property=value2, etc.). Supported by Propertiesconfiguration, but may not work when working with properties files using other tools.

    • Setforcesingleline (): Similar to Setsingleline (), but sets the global single-line tag. If set to true, all property values are always written in a single line.

    • Setglobalseparator (): It is possible to define a property delimiter. This can be done using setglobalseparator (). This is an arbitrary string that specifies what can be used as a delimiter. (Note: In order to produce a valid configuration file, only the character = and: should be used as a delimiter, before and after you can use or do not use spaces), but the method is not enforced.

    • Setseparator (): This method is similar to Setglobalseparator (), but allows you to set the property delimiter for a specific property.

    • Setlineseparator (): Use this method to specify the line delimiter. The default is to use a specific platform line delimiter (for example, UNIX is \ n).

The default settings for Propertiesconfigurationlayout choose to retain most of the layout of the original configuration file. You can use the above method to perform specific layout restrictions.

7 Custom Configuration Reader and renderer

In some cases, it is necessary to have more control over the process of reading and writing properties files. For example, an application may have to process some legacy configuration files in a specific format, Propertiesconfiguration does not support out-of-the-box, when it must not be modified. In this case, you might inject a custom reader and an output to the configuration file.

Each default profile is read and written out through (defined in propertiesconfiguration) nested classes Propertiesreader and Propertieswriter. These classes are regular readers and the output class (both derived from the base class of the Java.io package) provides some additional ways to handle the configuration file more conveniently. Custom implementations of the profile reader and the output must extend these base classes.

In order to install a custom property reader or output, Propertiesconfiguration provides the Iofactory interface (which is also a nested class). An object implements the interface that is stored in each propertiesconfiguration instance. Whenever a profile is read or written out (for example, when the load () or save () method is called) Iofactory object Access creates a property reader or writer.

The Iofactory interface is fairly simple; it defines a method to create a property reader and a property renderer. The default implementation calls Defaultiofactory when Iofactory is not specified with Propertiesconfiguration. For a more specific discussion, provide an example of injecting a custom property reader. The key that we load a configuration file must contain spaces. Default Propertiesconfiguration not supported.

Background Color = #800080
Foreground Color = #000080

The first step is to create a custom property reader implementation that can handle this property. Class derives from Propertiesconfiguration.propertiesreader and overrides the Parseproperty () method:

public class Whitespacepropertiesreader extends Propertiesconfiguration.propertiesreader
{
Public Whitespacepropertiesreader (Reader in, Char delimiter)
{
Super (in, delimiter);
}

/**
* Special algorithm for parsing attribute keys with spaces. This method is called every time a row is read from the configuration file without comments.
*/
protected void Parseproperty (String line)
{
Separate lines only in 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 ();

The keys and values of the properties are now stored
Initpropertyname (key);
Initpropertyvalue (value);
}
}

Note Call the Initpropertyname () and Initpropertyvalue () methods. This causes the parsing operation to be stored. The next step is to provide a specific implementation of the Iofactory interface to return the new property reader class. We only want to replace the property reader (and use the standard output) to derive the defaultiofactory implementation, so you must only overwrite the Createpropertiesreader () method.

public class Whitespaceiofactory extends Propertiesconfiguration.defaultiofactory
{
/**
* Return to our developed property reader
*/
Public Propertiesreader Createpropertiesreader (Reader in, Char delimiter)
{
return new Whitespacepropertiesreader (in, delimiter);
}
}

Finally we have to create a new instance of the Iofactory implementation and pass in the Propertiesconfiguration object. This must be done before the load () method call. So we can't use constructors to load data. The code for setting up the configuration object should look like this:

propertiesconfiguration config = new propertiesconfiguration ();
Config.setiofactory (New Whitespaceiofactory ());
Config.setfile (...); Set the loaded file
Config.load ();













Apache Commons configuration of the three properties file

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.