Author: oheger
Date: Tue Dec 26 08:19:07 2006
New Revision: 490321
URL: http://svn.apache.org/viewvc?view=rev&rev=490321
Log:
CONFIGURATION-192: Incorporated lang's StrSubstitutor for variable
interpolation; interpolation has been made more customizable
Added:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
(with props)
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
(with props)
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/TestBaseConfiguration.java
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java?view=diff&rev=490321&r1=490320&r2=490321
==============================================================================
---
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
Tue Dec 26 08:19:07 2006
@@ -28,7 +28,10 @@
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.iterators.FilterIterator;
import org.apache.commons.configuration.event.EventSource;
+import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
import org.apache.commons.lang.BooleanUtils;
+import org.apache.commons.lang.text.StrLookup;
+import org.apache.commons.lang.text.StrSubstitutor;
/**
* <p>Abstract configuration class. Provides basic functionality but does not
@@ -107,6 +110,9 @@
*/
private boolean throwExceptionOnMissing;
+ /** Stores a reference to the object that handles variable interpolation.*/
+ private StrSubstitutor substitutor;
+
/**
* For configurations extending AbstractConfiguration, allow them to change
* the listDelimiter from the default comma (","). This value will be used
@@ -228,6 +234,45 @@
public boolean isThrowExceptionOnMissing()
{
return throwExceptionOnMissing;
+ }
+
+ /**
+ * Returns the object that is responsible for variable interpolation.
+ *
+ * @return the object responsible for variable interpolation
+ * @since 1.4
+ */
+ public synchronized StrSubstitutor getSubstitutor()
+ {
+ if (substitutor == null)
+ {
+ substitutor = new StrSubstitutor(createInterpolator());
+ }
+ return substitutor;
+ }
+
+ /**
+ * Creates the interpolator object that is responsible for variable
+ * interpolation. This method is invoked on first access of the
+ * interpolation features. It creates a new instance of
+ * <code>ConfigurationInterpolator</code> and sets the default lookup
+ * object to an implementation that queries this configuration.
+ *
+ * @return the newly created interpolator object
+ * @since 1.4
+ */
+ protected ConfigurationInterpolator createInterpolator()
+ {
+ ConfigurationInterpolator interpol = new ConfigurationInterpolator();
+ interpol.setDefaultLookup(new StrLookup()
+ {
+ public String lookup(String var)
+ {
+ Object prop = resolveContainerStore(var);
+ return (prop != null) ? prop.toString() : null;
+ }
+ });
+ return interpol;
}
/**
Modified:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/PropertyConverter.java?view=diff&rev=490321&r1=490320&r2=490321
==============================================================================
---
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
Tue Dec 26 08:19:07 2006
@@ -681,111 +681,11 @@
{
if (value instanceof String)
{
- return interpolateHelper((String) value, null, config);
+ return config.getSubstitutor().replace((String) value);
}
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();
}
}
Added:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java?view=auto&rev=490321
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
(added)
+++
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
Tue Dec 26 08:19:07 2006
@@ -0,0 +1,317 @@
+/*
+ * 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.
+ */
+package org.apache.commons.configuration.interpol;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.lang.text.StrLookup;
+
+/**
+ * <p>
+ * A class that handles interpolation (variable substitution) for configuration
+ * objects.
+ * </p>
+ * <p>
+ * Each instance of <code>AbstractConfiguration</code> is associated with an
+ * object of this class. Each interpolation tasks are delegated to this object.
+ * </p>
+ * <p>
+ * <code>ConfigurationInterpolator</code> works together with the
+ * <code>StrSubstitutor</code> class from <a
+ * href="http://jakarta.apache.org/commons/lang">Commons Lang</a>. By extending
+ * <code>StrLookup</code> it is able to provide values for variables that
+ * appear in expressions.
+ * </p>
+ * <p>
+ * The basic idea of this class is that it can maintain a set of primitive
+ * <code>StrLookup</code> objects, each of which are identified by a special
+ * prefix. The variables to be processed have the form
+ * <code>${prefix:name}</code>. <code>ConfigurationInterpolator</code> will
+ * extract the prefix and determine, which primitive lookup object is
registered
+ * for it. Then the name of the variable is passed to this object to obtain the
+ * actual value. It is also possible to define a default lookup object, which
+ * will be used for variables that do not have a prefix.
+ * </p>
+ * <p>
+ * When a new instance of this class is created it is initialized with a
default
+ * set of primitive lookup objects. This set can be customized using the static
+ * methods <code>registerGlobalLookup()</code> and
+ * <code>deregisterGlobalLookup()</code>. Per default it contains the
+ * following standard lookup objects:
+ * </p>
+ * <p>
+ * <table border="1">
+ * <tr>
+ * <th>Prefix</th>
+ * <th>Lookup object</th>
+ * </tr>
+ * <tr>
+ * <td valign="top">sys</td>
+ * <td>With this prefix a lookup object is associated that is able to resolve
+ * system properties.</td>
+ * </tr>
+ * </table>
+ * </p>
+ * <p>
+ * After an instance has been created the current set of lookup objects can be
+ * modified using the <code>registerLookup()</code> and
+ * <code>deregisterLookup()</code> methods. The default lookup object (that is
+ * invoked for variables without a prefix) can be set with the
+ * <code>setDefaultLookup()</code> method. (If a
+ * <code>ConfigurationInterpolator</code> instance is created by a
+ * configuration object, this lookup points to the configuration itself, so
that
+ * variables are resolved using the configuration's properties. This ensures
+ * backward compatibility to earlier version of Commons Configuration.)
+ * </p>
+ * <p>
+ * Implementation node: Instances of this class are not thread-safe related to
+ * modifications of their current set of registered lookup objects. It is
+ * intended that each instance is associated with a single
+ * <code>Configuration</conde>
+ * object and used for its interpolation tasks.</p>
+ *
+ * @author Oliver Heger
+ * @version $Id$
+ * @since 1.4
+ * @author <a
+ *
href="http://jakarta.apache.org/commons/configuration/team-list.html">Commons
+ * Configuration team</a>
+ */
+public class ConfigurationInterpolator extends StrLookup
+{
+ /**
+ * Constant for the prefix of the standard lookup object for resolving
+ * system properties.
+ */
+ public static final String PREFIX_SYSPROPERTIES = "sys";
+
+ /** Constant for the prefix separator. */
+ private static final char PREFIX_SEPARATOR = ':';
+
+ /** A map with the globally registered lookup objects. */
+ private static Map globalLookups;
+
+ /** A map with the locally registered lookup objects. */
+ private Map localLookups;
+
+ /** Stores the default lookup object. */
+ private StrLookup defaultLookup;
+
+ /**
+ * Creates a new instance of <code>ConfigurationInterpolator</code>.
+ */
+ public ConfigurationInterpolator()
+ {
+ synchronized (globalLookups)
+ {
+ localLookups = new HashMap(globalLookups);
+ }
+ }
+
+ /**
+ * Registers the given lookup object for the specified prefix globally.
This
+ * means that all instances that are created later will use this lookup
+ * object for this prefix. If for this prefix a lookup object is already
+ * registered, the new lookup object will replace the old one. Note that
the
+ * lookup objects registered here will be shared between multiple clients.
+ * So they should be thread-safe.
+ *
+ * @param prefix the variable prefix (must not be <b>null</b>)
+ * @param lookup the lookup object to be used for this prefix (must not be
+ * <b>null</b>)
+ */
+ public static void registerGlobalLookup(String prefix, StrLookup lookup)
+ {
+ if (prefix == null)
+ {
+ throw new IllegalArgumentException(
+ "Prefix for lookup object must not be null!");
+ }
+ if (lookup == null)
+ {
+ throw new IllegalArgumentException(
+ "Lookup object must not be null!");
+ }
+ synchronized (globalLookups)
+ {
+ globalLookups.put(prefix, lookup);
+ }
+ }
+
+ /**
+ * Deregisters the global lookup object for the specified prefix. This
means
+ * that this lookup object won't be available for later created instances
+ * any more. For already existing instances this operation does not have
any
+ * impact.
+ *
+ * @param prefix the variable prefix
+ * @return a flag whether for this prefix a lookup object had been
+ * registered
+ */
+ public static boolean deregisterGlobalLookup(String prefix)
+ {
+ synchronized (globalLookups)
+ {
+ return globalLookups.remove(prefix) != null;
+ }
+ }
+
+ /**
+ * Registers the given lookup object for the specified prefix at this
+ * instance. From now on this lookup object will be used for variables that
+ * have the specified prefix.
+ *
+ * @param prefix the variable prefix (must not be <b>null</b>)
+ * @param lookup the lookup object to be used for this prefix (must not be
+ * <b>null</b>)
+ */
+ public void registerLookup(String prefix, StrLookup lookup)
+ {
+ if (prefix == null)
+ {
+ throw new IllegalArgumentException(
+ "Prefix for lookup object must not be null!");
+ }
+ if (lookup == null)
+ {
+ throw new IllegalArgumentException(
+ "Lookup object must not be null!");
+ }
+ localLookups.put(prefix, lookup);
+ }
+
+ /**
+ * Deregisters the lookup object for the specified prefix at this instance.
+ * It will be removed from this instance.
+ *
+ * @param prefix the variable prefix
+ * @return a flag whether for this prefix a lookup object had been
+ * registered
+ */
+ public boolean deregisterLookup(String prefix)
+ {
+ return localLookups.remove(prefix) != null;
+ }
+
+ /**
+ * Returns a set with the prefixes, for which lookup objects are registered
+ * at this instance. This means that variables with these prefixes can be
+ * processed.
+ *
+ * @return a set with the registered variable prefixes
+ */
+ public Set prefixSet()
+ {
+ return localLookups.keySet();
+ }
+
+ /**
+ * Returns the default lookup object.
+ *
+ * @return the default lookup object
+ */
+ public StrLookup getDefaultLookup()
+ {
+ return defaultLookup;
+ }
+
+ /**
+ * Sets the default lookup object. This lookup object will be used for all
+ * variables without a special prefix. If it is set to <b>null</b>, such
+ * variables won't be processed.
+ *
+ * @param defaultLookup the new default lookup object
+ */
+ public void setDefaultLookup(StrLookup defaultLookup)
+ {
+ this.defaultLookup = defaultLookup;
+ }
+
+ /**
+ * Resolves the specified variable. This implementation will try to extract
+ * a variable prefix from the given variable name (the first colon (':') is
+ * used as prefix separator). It then passes the name of the variable with
+ * the prefix stripped to the lookup object registered for this prefix. If
+ * no prefix can be found, the default lookup object will be used.
+ *
+ * @param var the name of the variable whose value is to be looked up
+ * @return the value of this variable or <b>null</b> if it cannot be
+ * resolved
+ */
+ public String lookup(String var)
+ {
+ if (var == null)
+ {
+ return null;
+ }
+
+ int prefixPos = var.indexOf(PREFIX_SEPARATOR);
+ if (prefixPos < 0)
+ {
+ return fetchNoPrefixLookup().lookup(var);
+ }
+ else
+ {
+ String prefix = var.substring(0, prefixPos);
+ String name = var.substring(prefixPos + 1);
+ return fetchLookupForPrefix(prefix).lookup(name);
+ }
+ }
+
+ /**
+ * Returns the lookup object to be used for variables without a prefix.
This
+ * implementation will check whether a default lookup object was set. If
+ * this is the case, it will be returned. Otherwise a <b>null</b> lookup
+ * object will be returned.
+ *
+ * @return the lookup object to be used for variables without a prefix
+ */
+ protected StrLookup fetchNoPrefixLookup()
+ {
+ return (getDefaultLookup() != null) ? getDefaultLookup() : StrLookup
+ .noneLookup();
+ }
+
+ /**
+ * Obtains the lookup object for the specified prefix. This method is
called
+ * by the <code>lookup()</code> method. This implementation will check
+ * whether a lookup object is registered for the given prefix. If not, a
+ * <b>null</b> lookup object will be returned.
+ *
+ * @param prefix the prefix
+ * @return the lookup object to be used for this prefix
+ */
+ protected StrLookup fetchLookupForPrefix(String prefix)
+ {
+ StrLookup lookup = (StrLookup) localLookups.get(prefix);
+ if (lookup == null)
+ {
+ lookup = StrLookup.noneLookup();
+ }
+ return lookup;
+ }
+
+ // static initializer, sets up the map with the standard lookups
+ static
+ {
+ globalLookups = new HashMap();
+ globalLookups.put(PREFIX_SYSPROPERTIES, StrLookup
+ .systemPropertiesLookup());
+ }
+}
Propchange:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
jakarta/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/interpol/ConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java?view=diff&rev=490321&r1=490320&r2=490321
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java
(original)
+++
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java
Tue Dec 26 08:19:07 2006
@@ -674,6 +674,48 @@
assertEquals("Wrong int property", 42, subset.getInt("b"));
}
+ /**
+ * Tests interpolation when the referred property is not found.
+ */
+ public void testInterpolationUnknownProperty()
+ {
+ config.addProperty("test.interpol", "${unknown.property}");
+ assertEquals("Wrong interpolated unknown property",
+ "${unknown.property}", config.getString("test.interpol"));
+ }
+
+ /**
+ * Tests interpolation of system properties.
+ */
+ public void testInterpolationSystemProperties()
+ {
+ String[] sysProperties =
+ { "java.version", "java.vendor", "os.name", "java.class.path" };
+ for (int i = 0; i < sysProperties.length; i++)
+ {
+ config.addProperty("prop" + i, "${sys:" + sysProperties[i] + "}");
+ }
+
+ for (int i = 0; i < sysProperties.length; i++)
+ {
+ assertEquals("Wrong value for system property " + sysProperties[i],
+ System.getProperty(sysProperties[i]), config
+ .getString("prop" + i));
+ }
+ }
+
+ /**
+ * Tests whether a variable can be escaped, so that it won't be
+ * interpolated.
+ */
+ public void testInterpolationEscaped()
+ {
+ config.addProperty("var", "x");
+ config.addProperty("escVar", "Use the variable $${${var}}.");
+ assertEquals("Wrong escaped variable", "Use the variable ${x}.", config
+ .getString("escVar"));
+ }
+
public void testGetHexadecimalValue()
{
config.setProperty("number", "0xFF");
Added:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
URL:
http://svn.apache.org/viewvc/jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java?view=auto&rev=490321
==============================================================================
---
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
(added)
+++
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
Tue Dec 26 08:19:07 2006
@@ -0,0 +1,326 @@
+/*
+ * 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.
+ */
+package org.apache.commons.configuration.interpol;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.lang.text.StrLookup;
+
+import junit.framework.TestCase;
+
+/**
+ * Test class for ConfigurationInterpolator.
+ *
+ * @version $Id$
+ */
+public class TestConfigurationInterpolator extends TestCase
+{
+ /** Constant for a test variable prefix. */
+ private static final String TEST_PREFIX = "prefix";
+
+ /** Constant for a test variable name. */
+ private static final String TEST_NAME = "varname";
+
+ /** Constant for the value of the test variable. */
+ private static final String TEST_VALUE = "TestVariableValue";
+
+ /** Stores the object to be tested. */
+ private ConfigurationInterpolator interpolator;
+
+ protected void setUp() throws Exception
+ {
+ super.setUp();
+ interpolator = new ConfigurationInterpolator();
+ }
+
+ /**
+ * Cleans the test environment. Deregisters the test lookup object if
+ * necessary.
+ */
+ protected void tearDown() throws Exception
+ {
+ ConfigurationInterpolator.deregisterGlobalLookup(TEST_PREFIX);
+ }
+
+ /**
+ * Tests creating an instance. Does it contain some predefined lookups?
+ */
+ public void testInit()
+ {
+ assertNull("A default lookup is set", interpolator.getDefaultLookup());
+ assertFalse("No predefined lookups",
interpolator.prefixSet().isEmpty());
+ }
+
+ /**
+ * Tries to register a global lookup for a null prefix. This should cause
an
+ * exception.
+ */
+ public void testRegisterGlobalLookupNullPrefix()
+ {
+ try
+ {
+ ConfigurationInterpolator.registerGlobalLookup(null, StrLookup
+ .noneLookup());
+ fail("Could register global lookup with null prefix!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tries to register a global null lookup. This should cause an exception.
+ */
+ public void testRegisterGlobalLookupNull()
+ {
+ try
+ {
+ ConfigurationInterpolator.registerGlobalLookup(TEST_PREFIX, null);
+ fail("Could register global null lookup!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tests registering a global lookup object. This lookup object should then
+ * be available for instances created later on.
+ */
+ public void testRegisterGlobalLookup()
+ {
+ ConfigurationInterpolator.registerGlobalLookup(TEST_PREFIX, StrLookup
+ .noneLookup());
+ ConfigurationInterpolator int2 = new ConfigurationInterpolator();
+ assertTrue("No lookup registered for test prefix", int2.prefixSet()
+ .contains(TEST_PREFIX));
+ assertFalse("Existing instance was modified", interpolator.prefixSet()
+ .contains(TEST_PREFIX));
+ }
+
+ /**
+ * Tests deregistering a global lookup object.
+ */
+ public void testDeregisterGlobalLookup()
+ {
+ ConfigurationInterpolator.registerGlobalLookup(TEST_PREFIX, StrLookup
+ .noneLookup());
+ assertTrue("Lookup could not be deregistered",
+ ConfigurationInterpolator.deregisterGlobalLookup(TEST_PREFIX));
+ ConfigurationInterpolator int2 = new ConfigurationInterpolator();
+ assertFalse("Deregistered lookup still available", int2.prefixSet()
+ .contains(TEST_PREFIX));
+ }
+
+ /**
+ * Tests deregistering an unknown lookup.
+ */
+ public void testDeregisterGlobalLookupNonExisting()
+ {
+ assertFalse("Could deregister unknown global lookup",
+ ConfigurationInterpolator.deregisterGlobalLookup(TEST_PREFIX));
+ }
+
+ /**
+ * Tests registering a lookup object at an instance.
+ */
+ public void testRegisterLookup()
+ {
+ int cnt = interpolator.prefixSet().size();
+ interpolator.registerLookup(TEST_PREFIX, StrLookup.noneLookup());
+ assertTrue("New lookup not registered", interpolator.prefixSet()
+ .contains(TEST_PREFIX));
+ assertEquals("Wrong number of registered lookups", cnt + 1,
+ interpolator.prefixSet().size());
+ ConfigurationInterpolator int2 = new ConfigurationInterpolator();
+ assertFalse("Local registration has global impact", int2.prefixSet()
+ .contains(TEST_PREFIX));
+ }
+
+ /**
+ * Tests registering a null lookup object. This should cause an exception.
+ */
+ public void testRegisterLookupNull()
+ {
+ try
+ {
+ interpolator.registerLookup(TEST_PREFIX, null);
+ fail("Could register null lookup!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tests registering a lookup object for an undefined prefix. This should
+ * cause an exception.
+ */
+ public void testRegisterLookupNullPrefix()
+ {
+ try
+ {
+ interpolator.registerLookup(null, StrLookup.noneLookup());
+ fail("Could register lookup for null prefix!");
+ }
+ catch (IllegalArgumentException iex)
+ {
+ // ok
+ }
+ }
+
+ /**
+ * Tests deregistering a local lookup object.
+ */
+ public void testDeregisterLookup()
+ {
+ interpolator.registerLookup(TEST_PREFIX, StrLookup.noneLookup());
+ assertTrue("Derigstration not successfull", interpolator
+ .deregisterLookup(TEST_PREFIX));
+ assertFalse("Deregistered prefix still contained", interpolator
+ .prefixSet().contains(TEST_PREFIX));
+ }
+
+ /**
+ * Tests deregistering an unknown lookup object.
+ */
+ public void testDeregisterLookupNonExisting()
+ {
+ assertFalse("Could deregister unknown lookup", interpolator
+ .deregisterLookup(TEST_PREFIX));
+ }
+
+ /**
+ * Tests whether a variable can be resolved using the associated lookup
+ * object. The lookup is identified by the variable's prefix.
+ */
+ public void testLookupWithPrefix()
+ {
+ interpolator.registerLookup(TEST_PREFIX, setUpTestLookup());
+ assertEquals("Wrong variable value", TEST_VALUE, interpolator
+ .lookup(TEST_PREFIX + ':' + TEST_NAME));
+ }
+
+ /**
+ * Tests the behavior of the lookup method for variables with an unknown
+ * prefix. These variables should not be resolved.
+ */
+ public void testLookupWithUnknownPrefix()
+ {
+ interpolator.registerLookup(TEST_PREFIX, setUpTestLookup());
+ assertNull("Variable could be resolved", interpolator
+ .lookup("UnknownPrefix:" + TEST_NAME));
+ assertNull("Variable with empty prefix could be resolved", interpolator
+ .lookup(":" + TEST_NAME));
+ }
+
+ /**
+ * Tests looking up a variable without a prefix. This should trigger the
+ * default lookup object.
+ */
+ public void testLookupDefault()
+ {
+ interpolator.setDefaultLookup(setUpTestLookup());
+ assertEquals("Wrong variable value", TEST_VALUE, interpolator
+ .lookup(TEST_NAME));
+ }
+
+ /**
+ * Tests looking up a variable without a prefix when no default lookup is
+ * specified. Result should be null in this case.
+ */
+ public void testLookupNoDefault()
+ {
+ assertNull("Variable could be resolved",
interpolator.lookup(TEST_NAME));
+ }
+
+ /**
+ * Tests the empty variable prefix. This is a special case, but legal.
+ */
+ public void testLookupEmptyPrefix()
+ {
+ interpolator.registerLookup("", setUpTestLookup());
+ assertEquals("Wrong variable value", TEST_VALUE, interpolator
+ .lookup(":" + TEST_NAME));
+ }
+
+ /**
+ * Tests an empty variable name.
+ */
+ public void testLookupEmptyVarName()
+ {
+ Map map = new HashMap();
+ map.put("", TEST_VALUE);
+ interpolator.registerLookup(TEST_PREFIX, StrLookup.mapLookup(map));
+ assertEquals("Wrong variable value", TEST_VALUE, interpolator
+ .lookup(TEST_PREFIX + ":"));
+ }
+
+ /**
+ * Tests an empty variable name without a prefix.
+ */
+ public void testLookupDefaultEmptyVarName()
+ {
+ Map map = new HashMap();
+ map.put("", TEST_VALUE);
+ interpolator.setDefaultLookup(StrLookup.mapLookup(map));
+ assertEquals("Wrong variable value", TEST_VALUE, interpolator
+ .lookup(""));
+ }
+
+ /**
+ * Tests looking up a null variable. Result shoult be null, too.
+ */
+ public void testLookupNull()
+ {
+ assertNull("Could resolve null variable", interpolator.lookup(null));
+ }
+
+ /**
+ * Creates a lookup object that can resolve the test variable.
+ *
+ * @return the test lookup object
+ */
+ private StrLookup setUpTestLookup()
+ {
+ Map map = new HashMap();
+ map.put(TEST_NAME, TEST_VALUE);
+ return StrLookup.mapLookup(map);
+ }
+
+ /**
+ * Tests whether system properties can be correctly resolved.
+ */
+ public void testLookupSysProperties()
+ {
+ Properties sysProps = System.getProperties();
+ for (Iterator it = sysProps.keySet().iterator(); it.hasNext();)
+ {
+ String key = (String) it.next();
+ assertEquals("Wrong value for system property " + key, sysProps
+ .getProperty(key), interpolator
+ .lookup(ConfigurationInterpolator.PREFIX_SYSPROPERTIES
+ + ":" + key));
+ }
+ }
+}
Propchange:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:keywords = Date Author Id Revision HeadURL
Propchange:
jakarta/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/interpol/TestConfigurationInterpolator.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]