Using XML based ConfigurationsThis section explains how to use Hierarchical and Structured XML datasets. Hierarchical propertiesThe XML document we used in the section about composite configuration was quite simple. Because of its tree-like nature XML documents can represent data that is structured in many ways. This section explains how to deal with such structured documents. Structured XMLConsider the following scenario: An application operates on database tables and wants to load a definition of the database schema from its configuration. A XML document provides this information. It could look as follows: <?xml version="1.0" encoding="ISO-8859-1" ?> <database> <tables> <table tableType="system"> <name>users</name> <fields> <field> <name>uid</name> <type>long</type> </field> <field> <name>uname</name> <type>java.lang.String</type> </field> <field> <name>firstName</name> <type>java.lang.String</type> </field> <field> <name>lastName</name> <type>java.lang.String</type> </field> <field> <name>email</name> <type>java.lang.String</type> </field> </fields> </table> <table tableType="application"> <name>documents</name> <fields> <field> <name>docid</name> <type>long</type> </field> <field> <name>name</name> <type>java.lang.String</type> </field> <field> <name>creationDate</name> <type>java.util.Date</type> </field> <field> <name>authorID</name> <type>long</type> </field> <field> <name>version</name> <type>int</type> </field> </fields> </table> </tables> </database> This XML is quite self explanatory; there is an arbitrary number of table elements, each of it has a name and a list of fields. A field in turn consists of a name and a data type. To access the data stored in this document it must be included in the configuration definition file: <?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="usergui.properties"/> <xml fileName="gui.xml"/> <xml fileName="tables.xml"/> </configuration>
The additional
Because the document contains a list of tables some properties
are defined more than once. E.g. the configuration key
Multiple definitions of a property do not cause problems and are
supported by all classes of Configuration. If such a property
is queried using Object prop = config.getProperty("tables.table.name"); if(prop instanceof Collection) { System.out.println("Number of tables: " + ((Collection) prop).size()); }
An alternative to this code would be the Accessing structured properties
Okay, we can obtain a list with the name of all defined
tables. In the same way we can retrieve a list with the names
of all table fields: just pass the key
The answer is, with our actual approach we have no chance to obtain this knowledge! If XML documents are loaded this way, their exact structure is lost. Though all field names are found and stored the information which field belongs to which table is not saved. Fortunately Configuration provides a way of dealing with structured XML documents. To enable this feature the configuration definition file has to be slightly altered. It becomes: <?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="usergui.properties"/> <xml fileName="gui.xml"/> <hierarchicalXml fileName="tables.xml"/> </configuration>
Note that one When working with such hierarchical properties configuration keys used to query properties support an extended syntax. All components of a key can be appended by a numerical value in parentheses that determines the index of the affected property. This is explained best by some examples:
We will now provide some configuration keys and show the results
of a
These examples should make the usage of indices quite clear.
Because each configuration key can contain an arbitrary number
of indices it is possible to navigate through complex structures of
XML documents; each XML element can be uniquely identified.
So at the end of this section we can draw the following facit:
For simple XML documents that define only some simple properties
and do not have a complex structure the default XML configuration
class is suitable. If documents are more complex and their structure
is important, the hierarchy aware class should be used, which is
enabled by an additional 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. 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> <hierarchicalXml fileName="tables.xml"/> <hierarchicalXml 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
|