You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by oh...@apache.org on 2006/12/30 17:05:52 UTC

svn commit: r491244 - /jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml

Author: oheger
Date: Sat Dec 30 08:05:51 2006
New Revision: 491244

URL: http://svn.apache.org/viewvc?view=rev&rev=491244
Log:
CONFIGURATION-192: Added new chapter about basic features (like variable interpolation) to the user guide

Added:
    jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml   (with props)

Added: jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml?view=auto&rev=491244
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml (added)
+++ jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml Sat Dec 30 08:05:51 2006
@@ -0,0 +1,277 @@
+<?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>Configuration Basic Features</title>
+  <author email="oheger@apache.org">Oliver Heger</author>
+ </properties>
+
+<body>
+	<section name="Basic features and AbstractConfiguration">
+    <p>
+      The <code>Configuration</code> interface defines a whole bunch of methods.
+      Implementing these methods all from scratch can be quite hard. Because of
+      that the <code><a href="apidocs/org/apache/commons/configuration/AbstractConfiguration.html">
+      AbstractConfiguration</a></code> class exists. This class serves as a
+      common base class for most of the <code>Configuration</code> implementations
+      in <em>Commons Configuration</em> and provides a great deal of the
+      functionality required by the interface. So for creating a custom
+      <code>Configuration</code> implementation this class will be a good
+      starting point.
+    </p>
+    <p>
+      In addition to base implementations for lots of the methods declared in
+      the <code>Configuration</code> interface the <code>AbstractConfiguration</code>
+      class provides some other handy and convenient features. Because this
+      class is at the very root of the class hierarchy in <em>Commons
+      Configuration</em> these features are available in most of the specific
+      implementations of the <code>Configuration</code> interface provided by
+      this library. We will cover some of these basic features in this section.
+    </p>
+
+    <subsection name="Handling of missing properties">
+	<p>
+      What is a configuration object supposed to do if you pass in a key to one
+      of its get methods that does not map to an existing property? Well, the
+      default behavior as implemented in <code>AbstractConfiguration</code> is
+      to return <b>null</b> if the return value is an object type. For primitive
+      types as return values returning <b>null</b> (or any other special
+      value) is not possible, so in this case a <code>NoSuchElementException</code>
+      is thrown:
+    </p>
+    <source><![CDATA[
+// This will probably return null
+String strValue = config.getString("NonExistingProperty");
+
+// This might throw an exception
+long longValue = config.getLong("NonExistingProperty");
+]]></source>
+    <p>
+      For object types like <code>String</code>, <code>BigDecimal</code>, or
+      <code>BigInteger</code> this default behavior can be changed: If the
+      <code>setThrowExceptionOnMissing()</code> method is called with an
+      argument of <b>true</b>, these methods will behave like their primitive
+      counter parts and also throw an exception if the passed in property key
+      cannot be resolved.
+    </p>
+    <p>
+      <em>Note:</em> Unfortunately support for the <code>throwExceptionOnMissing</code>
+      property is not always consistent: The methods <code>getList()</code> and
+      <code>getStringArray()</code> do not evaluate this flag, but return an
+      empty list or array if the requested property cannot be found. Maybe this
+      behavior will be changed in a future major release.
+    </p>
+    </subsection>
+
+    <subsection name="List handling">
+    <p>
+      With <code>getList()</code> and <code>getStringArray()</code> the
+      <code>Configuration</code> interface defines methods for dealing with
+      properties that have multiple values. When a configuration source (e.g.
+      a properties file, an XML document, or a JNDI context) is processed the
+      corresponding <code>Configuration</code> implementation detects such
+      properties with multiple values and ensures that the data is correctly
+      stored.
+    </p>
+    <p>
+      When modifying properties the <code>addProperty()</code> and
+      <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:
+    </p>
+<source>
+// Change the list delimiter character to a slash
+config.setListDelimiter('/');
+// Now add some properties
+config.addProperty("greeting", "Hello, how are you?");
+config.addProperty("colors.pie",
+  new String[] { "#FF0000", "#00FF00", "#0000FF" });
+config.addProperty("colors.graph", "#808080/#00FFCC/#6422FF");
+
+// Access data
+String salut = config.getString("greeting");
+List colPie = config.getList("colors.pie");
+String[] colGraph = config.getStringArray("colors.graph");
+
+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 splitted, 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.
+    </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">
+    <p>
+      If you are familiar with Ant or Maven, you have most certainly already encountered
+      the variables (like <code>${token}</code>) that are automatically expanded when the
+      configuration file is loaded. Commons Configuration supports this feature as well,
+      here is an example (we use a properties file in this example, but other
+      configuration sources work the same way; you can learn more about
+      properties files in the chapter <a href="howto_properties.html">Properties
+      files</a>):
+    </p>
+<source>
+application.name = Killer App
+application.version = 1.6.2
+
+application.title = ${application.name} ${application.version}
+</source>
+    <p>
+      If you now retrieve the value for the <code>application.title</code>
+      property, the result will be <code>Killer App 1.6.2</code>. So per default
+      variables are interpreted as the keys of other properties. This is only a
+      special case, the general syntax of a variable name is
+      <code>${prefix:name}</code>. The prefix tells Commons Configuration that
+      the variable is to evaluated in a certain context. We have already seen
+      that the context is the current configuration instance if the prefix is
+      missing. The following other prefix names are supported by default:
+      <table border="1">
+      <tr>
+        <th>Prefix</th>
+        <th>Description</th>
+      </tr>
+      <tr>
+        <td valign="top">sys</td>
+        <td>This prefix marks a variable to be a system property. Commons
+        Configuration will search for a system property with the given name and
+        replace the variable by its value. This is a very easy means for
+        accessing the values of system properties in every configuration
+        implementation.</td>
+      </tr>
+      <tr>
+        <td valign="top">const</td>
+        <td>The <code>const</code> prefix indicates that a variable is to be
+        interpreted as a constant member field of a class (i.e. a field with the
+        <b>static final</b> modifiers). The name of the variable must be of the form
+        <code>&lt;full qualified class name&gt;.&lt;field name&gt;</code>. The
+        specified class will be loaded and the value of this field will be
+        obtained.</td>
+      </tr>
+      </table>
+      Here are some examples (again using properties syntax):
+    </p>
+    <source><![CDATA[
+user.file = ${sys:user.home}/settings.xml
+
+action.key = ${const:java.awt.event.KeyEvent.VK_CANCEL}
+]]></source>
+    <p>
+      If a variable cannot be resolved, e.g. because the name is invalid or an
+      unknown prefix is used, it won't be replaced, but is returned as is
+      including the dollar sign and the curly braces.
+    </p>
+    </subsection>
+    
+    <subsection name="Customizing interpolation">
+    <p>
+      This sub section goes a bit behind the scenes of interpolation and
+      explains some approaches how you can add your own interpolation facilities.
+      Under the hood interpolation is implemented using the
+      <code>StrSubstitutor</code> class of the <code>text</code> package of
+      <a href="http://jakarta.apache.org/commons/lang/">Commons Lang</a>. This
+      class uses objects derived from the <code>StrLookup</code> class for
+      resolving variables. <code>StrLookup</code> defines a simple
+      <code>lookup()</code> method that must be implemented by custom
+      implementations; it expects the name of a variable as argument and
+      returns the corresponding value (further details can be found in the
+      documentation of Commons Lang). The standard prefixes for variables we
+      have covered so far are indeed realized by special classes derived from
+      <code>StrLookup</code>.
+    </p>
+    <p>
+      It is now possible to create your own implementation of <code>StrLookup</code>
+      and make it available for all configuration objects under a custom
+      prefix. We will show how this can be achieved. The first step is to
+      create a new class derived from <code>StrLookup</code>, which must
+      implement the <code>lookup()</code> method. As an example we implement a
+      rather dull lookup object that simply returns a kind of &quot;echo&quot;
+      for the variable passed in:
+    </p>
+    <source><![CDATA[
+import org.apache.commons.lang.text.StrLookup;
+
+public class EchoLookup extends StrLookup
+{
+    public String lookup(String varName)
+    {
+        return "Value of variable " + varName;
+    }
+}
+]]></source>
+    <p>
+      Now we want this class to be called for variables with the prefix
+      <code>echo</code>. For this purpose the <code>EchoLookup</code> class
+      has to be registered at the
+      <code><a href="apidocs/org/apache/commons/configuration/interpol/ConfigurationInterpolator.html">
+      ConfigurationInterpolator</a></code> class with the desired prefix.
+      <code>ConfigurationInterpolator</code> implements a thin wrapper over the
+      <code>StrLookup</code> API defined by Commons Lang. It has a static
+      <code>registerGlobalLookup()</code> method, which we have to call as
+      follows:
+    </p>
+    <source><![CDATA[
+// Place this code somewhere in an initialization section of your application
+ConfigurationInterpolator.registerGlobalLookup("echo", new EchoLookup());
+    ]]></source>
+    <p>
+      Each <code>AbstractConfiguration</code> object that is created after this
+      line is executed will contain the new lookup class and can thus resolve
+      variables of the form <code>${echo:my_variable}</code>.
+    </p>
+    <p>
+      Each instance of <code>AbstractConfiguration</code> is associated with a
+      <code>ConfigurationInterpolator</code> object. This object is created by
+      the <code>createInterpolator()</code> method on first access of one of
+      the interpolation features. By overriding this method even deeper
+      intervention in the interpolation mechanism is possible. For instance
+      a custom implementation can add further lookup objects to the interpolator,
+      which are then only used by this configuration instance.
+    </p>
+    </subsection>
+    </section>
+</body>
+
+</document>
\ No newline at end of file

Propchange: jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/commons/proper/configuration/trunk/xdocs/howto_basicfeatures.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org