You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by oh...@apache.org on 2007/10/25 22:22:35 UTC

svn commit: r588335 - in /commons/proper/configuration/trunk/src: java/org/apache/commons/configuration/ test/org/apache/commons/configuration/

Author: oheger
Date: Thu Oct 25 13:22:35 2007
New Revision: 588335

URL: http://svn.apache.org/viewvc?rev=588335&view=rev
Log:
CONFIGURATION-273: Added a new method interpolatedConfiguration() to AbstractConfiguration, which returns a configuration with all variables substituted by their actual values; tests for interpolation have been refactored into a special test class, so that they can easily be applied to other Configuration implementations.

Added:
    commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java   (with props)
Modified:
    commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
    commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java

Modified: commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java?rev=588335&r1=588334&r2=588335&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/java/org/apache/commons/configuration/AbstractConfiguration.java Thu Oct 25 13:22:35 2007
@@ -1239,4 +1239,37 @@
             }
         }
     }
+
+    /**
+     * Returns a configuration with the same content as this configuration, but
+     * with all variables replaced by their actual values. This method tries to
+     * clone the configuration and then perform interpolation on all properties.
+     * So property values of the form <code>${var}</code> will be resolved as
+     * far as possible (if a variable cannot be resolved, it remains unchanged).
+     * This operation is useful if the content of a configuration is to be
+     * exported or processed by an external component that does not support
+     * variable interpolation.
+     *
+     * @return a configuration with all variables interpolated
+     * @throws ConfigurationRuntimeException if this configuration cannot be
+     * cloned
+     * @since 1.5
+     */
+    public Configuration interpolatedConfiguration()
+    {
+        // first clone this configuration
+        AbstractConfiguration c = (AbstractConfiguration) ConfigurationUtils
+                .cloneConfiguration(this);
+
+        // now perform interpolation
+        c.setDelimiterParsingDisabled(true);
+        for (Iterator it = getKeys(); it.hasNext();)
+        {
+            String key = (String) it.next();
+            c.setProperty(key, getList(key));
+        }
+
+        c.setDelimiterParsingDisabled(isDelimiterParsingDisabled());
+        return c;
+    }
 }

Added: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java?rev=588335&view=auto
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java (added)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java Thu Oct 25 13:22:35 2007
@@ -0,0 +1,253 @@
+/*
+ * 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;
+
+import java.awt.event.KeyEvent;
+import java.util.List;
+
+import junit.framework.Assert;
+
+import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
+import org.apache.commons.lang.text.StrLookup;
+
+/**
+ * A helper class that defines a bunch of tests related to variable
+ * interpolation. It can be used for running these tests on different
+ * configuration implementations.
+ *
+ * @author Oliver Heger
+ * @version $Id$
+ */
+public class InterpolationTestHelper
+{
+    /**
+     * Tests basic interpolation facilities of the specified configuration.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolation(Configuration config)
+    {
+        config.setProperty("applicationRoot", "/home/applicationRoot");
+        config.setProperty("db", "${applicationRoot}/db/hypersonic");
+        String unInterpolatedValue = "${applicationRoot2}/db/hypersonic";
+        config.setProperty("dbFailedInterpolate", unInterpolatedValue);
+        String dbProp = "/home/applicationRoot/db/hypersonic";
+
+        Assert.assertEquals("Checking interpolated variable", dbProp, config
+                .getString("db"));
+        Assert.assertEquals("lookup fails, leave variable as is", config
+                .getString("dbFailedInterpolate"), unInterpolatedValue);
+
+        config.setProperty("arrayInt", "${applicationRoot}/1");
+        String[] arrayInt = config.getStringArray("arrayInt");
+        Assert.assertEquals("check first entry was interpolated",
+                "/home/applicationRoot/1", arrayInt[0]);
+
+        config.addProperty("path", "/temp,C:\\Temp,/usr/local/tmp");
+        config.setProperty("path.current", "${path}");
+        Assert.assertEquals("Interpolation with multi-valued property",
+                "/temp", config.getString("path.current"));
+    }
+
+    /**
+     * Tests an interpolation over multiple levels (i.e. the replacement of a
+     * variable is another variable and so on).
+     *
+     * @param config the configuration to test
+     */
+    public static void testMultipleInterpolation(Configuration config)
+    {
+        config.setProperty("test.base-level", "/base-level");
+        config
+                .setProperty("test.first-level",
+                        "${test.base-level}/first-level");
+        config.setProperty("test.second-level",
+                "${test.first-level}/second-level");
+        config.setProperty("test.third-level",
+                "${test.second-level}/third-level");
+
+        String expectedValue = "/base-level/first-level/second-level/third-level";
+
+        Assert
+                .assertEquals(config.getString("test.third-level"),
+                        expectedValue);
+    }
+
+    /**
+     * Tests an invalid interpolation that results in an infinite loop. This
+     * loop should be detected and an exception should be thrown.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationLoop(Configuration config)
+    {
+        config.setProperty("test.a", "${test.b}");
+        config.setProperty("test.b", "${test.a}");
+
+        try
+        {
+            config.getString("test.a");
+            Assert
+                    .fail("IllegalStateException should have been thrown for looped property references");
+        }
+        catch (IllegalStateException e)
+        {
+            // ok
+        }
+
+    }
+
+    /**
+     * Tests interpolation when a subset configuration is involved.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationSubset(Configuration config)
+    {
+        config.addProperty("test.a", new Integer(42));
+        config.addProperty("test.b", "${test.a}");
+        Assert.assertEquals("Wrong interpolated value", 42, config
+                .getInt("test.b"));
+        Configuration subset = config.subset("test");
+        Assert.assertEquals("Wrong string property", "42", subset
+                .getString("b"));
+        Assert.assertEquals("Wrong int property", 42, subset.getInt("b"));
+    }
+
+    /**
+     * Tests interpolation when the referred property is not found.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationUnknownProperty(Configuration config)
+    {
+        config.addProperty("test.interpol", "${unknown.property}");
+        Assert.assertEquals("Wrong interpolated unknown property",
+                "${unknown.property}", config.getString("test.interpol"));
+    }
+
+    /**
+     * Tests interpolation of system properties.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationSystemProperties(Configuration config)
+    {
+        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++)
+        {
+            Assert.assertEquals("Wrong value for system property "
+                    + sysProperties[i], System.getProperty(sysProperties[i]),
+                    config.getString("prop" + i));
+        }
+    }
+
+    /**
+     * Tests interpolation of constant values.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationConstants(Configuration config)
+    {
+        config.addProperty("key.code",
+                "${const:java.awt.event.KeyEvent.VK_CANCEL}");
+        Assert.assertEquals("Wrong value of constant variable",
+                KeyEvent.VK_CANCEL, config.getInt("key.code"));
+        Assert.assertEquals("Wrong value when fetching constant from cache",
+                KeyEvent.VK_CANCEL, config.getInt("key.code"));
+    }
+
+    /**
+     * Tests whether a variable can be escaped, so that it won't be
+     * interpolated.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolationEscaped(Configuration config)
+    {
+        config.addProperty("var", "x");
+        config.addProperty("escVar", "Use the variable $${${var}}.");
+        Assert.assertEquals("Wrong escaped variable", "Use the variable ${x}.",
+                config.getString("escVar"));
+    }
+
+    /**
+     * Tests accessing and manipulating the interpolator object.
+     *
+     * @param config the configuration to test
+     */
+    public static void testGetInterpolator(AbstractConfiguration config)
+    {
+        config.addProperty("var", "${echo:testVar}");
+        ConfigurationInterpolator interpol = config.getInterpolator();
+        interpol.registerLookup("echo", new StrLookup()
+        {
+            public String lookup(String varName)
+            {
+                return "Value of variable " + varName;
+            }
+        });
+        Assert.assertEquals("Wrong value of echo variable",
+                "Value of variable testVar", config.getString("var"));
+    }
+
+    /**
+     * Tests obtaining a configuration with all variables replaced by their
+     * actual values.
+     *
+     * @param config the configuration to test
+     */
+    public static void testInterpolatedConfiguration(
+            AbstractConfiguration config)
+    {
+        config.setProperty("applicationRoot", "/home/applicationRoot");
+        config.setProperty("db", "${applicationRoot}/db/hypersonic");
+        config.setProperty("inttest.interpol", "${unknown.property}");
+        config.setProperty("intkey.code",
+                "${const:java.awt.event.KeyEvent.VK_CANCEL}");
+        config.setProperty("inttest.sysprop", "${sys:java.version}");
+        config.setProperty("inttest.numvalue", "3\\,1415");
+        config.setProperty("inttest.value", "${inttest.numvalue}");
+        config.setProperty("inttest.list", "${db}");
+        config.addProperty("inttest.list", "${inttest.value}");
+
+        Configuration c = config.interpolatedConfiguration();
+        Assert.assertEquals("Property not replaced",
+                "/home/applicationRoot/db/hypersonic", c.getProperty("db"));
+        Assert.assertEquals("Const variable not replaced", KeyEvent.VK_CANCEL,
+                c.getInt("intkey.code"));
+        Assert.assertEquals("Sys property not replaced", System
+                .getProperty("java.version"), c.getProperty("inttest.sysprop"));
+        Assert.assertEquals("Delimiter value not replaced", "3,1415", c
+                .getProperty("inttest.value"));
+        List lst = (List) c.getProperty("inttest.list");
+        Assert.assertEquals("Wrong number of list elements", 2, lst.size());
+        Assert.assertEquals("List element 0 not replaced",
+                "/home/applicationRoot/db/hypersonic", lst.get(0));
+        Assert
+                .assertEquals("List element 1 not replaced", "3,1415", lst
+                        .get(1));
+        Assert.assertEquals("Unresolvable variable not found",
+                "${unknown.property}", c.getProperty("inttest.interpol"));
+    }
+}

Propchange: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/InterpolationTestHelper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java
URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java?rev=588335&r1=588334&r2=588335&view=diff
==============================================================================
--- commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java (original)
+++ commons/proper/configuration/trunk/src/test/org/apache/commons/configuration/TestBaseConfiguration.java Thu Oct 25 13:22:35 2007
@@ -17,7 +17,6 @@
 
 package org.apache.commons.configuration;
 
-import java.awt.event.KeyEvent;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
@@ -29,16 +28,14 @@
 import java.util.Set;
 import java.util.StringTokenizer;
 
-import org.apache.commons.collections.set.ListOrderedSet;
-import org.apache.commons.configuration.event.ConfigurationEvent;
-import org.apache.commons.configuration.event.ConfigurationListener;
-import org.apache.commons.configuration.interpol.ConfigurationInterpolator;
-import org.apache.commons.lang.text.StrLookup;
-
 import junit.framework.TestCase;
 import junitx.framework.ListAssert;
 import junitx.framework.ObjectAssert;
 
+import org.apache.commons.collections.set.ListOrderedSet;
+import org.apache.commons.configuration.event.ConfigurationEvent;
+import org.apache.commons.configuration.event.ConfigurationListener;
+
 /**
  * Tests some basic functions of the BaseConfiguration class. Missing keys will
  * throw Exceptions
@@ -601,69 +598,19 @@
         assertFalse(it.hasNext());
     }
 
-    public void testInterpolation() throws Exception
+    public void testInterpolation()
     {
-        config.setProperty("applicationRoot", "/home/applicationRoot");
-        config.setProperty("db", "${applicationRoot}/db/hypersonic");
-        String unInterpolatedValue = "${applicationRoot2}/db/hypersonic";
-        config.setProperty("dbFailedInterpolate", unInterpolatedValue);
-        String dbProp = "/home/applicationRoot/db/hypersonic";
-
-        //construct a new config, using config as the defaults config for it.
-        BaseConfiguration superProp = config;
-
-        assertEquals(
-                "Checking interpolated variable", dbProp,
-                superProp.getString("db"));
-        assertEquals(
-                "lookup fails, leave variable as is",
-                superProp.getString("dbFailedInterpolate"),
-                unInterpolatedValue);
-
-        superProp.setProperty("arrayInt", "${applicationRoot}/1");
-        String[] arrayInt = superProp.getStringArray("arrayInt");
-        assertEquals(
-                "check first entry was interpolated",
-                "/home/applicationRoot/1",
-                arrayInt[0]);
-
-        config.addProperty("path", "/temp,C:\\Temp,/usr/local/tmp");
-        config.setProperty("path.current", "${path}");
-        assertEquals("Interpolation with multi-valued property", "/temp", superProp.getString("path.current"));
+        InterpolationTestHelper.testInterpolation(config);
     }
 
-    public void testMultipleInterpolation() throws Exception
+    public void testMultipleInterpolation()
     {
-        config.setProperty("test.base-level", "/base-level");
-        config.setProperty("test.first-level", "${test.base-level}/first-level");
-        config.setProperty(
-                "test.second-level",
-                "${test.first-level}/second-level");
-        config.setProperty(
-                "test.third-level",
-                "${test.second-level}/third-level");
-
-        String expectedValue =
-                "/base-level/first-level/second-level/third-level";
-
-        assertEquals(config.getString("test.third-level"), expectedValue);
+        InterpolationTestHelper.testMultipleInterpolation(config);
     }
 
-    public void testInterpolationLoop() throws Exception
+    public void testInterpolationLoop()
     {
-        config.setProperty("test.a", "${test.b}");
-        config.setProperty("test.b", "${test.a}");
-
-        try
-        {
-            config.getString("test.a");
-        }
-        catch (IllegalStateException e)
-        {
-            return;
-        }
-
-        fail("IllegalStateException should have been thrown for looped property references");
+        InterpolationTestHelper.testInterpolationLoop(config);
     }
 
     /**
@@ -671,12 +618,7 @@
      */
     public void testInterpolationSubset()
     {
-        config.addProperty("test.a", new Integer(42));
-        config.addProperty("test.b", "${test.a}");
-        assertEquals("Wrong interpolated value", 42, config.getInt("test.b"));
-        Configuration subset = config.subset("test");
-        assertEquals("Wrong string property", "42", subset.getString("b"));
-        assertEquals("Wrong int property", 42, subset.getInt("b"));
+        InterpolationTestHelper.testInterpolationSubset(config);
     }
 
     /**
@@ -684,9 +626,7 @@
      */
     public void testInterpolationUnknownProperty()
     {
-        config.addProperty("test.interpol", "${unknown.property}");
-        assertEquals("Wrong interpolated unknown property",
-                "${unknown.property}", config.getString("test.interpol"));
+        InterpolationTestHelper.testInterpolationUnknownProperty(config);
     }
 
     /**
@@ -694,19 +634,7 @@
      */
     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));
-        }
+        InterpolationTestHelper.testInterpolationSystemProperties(config);
     }
 
     /**
@@ -714,10 +642,7 @@
      */
     public void testInterpolationConstants()
     {
-        config.addProperty("key.code",
-                "${const:java.awt.event.KeyEvent.VK_CANCEL}");
-        assertEquals("Wrong value of constant variable", KeyEvent.VK_CANCEL,
-                config.getInt("key.code"));
+        InterpolationTestHelper.testInterpolationConstants(config);
     }
 
     /**
@@ -726,10 +651,7 @@
      */
     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"));
+        InterpolationTestHelper.testInterpolationEscaped(config);
     }
 
     /**
@@ -737,17 +659,16 @@
      */
     public void testGetInterpolator()
     {
-        config.addProperty("var", "${echo:testVar}");
-        ConfigurationInterpolator interpol = config.getInterpolator();
-        interpol.registerLookup("echo", new StrLookup()
-        {
-            public String lookup(String varName)
-            {
-                return "Value of variable " + varName;
-            }
-        });
-        assertEquals("Wrong value of echo variable",
-                "Value of variable testVar", config.getString("var"));
+        InterpolationTestHelper.testGetInterpolator(config);
+    }
+
+    /**
+     * Tests obtaining a configuration with all variables replaced by their
+     * actual values.
+     */
+    public void testInterpolatedConfiguration()
+    {
+        InterpolationTestHelper.testInterpolatedConfiguration(config);
     }
 
     public void testGetHexadecimalValue()