public interface IConfig
{
String getValue(String hierarchicalKey) throws ConfigException;
String getValue(String hierarchicalKey, String defaultValue);
Object fillObject(String hierarchicalKey, Object o) throws ConfigException;
}
<key1>
<key2>
<key3>some-value</key3>
<key4>some-other-value</key4>
</key2>
</key1>
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");
//The following will throw
//key not found exception
String key5 = cfg.getValue("key1.key2.key5");
//Non existent key5 will now have value5
String key5 = cfg.getValue("key1.key2.key5", "value5");
The above xml will be equivalent to
<key1>
<key2 key3="some-value" key4="some-other-value">
</key2>
</key1>
The above XML file is equivalent to
key1.key2.key3=some-value
key1.key2.key4=some-other-value
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;
}
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());
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.
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.