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><full qualified class name>.<field name></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 "echo"
+ 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