13-Jul-04 (Created: 13-Jul-04) | More in 'OSCON-2004'

Unified Abstract Configuration Pattern Examples

An abstract definition


public interface IConfig
{
	String getValue(String hierarchicalKey) throws ConfigException;
	String getValue(String hierarchicalKey, String defaultValue);
	Object fillObject(String hierarchicalKey, Object o) throws ConfigException;
}

Consider the following XML file


<key1>
     <key2>
           <key3>some-value</key3>
           <key4>some-other-value</key4>
     </key2>
</key1>

Let us see how we read these keys


IConfig cfg = Somehow.getIConfig();
String key3 = cfg.getValue("key1.key2.key3");
String key4 = cfg.getValue("key1.key2.key4");
//List of key3, and key4
List keys = cfg.getValue(""key1.key2");

Mandatory key reading


//The following will throw
//key not found exception
String key5 = cfg.getValue("key1.key2.key5");

Default values for keys


//Non existent key5 will now have value5
String key5 = cfg.getValue("key1.key2.key5", "value5");

Child/Attribute equivalence

The above xml will be equivalent to


<key1>
     <key2 key3="some-value" key4="some-other-value">
     </key2>
</key1>

XML/Property file equivalence

The above XML file is equivalent to


key1.key2.key3=some-value
key1.key2.key4=some-other-value

Object as a hierarchical data structure

We can redefine the above XML not only as a properties file but also as an object as follows


class key2
{
	String key3;
	String key4;
}

class Key1
{
	Key2 key2;
}

IConfig as a data source for an object

If we were to see an object as a structure and needing a set of hierarchical values, we can treat a configuration as a source for such an abstraction. With this understanding the above XML root node, the parent of key1 is said to be anchoring the object Key1. It should be fairly direct to see how we can directly read the configuration in to an object if needed.


Key1 key1Variable = cfg.fillObject( "key1", new Key1());

Need for an XPathConfig

The hierarchical keys that are used are really aproximations of an Xpath expression. Under some cirumstances it is desirable to have the full enquiring power of XPath at hand. In that scenario a configuration implementation may chose to additionally implement the following defined XPath interface as well


public interface IXPathConfig extends IConfig
{
	String getValue(String xpathExpr) throws ConfigException;
	String getValue(String xpathExpr, String defaultValue);

	List getNodes(String xpathExpr, String defaultValue);
	Object fillObject(String xpathExpr, Object o) throws ConfigException;
}

The intention is very similar except that the API is extended to carry an XPath expression and return appropriate hierarchical nodes. The implementation config file can be any structure for which an XPath implementation is available.

Multiple configuration files treated as a single configuration source

Development systems typically have more than one configuration file. This is purely an implmentation detail. The client is not aware that the configuration is split between multiple files. It is one of convenience.

References

1. General Introduction to Server side patterns

2. My notes on other patterns