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/06/08 22:11:30 UTC
svn commit: r412848 - in /jakarta/commons/proper/configuration/trunk: conf/
src/java/org/apache/commons/configuration/
src/java/org/apache/commons/configuration/beanutils/
src/test/org/apache/commons/configuration/
src/test/org/apache/commons/configura...
Author: oheger
Date: Thu Jun 8 13:11:29 2006
New Revision: 412848
URL: http://svn.apache.org/viewvc?rev=412848&view=rev
Log:
Enabled support for variable interpolation in DefaultConfigurationBuilder
Modified:
jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java
jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml
Modified: jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml (original)
+++ jakarta/commons/proper/configuration/trunk/conf/testComplexInitialization.xml Thu Jun 8 13:11:29 2006
@@ -15,17 +15,19 @@
</override>
</combiner>
</header>
+ <system/>
<properties fileName="test.properties" throwExceptionOnMissing="true"
config-name="properties">
<reloadingStrategy config-class="org.apache.commons.configuration.reloading.FileChangedReloadingStrategy"
refreshDelay="10000"/>
</properties>
- <xml fileName="test.xml" config-name="xml">
+ <!-- Fetch the file name from a variable -->
+ <xml fileName="${test_file_xml}" config-name="xml">
<expressionEngine config-class="org.apache.commons.configuration.tree.DefaultExpressionEngine"
propertyDelimiter="/" indexStart="[" indexEnd="]"/>
</xml>
<additional>
- <xml config-name="combiner1" fileName="testcombine1.xml"/>
+ <xml config-name="combiner1" fileName="${test_file_combine}"/> -->
<xml config-name="combiner2" fileName="testcombine2.xml"/>
</additional>
</configuration>
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/DefaultConfigurationBuilder.java Thu Jun 8 13:11:29 2006
@@ -30,6 +30,7 @@
import org.apache.commons.configuration.plist.PropertyListConfiguration;
import org.apache.commons.configuration.plist.XMLPropertyListConfiguration;
import org.apache.commons.configuration.tree.ConfigurationNode;
+import org.apache.commons.configuration.tree.DefaultExpressionEngine;
import org.apache.commons.configuration.tree.OverrideCombiner;
import org.apache.commons.configuration.tree.UnionCombiner;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
@@ -152,6 +153,11 @@
* configuration under the name defined by the <code>ADDITIONAL_NAME</code>
* constant.
* </p>
+ * <p>
+ * Implementation note: This class is not thread-safe. Especially the
+ * <code>getConfiguration()</code> methods should be called by a single thread
+ * only.
+ * </p>
*
* @since 1.3
* @author Oliver Heger
@@ -180,16 +186,40 @@
+ ".CONFIG_BEAN_FACTORY_NAME";
/** Constant for the reserved name attribute. */
- static final String ATTR_NAME = XMLBeanDeclaration.RESERVED_PREFIX + "name";
+ static final String ATTR_NAME = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + XMLBeanDeclaration.RESERVED_PREFIX
+ + "name"
+ + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
+
+ /** Constant for the name of the at attribute. */
+ static final String ATTR_ATNAME = "at";
/** Constant for the reserved at attribute. */
- static final String ATTR_AT = "at";
+ static final String ATTR_AT_RES = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + XMLBeanDeclaration.RESERVED_PREFIX
+ + ATTR_ATNAME
+ + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
+
+ /** Constant for the at attribute without the reserved prefix. */
+ static final String ATTR_AT = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + ATTR_ATNAME + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
+
+ /** Constant for the name of the optional attribute. */
+ static final String ATTR_OPTIONALNAME = "optional";
/** Constant for the reserved optional attribute. */
- static final String ATTR_OPTIONAL = "optional";
+ static final String ATTR_OPTIONAL_RES = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + XMLBeanDeclaration.RESERVED_PREFIX
+ + ATTR_OPTIONALNAME
+ + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
+
+ /** Constant for the optional attribute without the reserved prefix. */
+ static final String ATTR_OPTIONAL = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + ATTR_OPTIONALNAME + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
/** Constant for the file name attribute. */
- static final String ATTR_FILENAME = "fileName";
+ static final String ATTR_FILENAME = DefaultExpressionEngine.DEFAULT_ATTRIBUTE_START
+ + "fileName" + DefaultExpressionEngine.DEFAULT_ATTRIBUTE_END;
/** Constant for the name of the header section. */
static final String SEC_HEADER = "header";
@@ -268,6 +298,9 @@
{ PROPERTIES_PROVIDER, XML_PROVIDER, XML_PROVIDER, JNDI_PROVIDER,
SYSTEM_PROVIDER, PLIST_PROVIDER, BUILDER_PROVIDER };
+ /** Stores the configuration that is currently constructed.*/
+ private CombinedConfiguration constructedConfiguration;
+
/** Stores a map with the registered configuration providers. */
private Map providers;
@@ -436,15 +469,21 @@
load();
}
- CombinedConfiguration result = createOverrideConfiguration();
+ CombinedConfiguration result = createResultConfiguration();
+ constructedConfiguration = result;
+
+ List overrides = configurationsAt(KEY_OVERRIDE1);
+ overrides.addAll(configurationsAt(KEY_OVERRIDE2));
+ initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST);
+
List additionals = configurationsAt(KEY_UNION);
if (!additionals.isEmpty())
{
CombinedConfiguration addConfig = new CombinedConfiguration(
new UnionCombiner());
+ result.addConfiguration(addConfig, ADDITIONAL_NAME);
initCombinedConfiguration(addConfig, additionals,
KEY_ADDITIONAL_LIST);
- result.addConfiguration(addConfig, ADDITIONAL_NAME);
}
return result;
@@ -452,18 +491,16 @@
/**
* Creates the resulting combined configuration. This method is called by
- * <code>getConfiguration()</code>. Its task is to construct the
- * resulting (override) combined configuration and to add all declared
- * override configurations to it. This implementation checks whether the
+ * <code>getConfiguration()</code>. It checks whether the
* <code>header</code> section of the configuration definition file
* contains a <code>result</code> element. If this is the case, it will be
* used to initialize the properties of the newly created configuration
* object.
*
- * @return the override configuration object
+ * @return the resulting configuration object
* @throws ConfigurationException if an error occurs
*/
- protected CombinedConfiguration createOverrideConfiguration()
+ protected CombinedConfiguration createResultConfiguration()
throws ConfigurationException
{
XMLBeanDeclaration decl = new XMLBeanDeclaration(this, KEY_RESULT, true);
@@ -476,9 +513,6 @@
result.setNodeCombiner(new OverrideCombiner());
}
- List overrides = configurationsAt(KEY_OVERRIDE1);
- overrides.addAll(configurationsAt(KEY_OVERRIDE2));
- initCombinedConfiguration(result, overrides, KEY_OVERRIDE_LIST);
return result;
}
@@ -491,11 +525,11 @@
* @param containedConfigs the list with the declaratinos of the contained
* configurations
* @param keyListNodes a list with the declaration of list nodes
+ * @param interpolConfig the configuration to be used for interpolation
* @throws ConfigurationException if an error occurs
*/
protected void initCombinedConfiguration(CombinedConfiguration config,
- List containedConfigs, String keyListNodes)
- throws ConfigurationException
+ List containedConfigs, String keyListNodes) throws ConfigurationException
{
List listNodes = getList(keyListNodes);
for (Iterator it = listNodes.iterator(); it.hasNext();)
@@ -512,8 +546,8 @@
AbstractConfiguration newConf = createConfigurationAt(decl);
if (newConf != null)
{
- config.addConfiguration(newConf, decl
- .attributeValueStr(ATTR_NAME), decl.getAt());
+ config.addConfiguration(newConf, decl.getConfiguration()
+ .getString(ATTR_NAME), decl.getAt());
}
}
}
@@ -532,6 +566,26 @@
}
/**
+ * Performs interpolation. This method will not only take this configuration
+ * instance into account (which is the one that loaded the configuration
+ * definition file), but also the so far constructed combined configuration.
+ * So variables can be used that point to properties that are defined in
+ * configuration sources loaded by this builder.
+ *
+ * @param value the value to be interpolated
+ * @return the interpolated value
+ */
+ protected Object interpolate(Object value)
+ {
+ Object result = super.interpolate(value);
+ if (constructedConfiguration != null)
+ {
+ result = constructedConfiguration.interpolate(result);
+ }
+ return result;
+ }
+
+ /**
* Creates a configuration object from the specified configuration
* declaration.
*
@@ -654,15 +708,16 @@
*/
protected static class ConfigurationDeclaration extends XMLBeanDeclaration
{
- /** Stores a reference to the associated configuration factory. */
+ /** Stores a reference to the associated configuration builder. */
private DefaultConfigurationBuilder configurationBuilder;
/**
* Creates a new instance of <code>ConfigurationDeclaration</code> and
* initializes it.
*
- * @param buikder the associated configuration builder
+ * @param builder the associated configuration builder
* @param config the configuration this declaration is based onto
+ * @param interpolConfig the configuration to be used for interpolation
*/
public ConfigurationDeclaration(DefaultConfigurationBuilder builder,
HierarchicalConfiguration config)
@@ -688,8 +743,9 @@
*/
public String getAt()
{
- String result = attributeValueStr(RESERVED_PREFIX + ATTR_AT);
- return (result == null) ? attributeValueStr(ATTR_AT) : result;
+ String result = getConfiguration().getString(ATTR_AT_RES);
+ return (result == null) ? getConfiguration().getString(ATTR_AT)
+ : result;
}
/**
@@ -700,23 +756,14 @@
*/
public boolean isOptional()
{
- Object value = attributeValue(RESERVED_PREFIX + ATTR_OPTIONAL);
+ Boolean value = getConfiguration().getBoolean(ATTR_OPTIONAL_RES,
+ null);
if (value == null)
{
- value = attributeValue(ATTR_OPTIONAL);
- }
-
- try
- {
- return (value != null) ? PropertyConverter.toBoolean(value)
- .booleanValue() : false;
- }
- catch (ConversionException cex)
- {
- throw new ConfigurationRuntimeException(
- "optional attribute does not have a valid boolean value",
- cex);
+ value = getConfiguration().getBoolean(ATTR_OPTIONAL,
+ Boolean.FALSE);
}
+ return value.booleanValue();
}
/**
@@ -743,29 +790,6 @@
}
/**
- * Returns the value of the specified attribute. This can be useful for
- * certain <code>ConfigurationProvider</code> implementations.
- *
- * @param attrName the attribute's name
- * @return the attribute's value (or <b>null</b> if it does not exist)
- */
- public Object attributeValue(String attrName)
- {
- return super.attributeValue(attrName);
- }
-
- /**
- * Returns the string value of the specified attribute.
- *
- * @param attrName the attribute's name
- * @return the attribute's value (or <b>null</b> if it does not exist)
- */
- public String attributeValueStr(String attrName)
- {
- return super.attributeValueStr(attrName);
- }
-
- /**
* Checks whether the given node is reserved. This method will take
* further reserved attributes into account
*
@@ -780,10 +804,23 @@
}
return nd.isAttribute()
- && ((ATTR_AT.equals(nd.getName()) && nd.getParentNode()
- .getAttributeCount(RESERVED_PREFIX + ATTR_AT) == 0) || (ATTR_OPTIONAL
+ && ((ATTR_ATNAME.equals(nd.getName()) && nd.getParentNode()
+ .getAttributeCount(RESERVED_PREFIX + ATTR_ATNAME) == 0) || (ATTR_OPTIONALNAME
.equals(nd.getName()) && nd.getParentNode()
- .getAttributeCount(RESERVED_PREFIX + ATTR_OPTIONAL) == 0));
+ .getAttributeCount(RESERVED_PREFIX + ATTR_OPTIONALNAME) == 0));
+ }
+
+ /**
+ * Performs interpolation. This implementation will delegate
+ * interpolation to the configuration builder, which takes care that the
+ * currently constructed configuration is taken into account, too.
+ *
+ * @param value the value to be interpolated
+ * @return the interpolated value
+ */
+ protected Object interpolate(Object value)
+ {
+ return getConfigurationBuilder().interpolate(value);
}
}
@@ -971,7 +1008,7 @@
BeanDeclaration data) throws Exception
{
String fileName = ((ConfigurationDeclaration) data)
- .attributeValueStr(ATTR_FILENAME);
+ .getConfiguration().getString(ATTR_FILENAME);
if (fileName != null
&& fileName.toLowerCase().trim().endsWith(fileExtension))
{
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/HierarchicalConfiguration.java Thu Jun 8 13:11:29 2006
@@ -407,12 +407,12 @@
/**
* <p>
- * Returns a hierarchical configuration object that wraps the configuration
- * node specified by the given key. This method provides an easy means of
- * accessing sub trees of a hierarchical configuration. In the returned
- * configuration the sub tree can directly be accessed, it becomes the root
- * node of this configuration. Because of this the passed in key must select
- * exactly one configuration node; otherwise an
+ * Returns a hierarchical subnode configuration object that wraps the
+ * configuration node specified by the given key. This method provides an
+ * easy means of accessing sub trees of a hierarchical configuration. In the
+ * returned configuration the sub tree can directly be accessed, it becomes
+ * the root node of this configuration. Because of this the passed in key
+ * must select exactly one configuration node; otherwise an
* <code>IllegalArgumentException</code> will be thrown.
* </p>
* <p>
@@ -420,18 +420,17 @@
* <code>{@link #subset(String)}</code> method is that
* <code>subset()</code> supports arbitrary subsets of configuration nodes
* while <code>configurationAt()</code> only returns a single sub tree.
- * Actually, the object returned by this method is an instance of
- * <code>SubnodeConfiguration</code>. Please refer to the documentation
- * of this class to obtain further information about subnode configurations
- * and when they should be used.
+ * Please refer to the documentation of the
+ * <code>SubnodeConfiguration</code> class to obtain further information
+ * about subnode configurations and when they should be used.
* </p>
- *
+ *
* @param key the key that selects the sub tree
* @return a hierarchical configuration that contains this sub tree
* @see SubnodeConfiguration
* @since 1.3
*/
- public HierarchicalConfiguration configurationAt(String key)
+ public SubnodeConfiguration configurationAt(String key)
{
List nodes = fetchNodeList(key);
if (nodes.size() != 1)
@@ -489,7 +488,7 @@
* @return the configuration for the given node
* @since 1.3
*/
- protected HierarchicalConfiguration createSubnodeConfiguration(ConfigurationNode node)
+ protected SubnodeConfiguration createSubnodeConfiguration(ConfigurationNode node)
{
return new SubnodeConfiguration(this, node);
}
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/SubnodeConfiguration.java Thu Jun 8 13:11:29 2006
@@ -113,7 +113,7 @@
* @param node the sub node, for which the configuration is to be created
* @return a hierarchical configuration for this sub node
*/
- protected HierarchicalConfiguration createSubnodeConfiguration(ConfigurationNode node)
+ protected SubnodeConfiguration createSubnodeConfiguration(ConfigurationNode node)
{
return new SubnodeConfiguration(getParent(), node);
}
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/beanutils/XMLBeanDeclaration.java Thu Jun 8 13:11:29 2006
@@ -17,11 +17,11 @@
import java.util.HashMap;
import java.util.Iterator;
-import java.util.List;
import java.util.Map;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.PropertyConverter;
+import org.apache.commons.configuration.SubnodeConfiguration;
import org.apache.commons.configuration.tree.ConfigurationNode;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
@@ -85,6 +85,16 @@
* it can have attributes defining meta data or bean properties and even further
* nested elements for complex bean properties.
* </p>
+ * <p>
+ * A <code>XMLBeanDeclaration</code> object is usually created from a
+ * <code>HierarchicalConfiguration</code>. From this it will derive a
+ * <code>SubnodeConfiguration</code>, which is used to access the needed
+ * properties. This subnode configuration can be obtained using the
+ * <code>{@link #getConfiguration()}</code> method. All of its properties can
+ * be accessed in the usual way. To ensure that the property keys used by this
+ * class are understood by the configuration, the default expression engine will
+ * be set.
+ * </p>
*
* @since 1.3
* @author Oliver Heger
@@ -95,18 +105,21 @@
/** Constant for the prefix of reserved attributes. */
public static final String RESERVED_PREFIX = "config-";
+ /** Constant for the prefix for reserved attributes.*/
+ private static final String ATTR_PREFIX = "[@" + RESERVED_PREFIX;
+
/** Constant for the bean class attribute. */
- public static final String ATTR_BEAN_CLASS = RESERVED_PREFIX + "class";
+ public static final String ATTR_BEAN_CLASS = ATTR_PREFIX + "class]";
/** Constant for the bean factory attribute. */
- public static final String ATTR_BEAN_FACTORY = RESERVED_PREFIX + "factory";
+ public static final String ATTR_BEAN_FACTORY = ATTR_PREFIX + "factory]";
/** Constant for the bean factory parameter attribute. */
- public static final String ATTR_FACTORY_PARAM = RESERVED_PREFIX
- + "factoryParam";
+ public static final String ATTR_FACTORY_PARAM = ATTR_PREFIX
+ + "factoryParam]";
/** Stores the associated configuration. */
- private HierarchicalConfiguration configuration;
+ private SubnodeConfiguration configuration;
/** Stores the configuration node that contains the bean declaration. */
private ConfigurationNode node;
@@ -153,8 +166,8 @@
try
{
- node = (key == null) ? config.getRoot() : config.configurationAt(
- key).getRoot();
+ configuration = config.configurationAt(key);
+ node = configuration.getRootNode();
}
catch (IllegalArgumentException iex)
{
@@ -163,9 +176,10 @@
{
throw iex;
}
+ configuration = config.configurationAt(null);
node = new DefaultConfigurationNode();
}
- configuration = config;
+ initSubnodeConfiguration(getConfiguration());
}
/**
@@ -188,7 +202,7 @@
* @param config the configuration
* @param node the node with the bean declaration.
*/
- public XMLBeanDeclaration(HierarchicalConfiguration config,
+ public XMLBeanDeclaration(SubnodeConfiguration config,
ConfigurationNode node)
{
if (config == null)
@@ -203,6 +217,7 @@
this.node = node;
configuration = config;
+ initSubnodeConfiguration(config);
}
/**
@@ -210,7 +225,7 @@
*
* @return the associated configuration
*/
- public HierarchicalConfiguration getConfiguration()
+ public SubnodeConfiguration getConfiguration()
{
return configuration;
}
@@ -233,7 +248,7 @@
*/
public String getBeanFactoryName()
{
- return attributeValueStr(ATTR_BEAN_FACTORY);
+ return getConfiguration().getString(ATTR_BEAN_FACTORY);
}
/**
@@ -244,7 +259,7 @@
*/
public Object getBeanFactoryParameter()
{
- return attributeValue(ATTR_FACTORY_PARAM);
+ return getConfiguration().getProperty(ATTR_FACTORY_PARAM);
}
/**
@@ -255,7 +270,7 @@
*/
public String getBeanClassName()
{
- return attributeValueStr(ATTR_BEAN_CLASS);
+ return getConfiguration().getString(ATTR_BEAN_CLASS);
}
/**
@@ -272,8 +287,7 @@
ConfigurationNode attr = (ConfigurationNode) it.next();
if (!isReservedNode(attr))
{
- props.put(attr.getName(), PropertyConverter.interpolate(attr
- .getValue(), getConfiguration()));
+ props.put(attr.getName(), interpolate(attr .getValue()));
}
}
@@ -296,7 +310,7 @@
if (!isReservedNode(child))
{
nested.put(child.getName(), new XMLBeanDeclaration(
- getConfiguration(), child));
+ getConfiguration().configurationAt(child.getName()), child));
}
}
@@ -304,18 +318,18 @@
}
/**
- * Returns the value of the specified attribute node or <b>null</b> if it
- * does not exist. If there are multiple attributes with this name, this
- * implementation selects the first one.
- *
- * @param attrName the name of the attribute
- * @return the value of this attribute
- */
- protected Object attributeValue(String attrName)
- {
- List attrs = getNode().getAttributes(attrName);
- return attrs.isEmpty() ? null : ((ConfigurationNode) attrs.get(0))
- .getValue();
+ * Performs interpolation for the specified value. This implementation will
+ * interpolate against the current subnode configuration's parent. If sub
+ * classes need a different interpolation mechanism, they should override
+ * this method.
+ *
+ * @param value the value that is to be interpolated
+ * @return the interpolated value
+ */
+ protected Object interpolate(Object value)
+ {
+ return PropertyConverter.interpolate(value, getConfiguration()
+ .getParent());
}
/**
@@ -336,15 +350,14 @@
}
/**
- * Returns the value of the specified attribute as string. This is a
- * convenience method.
+ * Initializes the internally managed subnode configuration. This method
+ * will set some default values for some properties.
*
- * @param attrName the name of the attribute
- * @return the attribute's value as string
+ * @param conf the configuration to initialize
*/
- protected String attributeValueStr(String attrName)
+ private void initSubnodeConfiguration(SubnodeConfiguration conf)
{
- Object value = attributeValue(attrName);
- return (value != null) ? value.toString() : null;
+ conf.setThrowExceptionOnMissing(false);
+ conf.setExpressionEngine(null);
}
}
Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestDefaultConfigurationBuilder.java Thu Jun 8 13:11:29 2006
@@ -20,7 +20,6 @@
import java.util.Set;
import org.apache.commons.configuration.beanutils.BeanHelper;
-import org.apache.commons.configuration.beanutils.XMLBeanDeclaration;
import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
import org.apache.commons.configuration.tree.DefaultConfigurationNode;
import org.apache.commons.configuration.tree.xpath.XPathExpressionEngine;
@@ -64,6 +63,8 @@
System
.setProperty("java.naming.factory.initial",
"org.apache.commons.configuration.MockStaticMemoryInitialContextFactory");
+ System.setProperty("test_file_xml", "test.xml");
+ System.setProperty("test_file_combine", "testcombine1.xml");
factory = new DefaultConfigurationBuilder();
}
@@ -81,7 +82,7 @@
nd = new DefaultConfigurationNode("optional");
parent.addAttribute(nd);
assertTrue("Attribute optional not recognized", decl.isReservedNode(nd));
- nd = new DefaultConfigurationNode(XMLBeanDeclaration.ATTR_BEAN_CLASS);
+ nd = new DefaultConfigurationNode("config-class");
parent.addAttribute(nd);
assertTrue("Inherited attribute not recognized", decl
.isReservedNode(nd));
@@ -502,8 +503,10 @@
CombinedConfiguration cc = (CombinedConfiguration) factory
.getConfiguration();
+ assertEquals("System property not found", "test.xml",
+ cc.getString("test_file_xml"));
PropertiesConfiguration c1 = (PropertiesConfiguration) cc
- .getConfiguration(0);
+ .getConfiguration(1);
assertTrue(
"Reloading strategy was not set",
c1.getReloadingStrategy() instanceof FileChangedReloadingStrategy);
@@ -516,6 +519,8 @@
.getString("element2/subelement/subsubelement"));
assertEquals("List index not found", "two", xmlConf
.getString("list[0]/item[1]"));
+ assertEquals("Property in combiner file not found", "yellow", cc
+ .getString("/gui/selcolor"));
assertTrue("Delimiter flag was not set", cc
.isDelimiterParsingDisabled());
@@ -534,7 +539,7 @@
assertNotNull("Properties configuration not found", cc
.getConfiguration("properties"));
assertNotNull("XML configuration not found", cc.getConfiguration("xml"));
- assertEquals("Wrong number of contained configs", 3, cc
+ assertEquals("Wrong number of contained configs", 4, cc
.getNumberOfConfigurations());
CombinedConfiguration cc2 = (CombinedConfiguration) cc
Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/beanutils/TestXMLBeanDeclaration.java Thu Jun 8 13:11:29 2006
@@ -77,7 +77,7 @@
{
try
{
- decl = new XMLBeanDeclaration(new HierarchicalConfiguration(),
+ decl = new XMLBeanDeclaration(new HierarchicalConfiguration().configurationAt(null),
(ConfigurationNode) null);
fail("Could init declaration with null node!");
}
Modified: jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml
URL: http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml?rev=412848&r1=412847&r2=412848&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/howto_configurationbuilder.xml Thu Jun 8 13:11:29 2006
@@ -231,6 +231,29 @@
<code>additional</code> section).
</p>
<p>
+ Another useful feature is the built-in support for interpolation (i.e.
+ variable substitution): You can use variables in your configuration
+ definition file that are defined in declared configuration sources. For
+ instance, if the name of a configuration file to be loaded is defined by
+ the system property <code>CONFIG_FILE</code>, you can do something like
+ this:
+ </p>
+ <source><![CDATA[
+<configuration>
+ <!-- Load the system properties -->
+ <system/>
+ <!-- Now load the config file, using a system property as file name -->
+ <properties fileName="${CONFIG_FILE}"/>
+</configuration>
+]]></source>
+ <p>
+ Note that you can refer only to properties that have already been loaded.
+ If you change the order of the <code><system></code> and the
+ <code><properties></code> elements in the example above, an error
+ will occur because the <code>${CONFIG_FILE}</code> variable will then be
+ undefined at the moment it is evaluated.
+ </p>
+ <p>
<strong>The header section</strong>
</p>
<p>
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org