<?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>