Using a Configuration Factory
This section explains how a
The configuration definition file
When a single configuration file (e.g. a properties file) is the only
source of configuration data it is very simple to
load it using the specific configuration class that deals with
the corresponding format (e.g.
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="usergui.properties"/> </configuration>
Definition files for
For this example we store the definition file for
Setting up a ConfigurationFactory
Now we have to create a ConfigurationFactory factory = new ConfigurationFactory(); URL configURL = new File("config.xml").toURL(); factory.setConfigurationFileName(configURL.toString()); Configuration config = factory.getConfiguration(); As this code fragment shows the file name passed to the factory can be a full URL. This is also the recommended way of specifying the file because it provides the greatest flexibility and a consistent way of handling relative file names found in the definition file. Here we assumed the configuration definition file to be located in the current directory. It is also possible (and probably a better approach) to load the file from the class path. This could be done as follows: ConfigurationFactory factory = new ConfigurationFactory(); URL configURL = getClass().getResource("/config.xml"); factory.setConfigurationURL(configURL); Configuration config = factory.getConfiguration(); Accessing properties
Whatever way we used to load the configuration factory, we
should now have a String backColor = config.getString("color.background"); Multiple configuration sources
Using Overriding propertiesMany applications use the popular XML format for storing configuration information. So it is no wonder that Configuration also supports this type of configuration sources. In general each XML document can be used to define configuration settings. We start here with a rather simple one: <?xml version="1.0" encoding="ISO-8859-1" ?> <gui-definition> <colors> <background>#808080</background> <text>#000000</text> <header>#008000</header> <link normal="#000080" visited="#800080"/> </colors> <rowsPerPage>15</rowsPerPage> </gui-definition>
To make this XML document part of our global configuration we
have to modify our configuration definition file to also include
the new file. For XML documents the element <?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="usergui.properties"/> <xml fileName="gui.xml"/> </configuration>
The code for setting up the
There is one problem with this example configuration setup:
The
The answer is that the configuration sources are searched in the
order they are defined in the configuration definition file.
Here the properties file is included first, then comes the XML
file. Because the
It might not be obvious why it makes sense to define the value
of one and the same property in multiple configuration sources.
But consider the following scenario: An application comes with
a set of default properties and allows the user to override some
or all of them. This can now easy be realized by saving the
user's settings in a file and the default settings in another.
Then in the configuration definition file the file with the
user settings is included first and after that the file with the
default values. The application code that queries these
settings need not be aware whether a property was overriden by
the user. The Optional configuration sourcesThe example above with two configuration sources - one for user settings and one with default values - raises an interesting question: What will happen if the user has not defined specific properties yet? Or what if a new user starts our application for the first time and thus no user specific properties exist?
The default behavior of
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="usersettings.properties" optional="true"/> <properties fileName="default.properties"/> </configuration>
In this configuration definition file the first properties file
with user specific settings is marked as optional. This means that
if it cannot be loaded, Union configuration
In an earlier section about the configuration definition file for
Let's continue the example with the application that somehow process database tables and that reads the definitions of the affected tables from its configuration. This example and the corresponding XML configuration files were introduced in the section about XMLConfiguration. Now consider that this application grows larger and must be maintained by a team of developers. Each developer works on a separated set of tables. In such a scenario it would be problematic if the definitions for all tables would be kept in a single file. It can be expected that this file needs to be changed very often and thus can be a bottleneck for team development when it is nearly steadily checked out. It would be much better if each developer had an associated file with table definitions and all these information could be linked together at the end.
<?xml version="1.0" encoding="ISO-8859-1" ?> <config> <table tableType="application"> <name>tasks</name> <fields> <field> <name>taskid</name> <type>long</type> </field> <field> <name>name</name> <type>java.lang.String</type> </field> <field> <name>description</name> <type>java.lang.String</type> </field> <field> <name>responsibleID</name> <type>long</type> </field> <field> <name>creatorID</name> <type>long</type> </field> <field> <name>startDate</name> <type>java.util.Date</type> </field> <field> <name>endDate</name> <type>java.util.Date</type> </field> </fields> </table> </config> This file defines the structure of an additional table, which should be added to the so far existing table definitions. To achieve this the configuration definition file has to be changed: A new section is added that contains the include elements of all configuration sources which are to be combined. <?xml version="1.0" encoding="ISO-8859-1" ?> <!-- Configuration definition file that demonstrates the override and additional sections --> <configuration> <override> <properties fileName="usergui.properties"/> <xml fileName="gui.xml"/> </override> <additional> <xml fileName="tables.xml"/> <xml fileName="tasktables.xml" at="tables"/> </additional> </configuration>
Compared to the older versions of this file a couple of changes has been
done. One major difference is that the elements for including configuration
sources are no longer direct children of the root element, but are now
contained in either an
The
It is the
After these modifications have been performed the configuration obtained
from the
Note that it is also possible to override properties defined in an
The configuration definition file
We have seen how to write configuration definition files for
including properties and XML files. This section deals with other
options that can be specified in such a definition file and that
are evaluated by From time to time the question is raised whether there is a document type definition that exactly defines the structure of a configuration definition file. Frankly, the answer is no. This is because for a future version of Commons Configuration it is planed to make the configuration definition files extensible, i.e. allow developers to register their own tags and corresponding implementations of the Configuration interface. In the current version the set of supported XML elements is fixed. Below is a list of all supported tags and a description of each:
All of these elements can occur in a configuration definition file in arbitrary number and order. The following listing shows an example file using many of these tags. <?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <system/> <jndi prefix="java:comp/env"/> <properties fileName="test.properties"/> <xml fileName="test.xml"/> <properties fileName="test.properties.xml"/> </configuration> Setting further options
Many specialized configuration classes support initialization
properties that influence the behavior of their instances. For
example for file based configurations the encoding of the files
to load can be specified using the
Fortunately this is easy possible. For each XML element in a
configuration definition file additional attributes can be
specified that correspond to (bean) setter methods defined in the
associated configuration class. To derive the name of an attribute
from a setter method to be called, just drop the prefix "set" and
make the first letter lower case. So for instance the attribute
that invokes the <?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <xml fileName="test.xml" encoding="UTF-8" validating="true"/> </configuration>
Using this mechanism many properties of configuration classes can
be set when they are used together with |