Author: oheger
Date: Sun Jun  8 18:23:12 2014
New Revision: 1601235

URL: http://svn.apache.org/r1601235
Log:
Extracted a chapter about hierarchical configurations.

It makes sense to separate the information common to all hierarchical
configuration sources from the XML-specific descriptions.

Added:
    
commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_hierarchical.xml
Modified:
    commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml

Added: 
commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_hierarchical.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_hierarchical.xml?rev=1601235&view=auto
==============================================================================
--- 
commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_hierarchical.xml
 (added)
+++ 
commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_hierarchical.xml
 Sun Jun  8 18:23:12 2014
@@ -0,0 +1,1055 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Hierarchical Configurations</title>
+ </properties>
+
+<body>
+    <section name="Hierarchical Configurations">
+    <p>
+      Many sources of configuration data have a hierarchical or tree-like
+      nature. They can represent data that is structured in many ways.
+      Such configuration sources are represented by classes implementing the
+      <code><a 
href="../apidocs/org/apache/commons/configuration/HierarchicalConfiguration.html">
+      HierarchicalConfiguration</a></code> interface. With
+      <code><a 
href="../apidocs/org/apache/commons/configuration/BaseHierarchicalConfiguration.html">
+      BaseHierarchicalConfiguration</a></code> there is a fully functional
+      implementation of the interface from which most of the hierarchical
+      configuration classes shipped with <em>Commons Configuration</em> are
+      derived.
+    </p>
+    <p>
+      Prominent examples of hierarchical configuration sources are XML
+      documents. They can be read and written using the
+      <code><a 
href="../apidocs/org/apache/commons/configuration/XMLConfiguration.html">
+      XMLConfiguration</a></code> class. This section explains how
+      to deal with such structured data and demonstrates the enhanced query
+      facilities supported by <code>HierarchicalConfiguration</code>. We
+      use XML documents as examples for structured configuration sources,
+      but the information provided here (especially the rules for accessing
+      properties) applies to other hierarchical configurations as well.
+      Examples for other hierarchical configuration classes are
+      <ul>
+        <li><code><a 
href="../apidocs/org/apache/commons/configuration/CombinedConfiguration.html">
+        CombinedConfiguration</a></code></li>
+        <li><code><a 
href="../apidocs/org/apache/commons/configuration/INIConfiguration.html">
+        INIConfiguration</a></code></li>
+        <li><code><a 
href="../apidocs/org/apache/commons/configuration/plist/PropertyListConfiguration.html">
+        PropertyListConfiguration</a></code></li>
+      </ul>
+    </p>
+        
+    <subsection name="Accessing properties in hierarchical configurations">
+    <p>
+      We will start with a simple XML document to show some basics
+      about accessing properties. The following file named
+      <code>gui.xml</code> is used as example document:
+    </p>
+<source><![CDATA[
+<?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"/>
+    <default>${colors.header}</default>
+  </colors>
+  <rowsPerPage>15</rowsPerPage>
+  <buttons>
+    <name>OK</name>
+    <name>Cancel</name>
+    <name>Help</name>
+  </buttons>
+  <numberFormat pattern="###,###.##"/>
+</gui-definition>
+]]></source>
+    <p>
+      (As becomes obvious, this tutorial does not bother with good
+      design of XML documents, the example file should rather 
+      demonstrate the different ways of accessing properties.)
+      To access the data stored in this document it must be loaded
+      by <code><a 
href="../apidocs/org/apache/commons/configuration/XMLConfiguration.html">
+      XMLConfiguration</a></code>. Like for other 
+      <a href="howto_filebased.html">file-based</a>  configuration classes
+      a <code><a 
href="../apidocs/org/apache/commons/configuration/builder/FileBasedConfigurationBuilder.html">
+      FileBasedConfigurationBuilder</a></code> is used for reading the source
+      file as shown in the following code fragement:
+    </p>
+<source><![CDATA[
+Parameters params = new Parameters();
+FileBasedConfigurationBuilder<XMLConfiguration> builder =
+    new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
+    .configure(params.xml()
+        .setFileName("gui.xml"));
+try
+{
+    XMLConfiguration config = builder.getConfiguration();
+    ...
+}
+catch(ConfigurationException cex)
+{
+    // loading of the configuration file failed
+}
+]]></source>
+    <p>
+      If no exception was thrown, the properties defined in the
+      XML document are now available in the configuration object.
+      Other hierarchical configuration classes that operate on files can be
+      loaded in an analogous way. The following fragment shows how the
+      properties in the configuration object can be accessed:
+    </p>
+<source><![CDATA[
+String backColor = config.getString("colors.background");
+String textColor = config.getString("colors.text");
+String linkNormal = config.getString("colors.link[@normal]");
+String defColor = config.getString("colors.default");
+int rowsPerPage = config.getInt("rowsPerPage");
+List<Object> buttons = config.getList("buttons.name");
+]]></source>
+    <p>
+      This listing demonstrates some important points about constructing the
+      keys for accessing properties in hierarchical configuration sources and 
about
+      features of <code>HierarchicalConfiguration</code> in general:
+      <ul>
+        <li>
+          Nested elements are accessed using a dot notation. In
+          the example document there is an element <code>&lt;text&gt;</code>
+          in the body of the <code>&lt;color&gt;</code> element. The
+          corresponding key is <code>color.text</code>.
+        </li>
+        <li>
+          The root element is ignored when constructing keys. In
+          the example you do not write <code>gui-definition.color.text</code>,
+          but only <code>color.text</code>.
+        </li>
+        <li>
+          Attributes of XML elements are accessed in a XPath like notation.
+        </li>
+        <li>
+          <a 
href="howto_basicfeatures.html#Variable_Interpolation">Interpolation</a>
+          can be used in the same way as for all other standard configuration
+          implementations. Here the <code>&lt;default&gt;</code> element in the
+          <code>colors</code> section refers to another color.
+        </li>
+        <li>
+          Lists of properties can be defined by just repeating elements.
+          In this example the <code>buttons.name</code> property
+          has the three values <em>OK</em>, <em>Cancel</em>, and
+          <em>Help</em>, so it is queried using the <code>getList()</code>
+          method. This works with attributes, too. In addition, a special
+          <code><a 
href="../apidocs/org/apache/commons/configuration/convert/ListDelimiterHandler.html">
+          ListDelimiterHandler</a></code> implementation can be set which
+          supports splitting texts at a specific list delimiter character. This
+          works in the same way as described in the section about
+          <a href="howto_properties.html#Lists_and_arrays">properties
+          configuration</a>. If this mode was used, the three button names 
could
+          be defined in a single XML element. However, then the 
<em>pattern</em>
+          attribute of the <code>&lt;numberFormat&gt;</code> element needs to
+          escape the list delimiter which occurs in its content using a
+          backslash character. With these changes the affected part of the XML
+          document would look as follows:
+<source><![CDATA[
+  <buttons>
+    <name>OK, Cancel, Help</name>
+  </buttons>
+  <numberFormat pattern="###\,###.##"/>
+]]></source>
+          Because repeating elements is a natural pattern for XML documents
+          using list splitting is rather untypical for this format.
+        </li>
+      </ul>
+    </p>
+    <p>
+      The next section will show how data in a more complex XML
+      document can be processed.
+    </p>
+    </subsection>
+
+    <subsection name="Complex hierarchical structures">
+    <p>
+      Consider 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:
+    </p>
+    <source><![CDATA[
+<?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>
+]]></source>
+    <p>
+      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. This
+      XML document (let's call it <code>tables.xml</code>) can be
+      loaded in exactly the same way as the simple document in the
+      section before.
+    </p>
+    <p>
+      When we now want to access some of the properties we face a
+      problem: the syntax for  constructing configuration keys we
+      learned so far is not powerful enough to access all of the data
+      stored in the tables document.
+    </p>
+    <p>
+      Because the document contains a list of tables some properties
+      are defined more than once. E.g. the configuration key
+      <code>tables.table.name</code> refers to a <code>name</code>
+      element inside a <code>table</code> element inside a
+      <code>tables</code> element. This constellation happens to
+      occur twice in the tables document.
+    </p>
+    <p>
+      Multiple definitions of a property do not cause problems and are
+      supported by all classes of Configuration. If such a property
+      is queried using <code>getProperty()</code>, the method
+      recognizes that there are multiple values for that property and
+      returns a collection with all these values. So we could write
+    </p>
+    <source><![CDATA[
+Object prop = config.getProperty("tables.table.name");
+if(prop instanceof Collection)
+{
+       System.out.println("Number of tables: " + ((Collection<?>) 
prop).size());
+}
+]]></source>
+    <p>
+      An alternative to this code would be the <code>getList()</code>
+      method of <code>Configuration</code>. If a property is known to
+      have multiple values (as is the table name property in this example),
+      <code>getList()</code> allows retrieving all values at once.
+      <b>Note:</b> it is legal to call <code>getString()</code>
+      or one of the other getter methods on a property with multiple
+      values; it returns the first element of the list.
+    </p>
+    </subsection>
+
+    <subsection name="Accessing structured properties">
+    <p>
+      Okay, we can obtain a list with the names of all defined
+      tables. In the same way we can retrieve a list with the names
+      of all table fields: just pass the key
+      <code>tables.table.fields.field.name</code> to the
+      <code>getList()</code> method. In our example this list
+      would contain 10 elements, the names of all fields of all tables.
+      This is fine, but how do we know, which field belongs to
+      which table?
+    </p>
+    <p>
+      When working with such hierarchical structures the configuration keys
+      used to query properties can have 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. So if we have two
+      <code>table</code> elements we can exactly specify, which one we
+      want to address by appending the corresponding index. This is
+      explained best by some examples:
+    </p>
+    <p>
+      We will now provide some configuration keys and show the results
+      of a <code>getProperty()</code> call with these keys as arguments.
+      <dl>
+      <dt><code>tables.table(0).name</code></dt>
+      <dd>
+        Returns the name of the first table (all indices are 0 based),
+        in this example the string <em>users</em>.
+      </dd>
+      <dt><code>tables.table(0)[@tableType]</code></dt>
+      <dd>
+        Returns the value of the tableType attribute of the first
+        table (<em>system</em>).
+      </dd>
+      <dt><code>tables.table(1).name</code></dt>
+      <dd>
+        Analogous to the first example returns the name of the
+        second table (<em>documents</em>).
+      </dd>
+      <dt><code>tables.table(2).name</code></dt>
+      <dd>
+        Here the name of a third table is queried, but because there
+        are only two tables result is <b>null</b>. The fact that a
+        <b>null</b> value is returned for invalid indices can be used
+        to find out how many values are defined for a certain property:
+        just increment the index in a loop as long as valid objects
+        are returned.
+      </dd>
+      <dt><code>tables.table(1).fields.field.name</code></dt>
+      <dd>
+        Returns a collection with the names of all fields that
+        belong to the second table. With such kind of keys it is
+        now possible to find out, which fields belong to which table.
+      </dd>
+      <dt><code>tables.table(1).fields.field(2).name</code></dt>
+      <dd>
+        The additional index after field selects a certain field.
+        This expression represents the name of the third field in
+        the second table (<em>creationDate</em>).
+      </dd>
+      <dt><code>tables.table.fields.field(0).type</code></dt>
+      <dd>
+        This key may be a bit unusual but nevertheless completely
+        valid. It selects the data types of the first fields in all
+        tables. So here a collection would be returned with the
+        values [<em>long, long</em>].
+      </dd>
+      </dl>
+    </p>
+    <p>
+      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
+      hierarchical configurations; each property can be uniquely identified.
+    </p>
+    </subsection>
+
+    <subsection name="Sub Configurations">
+    <p>
+      Sometimes dealing with long property keys may become inconvenient,
+      especially if always the same properties are accessed. For this
+      case <code>HierarchicalConfiguration</code> provides a short cut
+      with the <code>configurationAt()</code> method. This method can
+      be passed a key that selects exactly one node of the hierarchy
+      of nodes contained in a hierarchical configuration. Then a new
+      hierarchical configuration will be returned whose root node is
+      the selected node. So all property keys passed into that
+      configuration should be relative to the new root node. For
+      instance, if we are only interested in information about the
+      first database table, we could do something like that:
+    </p>
+<source><![CDATA[
+HierarchicalConfiguration<ImmutableNode> sub = 
config.configurationAt("tables.table(0)");
+String tableName = sub.getString("name");  // only need to provide relative 
path
+List<Object> fieldNames = sub.getList("fields.field.name");
+]]></source>
+    <p>
+      For dealing with complex list-like structures there is another
+      short cut. Often it will be necessary to iterate over all items
+      in the list and access their (sub) properties. A good example are
+      the fields of the tables in our demo configuration. When you want
+      to process all fields of a table (e.g. for constructing a
+      <code>CREATE TABLE</code> statement), you will need all information
+      stored for them in the configuration. An option would be to use
+      the <code>getList()</code> method to fetch the required data one
+      by one:
+    </p>
+<source><![CDATA[
+List<Object> fieldNames = config.getList("tables.table(0).fields.field.name");
+List<Object> fieldTypes = config.getList("tables.table(0).fields.field.type");
+List<Object> ... // further calls for other data that might be stored in the 
config
+]]></source>
+    <p>
+      But this is not very readable and will fail if not all field
+      elements contain the same set of data (for instance the
+      <code>type</code> property may be optional, then the list for
+      the types can contain less elements than the other lists). A
+      solution to these problems is the <code>configurationsAt()</code>
+      method, a close relative to the <code>configurationAt()</code>
+      method covered above. This method evaluates the passed in key and
+      collects all configuration nodes that match this criterion. Then
+      for each node a <code>HierarchicalConfiguration</code> object is
+      created with this node as root node. A list with these configuration
+      objects is returned. As the following example shows this comes in
+      very handy when processing list-like structures:
+    </p>
+<source><![CDATA[
+List<HierarchicalConfiguration<ImmutableNode>> fields = 
+    config.configurationsAt("tables.table(0).fields.field");
+for(HierarchicalConfiguration sub : fields)
+{
+    // sub contains all data about a single field
+    String fieldName = sub.getString("name");
+    String fieldType = sub.getString("type");
+    ...
+]]></source>
+    <p>
+      Per default, the configurations returned by the 
<code>configurationAt()</code> and
+      <code>configurationsAt()</code> methods are a kind of snapshots of
+      the data stored in the original configuration. If the original
+      configuration is later changed, these changes are not visible in the
+      sub configuration and vice versa. If configuration settings just need
+      to be read, this is fine.
+    </p>
+    <p>
+      It is also possible to connect a sub configuration more directly to
+      its original configuration. This is done by using overloaded versions
+      of <code>configurationAt()</code> and <code>configurationsAt()</code>
+      which accept an additional <strong>boolean</strong> parameter. If
+      here the value <strong>true</strong> is passed, a special
+      configuration implementation is returned (in fact, an instance of the
+      <code><a 
href="../apidocs/org/apache/commons/configuration/SubnodeConfiguration.html">
+      SubnodeConfiguration</a></code> class) that operates on the same
+      data structures as the original configuration. Therefore, changes made
+      on one configuration are directly reflected by the other one.
+    </p>
+    <p>
+      Connecting a sub configuration with its parent configuration in the
+      described way is useful in use cases in which configurations are
+      updated. However, there can be pretty drastic updates which break
+      such a connection. As an example, consider the case that a sub
+      configuration is created for a certain sub tree of an original
+      configuration. Now this sub tree gets removed from the original
+      configuration. In this case, the sub configuration becomes detached
+      from its parent. Its content is not changed, but it is now again like
+      a snapshot or a copy of the original. This is demonstrated again in
+      the following example:
+<source><![CDATA[
+// sub points to the 2nd table
+HierarchicalConfiguration<ImmutableNode> sub = 
config.configurationAt("tables.table(1)", true);
+assertEquals("documents", sub.getString("name"));
+
+// Now change name in parent configuration => should be visible in sub config
+config.setProperty("tables.table(1).name", "tasks");
+assertEquals("tasks", sub.getString("name"));
+
+// Clear the whole content of the 2nd table
+config.clearTree("tables.table(1)");
+// The key used to create the sub configuration is no longer valid,
+// so it is now detacted; it contains the recent data.
+assertEquals("tasks", sub.getString("name"));
+]]></source>
+    </p>
+    <p>
+      This example uses the <code>clearTree()</code> method of
+      <code>HierarchicalConfiguration</code> to remove all information
+      about the second database table from the configuration data. While
+      <code>clearProperty()</code> only removes the value of a property,
+      <code>clearTree()</code> also removes all child elements and their
+      children recursively. After this operation the key
+      <em>tables.table(1)</em> specified when the sub configuration was
+      created no longer points to an existing element; therefore, the
+      sub configuration gets detached. Once detached, a sub configuration
+      cannot be reconnected to its parent again. Even if another table
+      element was added (making the sub key valid again), the sub
+      configuration remains detached.
+    </p>
+    </subsection>
+
+    <subsection name="Adding new properties">
+    <p>
+      So far we have learned how to use indices to avoid ambiguities when
+      querying properties. The same problem occurs when adding new
+      properties to a structured configuration. As an example let's
+      assume we want to add a new field to the second table. New properties
+      can be added to a configuration using the <code>addProperty()</code>
+      method. Of course, we have to exactly specify where in the tree like 
structure new
+      data is to be inserted. A statement like
+    </p>
+    <source><![CDATA[
+// Warning: This might cause trouble!
+config.addProperty("tables.table.fields.field.name", "size");
+]]></source>
+    <p>
+      would not be sufficient because it does not contain all needed
+      information. How is such a statement processed by the
+      <code>addProperty()</code> method?
+    </p>
+    <p>
+      <code>addProperty()</code> splits the provided key into its
+      single parts and navigates through the properties tree along the
+      corresponding element names. In this example it will start at the
+      root element and then find the <code>tables</code> element. The
+      next key part to be processed is <code>table</code>, but here a
+      problem occurs: the configuration contains two <code>table</code>
+      properties below the <code>tables</code> element. To get rid off
+      this ambiguity an index can be specified at this position in the
+      key that makes clear, which of the two properties should be
+      followed. <code>tables.table(1).fields.field.name</code> e.g.
+      would select the second <code>table</code> property. If an index
+      is missing, <code>addProperty()</code> always follows the last
+      available element. In our example this would be the second
+      <code>table</code>, too.
+    </p>
+    <p>
+      The following parts of the key are processed in exactly the same
+      manner. Under the selected <code>table</code> property there is
+      exactly one <code>fields</code> property, so this step is not
+      problematic at all. In the next step the <code>field</code> part
+      has to be processed. At the actual position in the properties tree
+      there are multiple <code>field</code> (sub) properties. So we here
+      have the same situation as for the <code>table</code> part.
+      Because no explicit index is defined the last <code>field</code>
+      property is selected. The last part of the key passed to
+      <code>addProperty()</code> (<code>name</code> in this example)
+      will always be added as new property at the position that has
+      been reached in the former processing steps. So in our example
+      the last <code>field</code> property of the second table would
+      be given a new <code>name</code> sub property and the resulting
+      structure would look like the following listing:
+    </p>
+    <source><![CDATA[
+       ...
+    <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>
+          <name>size</name>    <== Newly added property
+          <type>int</type>
+        </field>
+      </fields>
+    </table>
+  </tables>
+</database>
+]]></source>
+    <p>
+      This result is obviously not what was desired, but it demonstrates
+      how <code>addProperty()</code> works: the method follows an
+      existing branch in the properties tree and adds new leaves to it.
+      (If the passed in key does not match a branch in the existing tree,
+      a new branch will be added. E.g. if we pass the key
+      <code>tables.table.data.first.test</code>, the existing tree can be
+      navigated until the <code>data</code> part of the key. From here a
+      new branch is started with the remaining parts <code>data</code>,
+      <code>first</code> and <code>test</code>.)
+    </p>
+    <p>
+      If we want a different behavior, we must explicitely tell
+      <code>addProperty()</code> what to do. In our example with the
+      new field our intension was to create a new branch for the
+      <code>field</code> part in the key, so that a new <code>field</code>
+      property is added to the structure rather than adding sub properties
+      to the last existing <code>field</code> property. This can be
+      achieved by specifying the special index <code>(-1)</code> at the
+      corresponding position in the key as shown below:
+    </p>
+    <source><![CDATA[
+config.addProperty("tables.table(1).fields.field(-1).name", "size");
+config.addProperty("tables.table(1).fields.field.type", "int");
+]]></source>
+    <p>
+      The first line in this fragment specifies that a new branch is
+      to be created for the <code>field</code> property (index -1).
+      In the second line no index is specified for the field, so the
+      last one is used - which happens to be the field that has just
+      been created. So these two statements add a fully defined field
+      to the second table. This is the default pattern for adding new
+      properties or whole hierarchies of properties: first create a new
+      branch in the properties tree and then populate its sub properties.
+      As an additional example let's add a complete new table definition
+      to our example configuration:
+    </p>
+    <source><![CDATA[
+// Add a new table element and define the name
+config.addProperty("tables.table(-1).name", "versions");
+
+// Add a new field to the new table
+// (an index for the table is not necessary because the latest is used)
+config.addProperty("tables.table.fields.field(-1).name", "id");
+config.addProperty("tables.table.fields.field.type", "int");
+
+// Add another field to the new table
+config.addProperty("tables.table.fields.field(-1).name", "date");
+config.addProperty("tables.table.fields.field.type", "java.sql.Date");
+...
+]]></source>
+    <p>
+      For more information about adding properties to a hierarchical
+      configuration also have a look at the javadocs for
+      <code><a 
href="../apidocs/org/apache/commons/configuration/HierarchicalConfiguration.html">
+      HierarchicalConfiguration</a></code>.
+    </p>
+    </subsection>
+
+    <subsection name="Escaping special characters">
+    <p>
+      Some characters in property keys or values require a special
+      treatment.
+    </p>
+    <p>
+      Per default the dot character is used as delimiter by most
+      configuration classes (we will learn how to change this for
+      hierarchical configurations in a later section). In some
+      configuration formats however, dots can be contained in the
+      names of properties. For instance, in XML the dot is a legal
+      character that can occur in any tag. The same is true for the names
+      of properties in windows ini files. So the following XML
+      document is completely valid:
+    </p>
+    <source><![CDATA[
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<configuration>
+  <test.value>42</test.value>
+  <test.complex>
+    <test.sub.element>many dots</test.sub.element>
+  </test.complex>
+</configuration>
+]]></source>
+    <p>
+      This XML document can be loaded by <code>XMLConfiguration</code>
+      without trouble, but when we want to access certain properties
+      we face a problem: The configuration claims that it does not
+      store any values for the properties with the keys
+      <code>test.value</code> or <code>test.complex.test.sub.element</code>!
+    </p>
+    <p>
+      Of course, it is the dot character contained in the property
+      names, which causes this problem. A dot is always interpreted
+      as a delimiter between elements. So given the property key
+      <code>test.value</code> the configuration would look for an
+      element named <code>test</code> and then for a sub element
+      with the name <code>value</code>. To change this behavior it is
+      possible to escape a dot character, thus telling the configuration
+      that it is really part of an element name. This is simply done
+      by duplicating the dot. So the following statements will return
+      the desired property values:
+    </p>
+   <source><![CDATA[
+int testVal = config.getInt("test..value");
+String complex = config.getString("test..complex.test..sub..element");
+]]></source>
+    <p>
+      Note the duplicated dots whereever the dot does not act as
+      delimiter. This way it is possible to access properties containing
+      dots in arbitrary combination. However, as you can see, the
+      escaping can be confusing sometimes. So if you have a choice,
+      you should avoid dots in the tag names of your XML configuration
+      files or other configuration sources.
+    </p>
+    </subsection>
+    </section>
+
+    <section name="Expression engines">
+        <p>
+            In the previous chapters we saw many examples about how properties
+            in a <code>XMLConfiguration</code> object (or more general in a
+            <code>HierarchicalConfiguration</code> object, because this is the
+            base interface, which defines this functionality) can be queried or
+            modified using a special syntax for the property keys. Well, this
+            was not the full truth. Actually, property keys are not processed
+            by the configuration object itself, but are delegated to a helper
+            object, a so called <em>Expression engine</em>.
+        </p>
+        <p>
+            The separation of the task of interpreting property keys into a
+            helper object is a typical application of the <em>Strategy</em>
+            design pattern. In this case it also has the advantage that it
+            becomes possible to plug in different expression engines into a
+            <code>HierarchicalConfiguration</code> object. So by providing
+            different implementations of the
+            <code><a 
href="../apidocs/org/apache/commons/configuration/tree/ExpressionEngine.html">
+            ExpressionEngine</a></code>
+            interface hierarchical configurations can support alternative
+            expression languages for accessing their data.
+        </p>
+        <p>
+            Before we discuss the available expression engines that ship
+            with Commons Configuration, it should be explained how an
+            expression engine can be associated with a configuration object.
+            <code><a 
href="../apidocs/org/apache/commons/configuration/HierarchicalConfiguration.html">
+            HierarchicalConfiguration</a></code> and all implementing classes
+            provide a <code>setExpressionEngine()</code> method, which expects
+            an implementation of the <code>ExpressionEngine</code> interface as
+            argument. After this method was called, the configuration object 
will
+            use the passed expression engine, which means that all property 
keys
+            passed to methods like <code>getProperty()</code>,
+            <code>getString()</code>, or <code>addProperty()</code> must
+            conform to the syntax supported by this engine. Property keys
+            returned by the <code>getKeys()</code> method will follow this
+            syntax, too.
+        </p>
+        <p>
+            The recommended approach is that a configuration object is fully
+            initialized by the <a href="howto_builders.html">configuration
+            builder</a> which creates it. The initialization parameters for
+            hierarchical configurations allow setting the expression engine as
+            shown in the following code fragment (more information about
+            initialization parameters for hierarchical and XML configurations
+            is provided in a later section in this chapter):
+        </p>
+<source><![CDATA[
+Parameters params = new Parameters();
+FileBasedConfigurationBuilder<XMLConfiguration> builder =
+    new 
FileBasedConfigurationBuilder<BaseHierarchicalConfiguration>(BaseHierarchicalConfiguration.class)
+    .configure(params.hierarchical()
+        .setExpressionEngine(new MyExpressionEngine()));
+]]></source>
+        <p>
+            Remember that it is possible to define
+            <a 
href="howto_builders.html#Default_Initialization_Parameters">Default
+            Initialization Parameters</a> for specific configuration classes.
+            Using this mechanism, it is possible to instance to set a special
+            expression engine for all XML configurations used by an
+            application.
+        </p>
+        
+        <subsection name="The default expression engine">
+            <p>
+                The syntax described so far for property keys of hierarchical
+                configurations is implemented by a specific implementation of 
the
+                <code><a 
href="../apidocs/org/apache/commons/configuration/tree/ExpressionEngine.html">
+                ExpressionEngine</a></code> interface called
+                <code><a 
href="../apidocs/org/apache/commons/configuration/tree/DefaultExpressionEngine.html">
+                DefaultExpressionEngine</a></code>. An instance of this class
+                is used by the base implementation of
+                <code>HierarchicalConfiguration</code> if no specific 
expression
+                engine was set (which is the reason why our examples above 
worked).
+            </p>
+            <p>
+                After reading the examples of property keys provided so far in
+                this document you should have a sound understanding regarding
+                the features and the syntax supported by the
+                <code>DefaultExpressionEngine</code> class. But it can do a
+                little bit more for you: it defines a bunch of settings,
+                which can be used to customize most tokens that can appear in a
+                valid property key. You prefer curly brackets over paranthesis
+                as index markers? You find the duplicated dot as escaped
+                property delimiter counter-intuitive? Well, simply go ahead and
+                change it! The following example shows how the syntax of a
+                <code>DefaultExpressionEngine</code> object is modified. The
+                key is to create an instance of the
+                <code><a 
href="../apidocs/org/apache/commons/configuration/tree/DefaultExpressionEngineSymbols.html">
+                DefaultExpressionEngineSymbols</a></code> class and to
+                initialize it with the desired syntax elements. This is done
+                using a builder approach:
+            </p>
+            <source><![CDATA[
+DefaultExpressionEngineSymbols symbols =
+    new DefaultExpressionEngineSymbols.Builder(
+        DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS)
+        // Use a slash as property delimiter
+        .setPropertyDelimiter("/")
+        // Indices should be specified in curly brackets
+        .setIndexStart("{")
+        .setIndexEnd("}")
+        // For attributes use simply a @
+        .setAttributeStart("@")
+        .setAttributeEnd(null)
+        // A Backslash is used for escaping property delimiters
+        .setEscapedDelimiter("\\/")
+        .create();
+        
+// Now create a configuration using this expression engine
+Parameters params = new Parameters();
+FileBasedConfigurationBuilder<XMLConfiguration> builder =
+    new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
+    .configure(params.xml()
+        .setFileName("tables.xml")
+        .setExpressionEngine(engine));
+XMLConfiguration config = builder.getConfiguration();
+
+// Access properties using the new syntax
+String tableName = config.getString("tables/table{0}/name");
+String tableType = config.getString("tables/table{0}@type");
+         ]]></source>
+            <p>
+              <code>DefaultExpressionEngineSymbol</code> objects are
+              immutable; the same is true for 
<code>DefaultExpressionEngine</code>.
+              Thus a single expression engine instance can be shared between
+              multiple configuration instances. The example fragment shows the
+              typical usage pattern for constructing new
+              <code>DefaultExpressionEngine</code> instances with an 
alternative
+              syntax: A builder for a symbols object is constructed passing in
+              an instance that serves as starting point - here the constant
+              <code>DEFAULT_SYMBOLS</code> is used which defines the standard
+              syntax. Then methods of the builder are used to modify only the
+              settings which are to be adapted.
+            </p>
+            <p>
+                <em>Tip:</em> Sometimes when processing an XML document you
+                don't want to distinguish between attributes and 
&quot;normal&quot;
+                child nodes. You can achieve this by setting the
+                <code>AttributeEnd</code> property to <b>null</b> and the
+                <code>AttributeStart</code> property to the same value as the
+                <code>PropertyDelimiter</code> property. Then the syntax for
+                accessing attributes is the same as the syntax for other
+                properties:
+            </p>
+            <source><![CDATA[
+DefaultExpressionEngineSymbols symbolsNoAttributes =
+    new DefaultExpressionEngineSymbols.Builder(
+        DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS)
+        .setAttributeStart(
+            
DefaultExpressionEngineSymbols.DEFAULT_SYMBOLS.getPropertyDelimiter())
+        .setAttributeEnd(null)
+        .create();
+DefaultExpressionEngine engine = new 
DefaultExpressionEngine(symbolsNoAttributes);
+...
+Object value = config.getProperty("tables.table(0).name");
+// name can either be a child node of table or an attribute
+         ]]></source>
+        </subsection>
+        
+        <subsection name="The XPATH expression engine">
+            <p>
+                The expression language provided by the 
<code>DefaultExpressionEngine</code>
+                class is powerful enough to address all properties in a
+                hierarchical configuration, but it is not always convenient to
+                use. Especially if list structures are involved, it is often
+                necessary to iterate through the whole list to find a certain
+                element.
+            </p>
+            <p>
+                Think about our example configuration that stores information 
about
+                database tables. A use case could be to load all fields that 
belong
+                to the &quot;users&quot; table. If you knew the index of this
+                table, you could simply build a property key like
+                <code>tables.table(&lt;index&gt;).fields.field.name</code>,
+                but how do you find out the correct index? When using the
+                default expression engine, the only solution to this problem is
+                to iterate over all tables until you find the &quot;users&quot;
+                table.
+            </p>
+            <p>
+                Life would be much easier if an expression language could be 
used,
+                which would directly support queries of such kind. In the XML
+                world, the XPATH syntax has grown popular as a powerful means
+                of querying structured data. In XPATH a query that selects all
+                field names of the &quot;users&quot; table would look something
+                like <code>tables/table[@name='users']/fields/name</code> (here
+                we assume that the table's name is modelled as an attribute).
+                This is not only much simpler than an iteration over all 
tables,
+                but also much more readable: it is quite obvious, which fields
+                are selected by this query.
+            </p>
+            <p>
+                Given the power of XPATH it is no wonder that we got many
+                user requests to add XPATH support to <em>Commons 
Configuration</em>.
+                Well, here is it!
+            </p>
+            <p>
+                For enabling XPATH syntax for property keys you need the
+                <code><a 
href="../apidocs/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.html">
+                XPathExpressionEngine</a></code> class. This class
+                implements the <code>ExpressionEngine</code> interface and can
+                be plugged into a <code>HierarchicalConfiguration</code> object
+                in the same way as described above. Because instances of
+                <code>XPathExpressionEngine</code> are thread-safe and can be
+                shared between multiple configuration objects it is also
+                possible to set an instance as the default expression engine
+                in the <a 
href="howto_builders.html#Default_Initialization_Parameters">
+                default initialization parameters</a> for configuration
+                builders, so that all hierarchical configuration
+                objects make use of XPATH syntax. The following code fragment
+                shows how XPATH support can be enabled for a configuration
+                object:
+            </p>
+            <source><![CDATA[
+Parameters params = new Parameters();
+FileBasedConfigurationBuilder<XMLConfiguration> builder =
+    new FileBasedConfigurationBuilder<XMLConfiguration>(XMLConfiguration.class)
+    .configure(params.xml()
+        .setFileName("tables.xml")
+        .setExpressionEngine(new XPathExpressionEngine()));
+XMLConfiguration config = builder.getConfiguration();
+
+// Now we can use XPATH queries:
+List<Object> fields = config.getList("tables/table[1]/fields/name");
+         ]]></source>
+            <p>
+                XPATH expressions are not only used for selecting properties
+                (i.e. for the several getter methods), but also for adding new
+                properties. For this purpose the keys passed into the
+                <code>addProperty()</code> method must conform to a special
+                syntax. They consist of two parts: the first part is an
+                arbitrary XPATH expression that selects the node where the new
+                property is to be added to, the second part defines the new
+                element to be added. Both parts are separated by whitespace.
+            </p>
+            <p>
+                Okay, let's make an example. Say, we want to add a 
<code>type</code>
+                property under the first table (as a sibling to the 
<code>name</code>
+                element). Then the first part of our key will have to select
+                the first table element, the second part will simply be
+                <code>type</code>, i.e. the name of the new property:
+            </p>
+            <source><![CDATA[
+config.addProperty("tables/table[1] type", "system");
+         ]]></source>
+            <p>
+                (Note that indices in XPATH are 1-based, while in the default
+                expression language they are 0-based.) In this example the part
+                <code>tables/table[1]</code> selects the target element of the
+                add operation. This element must exist and must be unique, 
otherwise an exception
+                will be thrown. <code>type</code> is the name of the new 
element
+                that will be added. If instead of a normal element an attribute
+                should be added, the example becomes
+            </p>
+            <source><![CDATA[
+config.addProperty("tables/table[1] @type", "system");
+         ]]></source>
+            <p>
+                It is possible to add complete paths at once. Then the single
+                elements in the new path are separated by &quot;/&quot;
+                characters. The following example shows how data about a new
+                table can be added to the configuration. Here we use full 
paths:
+            </p>
+            <source><![CDATA[
+// Add new table "tasks" with name element and type attribute
+config.addProperty("tables table/name", "tasks");
+// last() selects the last element of this name,
+// which is the newest table element
+config.addProperty("tables/table[last()] @type", "system");
+
+// Now add fields
+config.addProperty("tables/table[last()] fields/field/name", "taskid");
+config.addProperty("tables/table[last()]/fields/field[last()] type", "int");
+config.addProperty("tables/table[last()]/fields field/name", "name");
+config.addProperty("tables/table[last()]/fields field/name", "startDate");
+...
+         ]]></source>
+            <p>
+                The first line of this example adds the path 
<code>table/name</code>
+                to the <code>tables</code> element, i.e. a new 
<code>table</code>
+                element will be created and added as last child to the
+                <code>tables</code> element. Then a new <code>name</code> 
element
+                is added as child to the new <code>table</code> element. To 
this
+                element the value &quot;tasks&quot; is assigned. The next line
+                adds a <code>type</code> attribute to the new table element. To
+                obtain the correct <code>table</code> element, to which the
+                attribute must be added, the XPATH function <code>last()</code>
+                is used; this function selects the last element with a given
+                name, which in this case is the new <code>table</code> element.
+                The following lines all use the same approach to construct a 
new
+                element hierarchy: At first complete new branches are added
+                (<code>fields/field/name</code>), then to the newly created
+                elements further children are added.
+            </p>
+            <p>
+                There is one gotcha with these keys described so far: they do
+                not work with the <code>setProperty()</code> method! This is
+                because <code>setProperty()</code> has to check whether the
+                passed in key already exists; therefore it needs a key which 
can
+                be interpreted by query methods. If you want to use
+                <code>setProperty()</code>, you can pass in regular keys (i.e.
+                without a whitespace separator). The method then tries to 
figure
+                out which part of the key already exists in the configuration
+                and adds new nodes as necessary. In principle such regular keys
+                can also be used with <code>addProperty()</code>. However, they
+                do not contain sufficient information to decide where new nodes
+                should be added.
+            </p>
+            <p>
+                To make this clearer let's go back to the example with the
+                tables. Consider that there is a configuration which already
+                contains information about some database tables. In order to 
add
+                a new table element in the configuration
+                <code>addProperty()</code> could be used as follows:
+            </p>
+            <source><![CDATA[
+config.addProperty("tables/table/name", "documents");
+         ]]></source>
+            <p>
+                In the configuration a <code>&lt;tables&gt;</code> element
+                already exists, also <code>&lt;table&gt;</code> and
+                <code>&lt;name&gt;</code> elements. How should the expression
+                engine know where new node structures are to be added? The
+                solution to this problem is to provide this information in the
+                key by stating:
+            </p>
+            <source><![CDATA[
+config.addProperty("tables table/name", "documents");
+         ]]></source>
+            <p>
+                Now it is clear that new nodes should be added as children of
+                the  <code>&lt;tables&gt;</code> element. More information 
about
+                keys and how they play together with <code>addProperty()</code>
+                and <code>setProperty()</code> can be found in the Javadocs for
+                <a 
href="../apidocs/org/apache/commons/configuration/tree/xpath/XPathExpressionEngine.html">
+                <code>XPathExpressionEngine</code></a>.
+            </p>
+            <p>
+                <em>Note:</em> XPATH support is implemented through
+                <a href="http://commons.apache.org/jxpath";>Commons JXPath</a>.
+                So when making use of this feature, be sure you include the
+                commons-jxpath jar in your classpath.
+            </p>
+            <p>
+                In this tutorial we don't want to describe XPATH syntax and
+                expressions in detail. Please refer to corresponding 
documentation.
+                It is important to mention that by embedding Commons JXPath the
+                full extent of the XPATH 1.0 standard can be used for 
constructing
+                property keys.
+            </p>
+        </subsection>
+    </section>
+</body>
+
+</document>
\ No newline at end of file

Modified: 
commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml
URL: 
http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml?rev=1601235&r1=1601234&r2=1601235&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml 
(original)
+++ commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml 
Sun Jun  8 18:23:12 2014
@@ -82,18 +82,18 @@
         <li><a 
href="howto_properties.html#Custom_properties_readers_and_writers">Custom 
properties readers and writers</a></li>
         <li><a 
href="howto_properties.html#Builder_Configuration_Related_to_Properties_Files">Builder
 Configuration Related to Properties Files</a></li>
       </ul>
-      <li><a href="howto_xml.html#Hierarchical_Configurations">Hierarchical 
Configurations</a></li>
+      <li><a 
href="howto_hierarchical.html#Hierarchical_Configurations">Hierarchical 
Configurations</a></li>
       <ul>
-        <li><a 
href="howto_xml.html#Accessing_properties_in_hierarchical_configurations">Accessing
 properties in hierarchical configurations</a></li>
-        <li><a href="howto_xml.html#Complex_hierarchical_structures">Complex 
hierarchical structures</a></li>
-        <li><a href="howto_xml.html#Accessing_structured_properties">Accessing 
structured properties</a></li>
-        <li><a href="howto_xml.html#Sub_Configurations">Sub 
Configurations</a></li>
-        <li><a href="howto_xml.html#Adding_new_properties">Adding new 
properties</a></li>
-        <li><a href="howto_xml.html#Escaping_special_characters">Escaping dot 
characters in property names</a></li>
-        <li><a href="howto_xml.html#Expression_engines">Expression 
engines</a></li>
+        <li><a 
href="howto_hierarchical.html#Accessing_properties_in_hierarchical_configurations">Accessing
 properties in hierarchical configurations</a></li>
+        <li><a 
href="howto_hierarchical.html#Complex_hierarchical_structures">Complex 
hierarchical structures</a></li>
+        <li><a 
href="howto_hierarchical.html#Accessing_structured_properties">Accessing 
structured properties</a></li>
+        <li><a href="howto_hierarchical.html#Sub_Configurations">Sub 
Configurations</a></li>
+        <li><a href="howto_hierarchical.html#Adding_new_properties">Adding new 
properties</a></li>
+        <li><a 
href="howto_hierarchical.html#Escaping_special_characters">Escaping dot 
characters in property names</a></li>
+        <li><a href="howto_hierarchical.html#Expression_engines">Expression 
engines</a></li>
         <ul>
-          <li><a href="howto_xml.html#The_default_expression_engine">The 
default expression engine</a></li>
-          <li><a href="howto_xml.html#The_XPATH_expression_engine">The XPATH 
expression engine</a></li>
+          <li><a 
href="howto_hierarchical.html#The_default_expression_engine">The default 
expression engine</a></li>
+          <li><a 
href="howto_hierarchical.html#The_XPATH_expression_engine">The XPATH expression 
engine</a></li>
         </ul>
         <li><a 
href="howto_xml.html#Validation_of_XML_configuration_files">Validation of XML 
configuration files</a></li>
       </ul>


Reply via email to