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/02/22 20:43:23 UTC
svn commit: r379859 - in /jakarta/commons/proper/configuration/trunk:
src/java/org/apache/commons/configuration/
src/test/org/apache/commons/configuration/ xdocs/
Author: oheger
Date: Wed Feb 22 11:43:20 2006
New Revision: 379859
URL: http://svn.apache.org/viewcvs?rev=379859&view=rev
Log:
Moved implementation of interpolation features from AbstractConfiguration to PropertiesConverter, so that it can be accessed from other objects, too (namely bean declaration classes)
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestPropertyConverter.java
jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java?rev=379859&r1=379858&r2=379859&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java Wed Feb 22 11:43:20 2006
@@ -219,7 +219,8 @@
*/
protected String interpolate(String base)
{
- return interpolateHelper(base, null);
+ Object result = interpolate((Object) base);
+ return (result == null) ? null : result.toString();
}
/**
@@ -231,14 +232,7 @@
*/
protected Object interpolate(Object value)
{
- if (value instanceof String)
- {
- return interpolate((String) value);
- }
- else
- {
- return value;
- }
+ return PropertyConverter.interpolate(value, this);
}
/**
@@ -253,82 +247,13 @@
* subsequent interpolated variables are added afterward.
*
* @return the string with the interpolation taken care of
+ * @deprecated Interpolation is now handled by
+ * <code>{@link PropertyConverter}</code>; this method will no longer be
+ * called
*/
protected String interpolateHelper(String base, List priorVariables)
{
- if (base == null)
- {
- return null;
- }
-
- // on the first call initialize priorVariables
- // and add base as the first element
- if (priorVariables == null)
- {
- priorVariables = new ArrayList();
- priorVariables.add(base);
- }
-
- int begin = -1;
- int end = -1;
- int prec = 0 - END_TOKEN.length();
- StringBuffer result = new StringBuffer();
-
- // FIXME: we should probably allow the escaping of the start token
- while (((begin = base.indexOf(START_TOKEN, prec + END_TOKEN.length())) > -1)
- && ((end = base.indexOf(END_TOKEN, begin)) > -1))
- {
- result.append(base.substring(prec + END_TOKEN.length(), begin));
- String variable = base.substring(begin + START_TOKEN.length(), end);
-
- // if we've got a loop, create a useful exception message and throw
- if (priorVariables.contains(variable))
- {
- String initialBase = priorVariables.remove(0).toString();
- priorVariables.add(variable);
- StringBuffer priorVariableSb = new StringBuffer();
-
- // create a nice trace of interpolated variables like so:
- // var1->var2->var3
- for (Iterator it = priorVariables.iterator(); it.hasNext();)
- {
- priorVariableSb.append(it.next());
- if (it.hasNext())
- {
- priorVariableSb.append("->");
- }
- }
-
- throw new IllegalStateException("infinite loop in property interpolation of " + initialBase + ": "
- + priorVariableSb.toString());
- }
- // otherwise, add this variable to the interpolation list.
- else
- {
- priorVariables.add(variable);
- }
-
- Object value = resolveContainerStore(variable);
- if (value != null)
- {
- result.append(interpolateHelper(value.toString(), priorVariables));
-
- // pop the interpolated variable off the stack
- // this maintains priorVariables correctness for
- // properties with multiple interpolations, e.g.
- // prop.name=${some.other.prop1}/blahblah/${some.other.prop2}
- priorVariables.remove(priorVariables.size() - 1);
- }
- else
- {
- //variable not defined - so put it back in the value
- result.append(START_TOKEN).append(variable).append(END_TOKEN);
- }
-
- prec = end;
- }
- result.append(base.substring(prec + END_TOKEN.length(), base.length()));
- return result.toString();
+ return base; // just a dummy implementation
}
/**
Modified: jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java?rev=379859&r1=379858&r2=379859&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java Wed Feb 22 11:43:20 2006
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2005 The Apache Software Foundation.
+ * Copyright 2004-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
@@ -714,5 +714,127 @@
{
return new SingletonIterator(value);
}
+ }
+
+ /**
+ * Performs interpolation of the specified value. This method checks if the
+ * given value contains variables of the form <code>${...}</code>. If
+ * this is the case, all occurrances will be substituted by their current
+ * values.
+ *
+ * @param value the value to be interpolated
+ * @param config the current configuration object
+ * @return the interpolated value
+ */
+ public static Object interpolate(Object value, AbstractConfiguration config)
+ {
+ if (value instanceof String)
+ {
+ return interpolateHelper((String) value, null, config);
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ /**
+ * Recursive handler for multple levels of interpolation. This will be
+ * replaced when Commons Lang provides an interpolation feature. When called
+ * the first time, priorVariables should be null.
+ *
+ * @param base string with the ${key} variables
+ * @param priorVariables serves two purposes: to allow checking for loops,
+ * and creating a meaningful exception message should a loop occur. It's
+ * 0'th element will be set to the value of base from the first call. All
+ * subsequent interpolated variables are added afterward.
+ * @param config the current configuration
+ * @return the string with the interpolation taken care of
+ */
+ private static String interpolateHelper(String base, List priorVariables,
+ AbstractConfiguration config)
+ {
+ if (base == null)
+ {
+ return null;
+ }
+
+ // on the first call initialize priorVariables
+ // and add base as the first element
+ if (priorVariables == null)
+ {
+ priorVariables = new ArrayList();
+ priorVariables.add(base);
+ }
+
+ int begin = -1;
+ int end = -1;
+ int prec = 0 - AbstractConfiguration.END_TOKEN.length();
+ StringBuffer result = new StringBuffer();
+
+ // FIXME: we should probably allow the escaping of the start token
+ while (((begin = base.indexOf(AbstractConfiguration.START_TOKEN, prec
+ + AbstractConfiguration.END_TOKEN.length())) > -1)
+ && ((end = base.indexOf(AbstractConfiguration.END_TOKEN, begin)) > -1))
+ {
+ result.append(base.substring(prec
+ + AbstractConfiguration.END_TOKEN.length(), begin));
+ String variable = base.substring(begin
+ + AbstractConfiguration.START_TOKEN.length(), end);
+
+ // if we've got a loop, create a useful exception message and throw
+ if (priorVariables.contains(variable))
+ {
+ String initialBase = priorVariables.remove(0).toString();
+ priorVariables.add(variable);
+ StringBuffer priorVariableSb = new StringBuffer();
+
+ // create a nice trace of interpolated variables like so:
+ // var1->var2->var3
+ for (Iterator it = priorVariables.iterator(); it.hasNext();)
+ {
+ priorVariableSb.append(it.next());
+ if (it.hasNext())
+ {
+ priorVariableSb.append("->");
+ }
+ }
+
+ throw new IllegalStateException(
+ "infinite loop in property interpolation of "
+ + initialBase + ": "
+ + priorVariableSb.toString());
+ }
+ // otherwise, add this variable to the interpolation list.
+ else
+ {
+ priorVariables.add(variable);
+ }
+
+ Object value = config.resolveContainerStore(variable);
+ if (value != null)
+ {
+ result.append(interpolateHelper(value.toString(),
+ priorVariables, config));
+
+ // pop the interpolated variable off the stack
+ // this maintains priorVariables correctness for
+ // properties with multiple interpolations, e.g.
+ // prop.name=${some.other.prop1}/blahblah/${some.other.prop2}
+ priorVariables.remove(priorVariables.size() - 1);
+ }
+ else
+ {
+ // variable not defined - so put it back in the value
+ result.append(AbstractConfiguration.START_TOKEN);
+ result.append(variable);
+ result.append(AbstractConfiguration.END_TOKEN);
+ }
+
+ prec = end;
+ }
+ result.append(base.substring(prec
+ + AbstractConfiguration.END_TOKEN.length(), base.length()));
+ return result.toString();
}
}
Modified: jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestPropertyConverter.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestPropertyConverter.java?rev=379859&r1=379858&r2=379859&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestPropertyConverter.java (original)
+++ jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestPropertyConverter.java Wed Feb 22 11:43:20 2006
@@ -1,3 +1,18 @@
+/*
+ * Copyright 2001-2006 The Apache Software Foundation.
+ *
+ * Licensed 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.
+ */
package org.apache.commons.configuration;
import java.util.List;
@@ -6,6 +21,8 @@
import junit.framework.TestCase;
/**
+ * Test class for PropertyConverter.
+ *
* @author Emmanuel Bourg
* @version $Revision$, $Date$
*/
@@ -71,4 +88,79 @@
assertEquals("3rd element", new Integer(3), it.next());
}
+ /**
+ * Tests the interpolation features.
+ */
+ public void testInterpolateString()
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("animal", "quick brown fox");
+ config.addProperty("target", "lazy dog");
+ assertEquals("Wrong interpolation",
+ "The quick brown fox jumps over the lazy dog.",
+ PropertyConverter.interpolate(
+ "The ${animal} jumps over the ${target}.", config));
+ }
+
+ /**
+ * Tests interpolation of an object. Here nothing should be substituted.
+ */
+ public void testInterpolateObject()
+ {
+ assertEquals("Object was not correctly interpolated", new Integer(42),
+ PropertyConverter.interpolate(new Integer(42),
+ new PropertiesConfiguration()));
+ }
+
+ /**
+ * Tests complex interpolation where the variables' values contain in turn
+ * other variables.
+ */
+ public void testInterpolateRecursive()
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("animal", "${animal_attr} fox");
+ config.addProperty("target", "${target_attr} dog");
+ config.addProperty("animal_attr", "quick brown");
+ config.addProperty("target_attr", "lazy");
+ assertEquals("Wrong complex interpolation",
+ "The quick brown fox jumps over the lazy dog.",
+ PropertyConverter.interpolate(
+ "The ${animal} jumps over the ${target}.", config));
+ }
+
+ /**
+ * Tests an interpolation that leads to a cycle. This should throw an
+ * exception.
+ */
+ public void testCyclicInterpolation()
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("animal", "${animal_attr} ${species}");
+ config.addProperty("animal_attr", "quick brown");
+ config.addProperty("species", "${animal}");
+ try
+ {
+ PropertyConverter.interpolate("This is a ${animal}", config);
+ fail("Cyclic interpolation was not detected!");
+ }
+ catch (IllegalStateException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tests interpolation if a variable is unknown. Then the variable won't be
+ * substituted.
+ */
+ public void testInterpolationUnknownVariable()
+ {
+ PropertiesConfiguration config = new PropertiesConfiguration();
+ config.addProperty("animal", "quick brown fox");
+ assertEquals("Wrong interpolation",
+ "The quick brown fox jumps over ${target}.", PropertyConverter
+ .interpolate("The ${animal} jumps over ${target}.",
+ config));
+ }
}
Modified: jakarta/commons/proper/configuration/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/configuration/trunk/xdocs/changes.xml?rev=379859&r1=379858&r2=379859&view=diff
==============================================================================
--- jakarta/commons/proper/configuration/trunk/xdocs/changes.xml (original)
+++ jakarta/commons/proper/configuration/trunk/xdocs/changes.xml Wed Feb 22 11:43:20 2006
@@ -1,6 +1,6 @@
<?xml version="1.0"?>
<!--
- Copyright 2004-2005 The Apache Software Foundation
+ Copyright 2004-2006 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -23,6 +23,12 @@
<body>
<release version="1.3-SNAPSHOT" date="in SVN">
+ <action dev="oheger" type="update">
+ The implementation of the interpolation features have been extracted out
+ off AbstractConfiguration and moved to PropertyConverter. The
+ interpolateHelper() method of AbstractConfiguration is now deprectated
+ and will not be called any more during interpolation.
+ </action>
<action dev="oheger" type="add" issue="38075">
A new method configurationsAdd() was added to HierarchicalConfiguration
that provides a convenient way of iterating over complex list-like
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org