You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2013/08/24 21:50:30 UTC

svn commit: r1517187 - in /commons/proper/configuration/trunk/src/site/xdoc/userguide: howto_basicfeatures.xml overview.xml user_guide.xml

Author: oheger
Date: Sat Aug 24 19:50:30 2013
New Revision: 1517187

URL: http://svn.apache.org/r1517187
Log:
Extended the user's guide.

Added sections describing the basic data type conversion facilities and how
they can be customized. The section about list delimiter handling was
reworked, too.

Modified:
    commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_basicfeatures.xml
    commons/proper/configuration/trunk/src/site/xdoc/userguide/overview.xml
    commons/proper/configuration/trunk/src/site/xdoc/userguide/user_guide.xml

Modified: commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_basicfeatures.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_basicfeatures.xml?rev=1517187&r1=1517186&r2=1517187&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_basicfeatures.xml (original)
+++ commons/proper/configuration/trunk/src/site/xdoc/userguide/howto_basicfeatures.xml Sat Aug 24 19:50:30 2013
@@ -96,18 +96,50 @@ long longValue = config.getLong("NonExis
       <code>setProperty()</code> methods of <code>AbstractConfiguration</code>
       also implement special list handling. The property value that is passed
       to these methods can be a list or an array resulting in a property
-      with multiple values. If the property value is a string, it is checked
-      whether it contains the <em>list delimiter character</em>. If this is
-      the case, the string is splitted, and its single parts are added one
-      by one. The list delimiter character is the comma by default. It is
-      also taken into account when the configuration source is loaded
-      (i.e. string values of properties will be checked whether they contain
-      this delimiter). By using the <code>setListDelimiter()</code>
-      method you can set it to a different character. Here are some examples:
+      with multiple values.
+    </p>
+    <p>
+      For some use cases it makes sense to treat string values in a special way.
+      For instance, some configuration formats do not support lists directly.
+      As an example, properties files can be used: they just consist of
+      key-value pairs, and there is no default syntax to assign multiple values
+      to a key. <code>AbstractConfiguration</code> supports a mechanism to split
+      strings at specific characters, so that effectively multiple values are
+      generated from a single string. To achieve this, an
+      <code>AbstractConfiguration</code> instance collaborates with an object
+      implementing the
+      <code><a href="../apidocs/org/apache/commons/configuration/convert/ListDelimiterHandler.html">
+      ListDelimiterHandler</a></code> interface. This interface defines methods
+      for dealing with objects that may contain multiple values. Examples of
+      such complex objects are arrays, lists, and strings containing a specific
+      list delimiter. Depending on a concrete implementation of the
+      <code>ListDelimiterHandler</code> interface, these objects are treated in
+      a special way.
+    </p>
+    <p>
+      Per default, <code>AbstractConfiguration</code> uses an instance of the
+      <code><a href="../apidocs/org/apache/commons/configuration/convert/DisabledListDelimiterHandler.html">
+      DisabledListDelimiterHandler</a></code> class as list handler. This
+      class can deal with lists and arrays, but it does not recognize any list
+      delimiter characters in strings. (Hence the name, as splitting of strings
+      at list delimiters is disabled.)
+    </p>
+    <p>
+      An alternative implementation of <code>ListDelimiterHandler</code> is
+      <code><a href="../apidocs/org/apache/commons/configuration/convert/DefaultListDelimiterHandler.html">
+      DefaultListDelimiterHandler</a></code>. This class actually supports
+      string splitting; the list delimiter character has to be passed to the
+      constructor. Whenever a property is added to the configuration (or the
+      configuration is loaded from its source), it is checked whether the
+      property value is a string and - if so - if it contains the list
+      delimiter character. In this case, the string is split, and its single
+      parts are added one by one. By using the <code>setListDelimiterHandler()</code>
+      method you can set a specific list handler implementation. Here are some
+      examples:
     </p>
 <source>
-// Change the list delimiter character to a slash
-config.setListDelimiter('/');
+// Enable list delimiter handling using a slash as delimiter character
+config.setListDelimiterHandler(new DefaultListDelimiterHandler('/'));
 // Now add some properties
 config.addProperty("greeting", "Hello, how are you?");
 config.addProperty("colors.pie",
@@ -122,29 +154,25 @@ String[] colGraph = config.getStringArra
 String firstPieColor = config.getString("colors.pie");
 </source>
     <p>
-      In this example the list delimiter character is changed from a comma
-      to a slash. Because of this the <code>greeting</code> property won't
-      be split, but remains a single string. The string passed as value
-      for the <code>colors.graph</code> property in opposite contains the
-      new delimiter character and thus will result in a property with three
-      values. Note that lists are of type <code>Object</code>. This is because
-      the concrete class of the values of a property is not known. For instance,
-      if you call <code>addProperty(&quot;answer&quot;, 42)</code>, an
-      <code>Integer</code> object will be stored in the configuration.
+      In this example splitting of strings is enabled using the slash character
+      as delimiter. Because this character is not contained in the
+      <code>greeting</code> property it won't be split, but remains a single
+      string. In contrast, the string passed as value for the
+      <code>colors.graph</code> property contains the delimiter character and
+      thus will result in a property with three values. Note that the
+      version of the <code>getList()</code> method used here returns lists of type
+      <code>Object</code>. This is because the concrete class of the values of a
+      property is not known. For instance, if you call
+      <code>addProperty(&quot;answer&quot;, 42)</code>, an
+      <code>Integer</code> object will be stored in the configuration. However,
+      there are overloaded versions of <code>getList()</code> supporting a
+      data type conversion to a specific target class (see below).
     </p>
     <p>
       Of interest is also the last line of the example fragment. Here the
       <code>getString()</code> method is called for a property that has
       multiple values. This call will return the first value of the list.
     </p>
-    <p>
-      If you want to change the list delimiter character for all configuration
-      objects, you can use the static <code>setDefaultListDelimiter()</code>
-      method of <code>AbstractConfiguration</code>. It is also possible to
-      disable splitting of string properties at all for a Configuration
-      instance by calling its <code>setDelimiterParsingDisabled()</code>
-      method with a value of <b>true</b>.
-    </p>
     </subsection>
 
     <subsection name="Variable Interpolation">
@@ -282,6 +310,7 @@ ConfigurationInterpolator.registerGlobal
       which are then only used by this configuration instance.
     </p>
     </subsection>
+
     <subsection name="Using Expressions">
       <p>
         In addition to the simple lookup mechanisms previously described, Commond Configuration
@@ -355,6 +384,180 @@ user.file = ${expr:System.getProperty("u
 </configuration>
 ]]></source>
     </subsection>
+
+    <subsection name="Data type conversions">
+    <p>
+      As was already mentioned when discussing the
+      <code><a href="../apidocs/org/apache/commons/configuration/Configuration.html">
+      Configuration</a></code> interface, there are various <code>get()</code>
+      methods returning property values in different target data types. If
+      necessary, a data type conversion is performed. Take a look at the
+      following example:
+    </p>
+<source><![CDATA[
+config.addProperty("answer", "42");
+int theAnswer = config.getInt("answer");
+]]></source>
+    <p>
+      Here a string value is assigned to the key <em>answer</em>. Then the
+      <code>getInt()</code> method is called to query this key as an integer
+      value. <code>getInt()</code> triggers a type conversion automatically.
+      If such a conversion is not possible, a runtime exception of type
+      <code>ConversionException</code> is thrown.
+    </p>
+    <p>
+      The <code>Configuration</code> interface defines a bunch of methods
+      returning property values in different data types. All of these methods
+      work in the same way: they obtain the actual value of the property and
+      attempt a data type conversion if necessary. In addition, there are
+      generic methods for accessing properties in specific data types:
+      <dl>
+        <dt>&lt;T&gt; get(Class&lt;T&gt; cls, String key);</dt>
+        <dd>Obtains the value of the specified property and tries to convert it
+        to the specified target type. If the key cannot be resolved, result is
+        <b>null</b>, or - if the <em>throwExceptionOnMissing</em> flag is set -
+        an exception is thrown.</dd>
+        <dt>&lt;T&gt; get(Class&lt;T&gt; cls, String key, T defValue);</dt>
+        <dd>Obtains the value of the specified property and tries to convert it
+        to the specified target type. If the key cannot be resolved, the
+        specified default value is returned (which may be <b>null</b>).</dd>
+      </dl>
+      In fact, all specialized <code>get()</code> methods are based on these
+      generic methods.
+    </p>
+    <p>
+      Generic conversion methods are also available for obtaining arrays or
+      collections. For instance, it is possible to obtain the value of a
+      property as an array of <b>int</b> or a list of <code>java.lang.Long</code>
+      objects. This can be achieved using the following methods:
+      <dl>
+        <dt>Object getArray(Class&lt;?&gt; cls, String key);</dt>
+        <dd>Returns an array of the specified element class. This method can
+        handle both object and primitive arrays. (Therefore, the return type
+        is just <code>Object</code> because there is no common base class for
+        all kinds of arrays.)</dd>
+        <dt>&lt;T&gt; List&lt;T&gt; getList(Class&lt;T&gt; cls, String key);</dt>
+        <dd>Returns a list of the specified element class.</dd>
+        <dt>&lt;T&gt; Collection&lt;T&gt; getCollection(Class&lt;T&gt; cls,
+        String key, Collection&lt;T&gt; target);</dt>
+        <dd>This method is similar to <code>getList()</code>, but it allows
+        specifying the target collection. This is useful if the result should
+        be stored in a different collection type, e.g. a set to remove
+        duplicates.</dd>
+      </dl>
+    </p>
+    <p>
+      These methods obtain all values stored for the property with the
+      passed in key. For each value a conversion to the desired target type is
+      performed. Then the resulting values are stored in the target array or
+      collection. There are also variants supporting default values.
+    </p>
+    <p>
+      It is worth to mention that data type conversion plays well together with
+      <a href="#Variable_Interpolation">variable interpolation</a>: Before a
+      data type conversion is attempted interpolation is handled first. Then
+      the resulting object is converted if necessary.
+    </p>
+    </subsection>
+
+    <subsection name="Customizing data type conversions">
+    <p>
+      <em>Commons Configuration</em> supports a number of conversions to
+      standard types out of the box. In addition to the result types of the
+      <code>get()</code> methods in the <code>Configuration</code> interface,
+      some more types are supported. These are listed in the documentation of the
+      <code><a href="../apidocs/org/apache/commons/configuration/DataConfiguration.html">
+      DataConfiguration</a></code> class. <code>DataConfiguration</code> is a
+      <em>decorator</em> providing additional data type conversion methods for
+      more target types; these additional methods are implemented on top of the
+      generic conversion methods provided by <code>AbstractConfiguration</code>.
+    </p>
+    <p>
+      If your application deals with special objects, there may be the
+      requirement to extend the conversion capabilities offered by the
+      library. To support this use case, there is the
+      <code><a href="../apidocs/org/apache/commons/configuration/convert/ConversionHandler.html">
+      ConversionHandler</a></code> interface. Each instance of a configuration
+      class derived from <code>AbstractConfiguration</code> is associated with
+      such a <code>ConversionHandler</code> object. The interface defines
+      methods for converting an object to a target class, and for converting
+      values to arrays or collections of a given element type. The data type
+      conversion methods implemented in <code>AbstractConfiguration</code>
+      delegate to this handler object.
+    </p>
+    <p>
+      The <code>ConversionHandler</code> interface gives a developer full
+      control over the whole data conversion process. By implementing the
+      different conversion methods, it is possible to integrate existing
+      conversion libraries (e.g. the converters offered by
+      <a href="http://commons.apache.org/proper/commons-beanutils/">Commons
+      BeanUtils</a>) with <em>Commons Configuration</em>.
+    </p>
+    <p>
+      If the conversion facilities provided by <em>Commons Configuration</em>
+      are not to be fully replaced, but only extended by some custom types,
+      the class <code><a href="../apidocs/org/apache/commons/configuration/convert/DefaultConversionHandler.html">
+      DefaultConversionHandler</a></code> is a good starting point. As the name
+      implies, an instance of this class is used per default for doing type
+      conversions. <code>DefaultConversionHandler</code> has some protected
+      methods which can be overridden by subclasses in order to extend data type
+      conversions:
+      <dl>
+        <dt><code>convertValue()</code></dt>
+        <dd>This is the main conversion method for single values. It is called
+        when a single value is to be converted to a target type and also for
+        the single elements of arrays or collections. If a conversion to another
+        target class is to be supported, this is the method to override. A
+        custom implementation typically checks whether the desired target class
+        is one of the classes it supports. If this is the case, the passed in
+        source object is converted, and the result is returned. Otherwise, the
+        super method is called to handle standard conversions.</dd>
+        <dt><code>isComplexObject()</code></dt>
+        <dd>This boolean method determines whether a passed in object contains
+        multiple values. When doing a conversion to a target class
+        <code>DefaultConversionHandler</code> checks whether the source object
+        is a complex object like an array or a collection. If this is the case,
+        it first extracts the value to be converted from the source object
+        before it calls <code>convertValue()</code>.</dd>
+        <dt><code>extractConversionValue()</code></dt>
+        <dd><code>extractConversionValue()</code> is called if a complex object
+        (i.e. an object containing multiple values) is to be converted to a
+        single object (i.e. not an array or a collection). In this case, it is
+        not directly obvious how the multiple values should be handled. This
+        situation occurs for example if a client calls <code>getInt()</code>
+        on a property which actually has multiple values. The default
+        implementation of <code>extractConversionValue()</code> simply returns
+        the first value available. If an application needs a different
+        behavior, it can provide a custom implementation of this method.</dd>
+        <dt><code>convert()</code></dt>
+        <dd>This method contains the logic for converting a single value. It
+        delegates to the other methods discussed here. It first checks whether
+        the object to be converted is a complex one. If so, it extracts the
+        value to be converted. Eventually, it delegates to
+        <code>convertValue()</code> for performing the actual conversion. So
+        in order to gain more control over the whole conversion process, this
+        method is a good candidate for overriding.</dd>
+      </dl>
+    </p>
+    <p>
+      After a custom <code>ConversionHandler</code> implementation has been
+      created, it can be installed at a configuration instance by using the
+      <code>setConversionHandler()</code> method:
+    </p>
+<source><![CDATA[
+CustomConversionHandler handler = new CustomConversionHandler(...);
+config.setConversionHandler(handler);
+]]></source>
+    <p>
+      Another feature of <code>DefaultConversionHandler</code> is that is
+      allows defining the format for the conversion of <code>Date</code> and
+      <code>Calendar</code> objects. This can be done by calling
+      <code>setDateFormat()</code> with the corresponding date pattern. The
+      expected string argument must be a pattern string compatible with the
+      <code>java.text.SimpleDateFormat</code> class. If no date format was set,
+      the default pattern <code>yyyy-MM-dd HH:mm:ss</code> is used.
+    </p>
+    </subsection>
   </section>
 </body>
 

Modified: commons/proper/configuration/trunk/src/site/xdoc/userguide/overview.xml
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/site/xdoc/userguide/overview.xml?rev=1517187&r1=1517186&r2=1517187&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/site/xdoc/userguide/overview.xml (original)
+++ commons/proper/configuration/trunk/src/site/xdoc/userguide/overview.xml Sat Aug 24 19:50:30 2013
@@ -169,12 +169,14 @@ Configuration config = factory.getConfig
         </ul>
         The names of these methods start with <code>get</code> followed by their
         data type. The <code>getString()</code> method for instance will return
-        String values, <code>getInt()</code> will operate on integers.
+        String values, <code>getInt()</code> will operate on integers. In
+        addition, there is a generic <code>get()</code> method which tries to
+        convert the value of a property to a specified target class.
       </p>
       <p>
         Properties can have multiple values, so it is also possible to query a
-        list containing all of the available values. This is done using the
-        <code>getList()</code> method.
+        list or an array containing all of the available values. This is done
+        using the <code>getList()</code> or <code>getArray()</code> methods.
       </p>
       <p>
         For manipulating properties or their values the following methods can

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=1517187&r1=1517186&r2=1517187&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 Sat Aug 24 19:50:30 2013
@@ -51,6 +51,9 @@
         <li><a href="howto_basicfeatures.html#List_handling">List handling</a></li>
         <li><a href="howto_basicfeatures.html#Variable_Interpolation">Variable Interpolation</a></li>
         <li><a href="howto_basicfeatures.html#Customizing_interpolation">Customizing interpolation</a></li>
+        <li><a href="howto_basicfeatures.html#Using_Expressions">Using Expressions</a></li>
+        <li><a href="howto_basicfeatures.html#Data_type_conversions">Data type conversions</a></li>
+        <li><a href="howto_basicfeatures.html#Customizing_data_type_conversions">Customizing data type conversions</a></li>
       </ul>
       <li><a href="howto_properties.html#Properties_files">Properties files</a></li>
       <ul>