Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 00C412009F4 for ; Thu, 26 May 2016 21:12:41 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id F3857160A18; Thu, 26 May 2016 19:12:40 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id F0CD4160A17 for ; Thu, 26 May 2016 21:12:39 +0200 (CEST) Received: (qmail 82218 invoked by uid 500); 26 May 2016 19:12:39 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 82208 invoked by uid 99); 26 May 2016 19:12:39 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd1-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 26 May 2016 19:12:39 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd1-us-west.apache.org (ASF Mail Server at spamd1-us-west.apache.org) with ESMTP id C3262C2E79 for ; Thu, 26 May 2016 19:12:38 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd1-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 0.374 X-Spam-Level: X-Spam-Status: No, score=0.374 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, KAM_LAZY_DOMAIN_SECURITY=1, RP_MATCHES_RCVD=-1.426] autolearn=disabled Received: from mx2-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd1-us-west.apache.org [10.40.0.7]) (amavisd-new, port 10024) with ESMTP id 64Gdf0ezEy6E for ; Thu, 26 May 2016 19:12:36 +0000 (UTC) Received: from mailrelay1-us-west.apache.org (mailrelay1-us-west.apache.org [209.188.14.139]) by mx2-lw-eu.apache.org (ASF Mail Server at mx2-lw-eu.apache.org) with ESMTP id D9DBA5F263 for ; Thu, 26 May 2016 19:12:35 +0000 (UTC) Received: from svn01-us-west.apache.org (svn.apache.org [10.41.0.6]) by mailrelay1-us-west.apache.org (ASF Mail Server at mailrelay1-us-west.apache.org) with ESMTP id B8773E009C for ; Thu, 26 May 2016 19:12:34 +0000 (UTC) Received: from svn01-us-west.apache.org (localhost [127.0.0.1]) by svn01-us-west.apache.org (ASF Mail Server at svn01-us-west.apache.org) with ESMTP id 285803A02CA for ; Thu, 26 May 2016 19:12:34 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1745634 - in /commons/proper/configuration/trunk/src: changes/ main/java/org/apache/commons/configuration2/interpol/ test/java/org/apache/commons/configuration2/ test/java/org/apache/commons/configuration2/interpol/ Date: Thu, 26 May 2016 19:12:33 -0000 To: commits@commons.apache.org From: oheger@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20160526191234.285803A02CA@svn01-us-west.apache.org> archived-at: Thu, 26 May 2016 19:12:41 -0000 Author: oheger Date: Thu May 26 19:12:33 2016 New Revision: 1745634 URL: http://svn.apache.org/viewvc?rev=1745634&view=rev Log: Merge branch 'arrayInterpolation_CONF-633' into trunk Modified: commons/proper/configuration/trunk/src/changes/changes.xml commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration2/interpol/ConfigurationInterpolator.java commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/InterpolationTestHelper.java commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/TestAbstractConfigurationBasicFeatures.java commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/interpol/TestConfigurationInterpolator.java Modified: commons/proper/configuration/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/changes/changes.xml?rev=1745634&r1=1745633&r2=1745634&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/changes/changes.xml (original) +++ commons/proper/configuration/trunk/src/changes/changes.xml Thu May 26 19:12:33 2016 @@ -27,6 +27,10 @@ + + Interpolation was improved to better support properties with multiple + values. + ImmutableConfiguration.getArray() has been deprecated. Arrays can now be queried using the generic get() method in a type-safe way. Modified: commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration2/interpol/ConfigurationInterpolator.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration2/interpol/ConfigurationInterpolator.java?rev=1745634&r1=1745633&r2=1745634&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration2/interpol/ConfigurationInterpolator.java (original) +++ commons/proper/configuration/trunk/src/main/java/org/apache/commons/configuration2/interpol/ConfigurationInterpolator.java Thu May 26 19:12:33 2016 @@ -91,6 +91,12 @@ public class ConfigurationInterpolator /** Constant for the prefix separator. */ private static final char PREFIX_SEPARATOR = ':'; + /** The variable prefix. */ + private static final String VAR_START = "${"; + + /** The variable suffix. */ + private static final String VAR_END = "}"; + /** A map containing the default prefix lookups. */ private static final Map DEFAULT_PREFIX_LOOKUPS; @@ -378,7 +384,20 @@ public class ConfigurationInterpolator { if (value instanceof String) { - return substitutor.replace((String) value); + String strValue = (String) value; + if (looksLikeSingleVariable(strValue)) + { + Object resolvedValue = resolveSingleVariable(strValue); + if (resolvedValue != null && !(resolvedValue instanceof String)) + { + // If the value is again a string, it needs no special + // treatment; it may also contain further variables which + // must be resolved; therefore, the default mechanism is + // applied. + return resolvedValue; + } + } + return substitutor.replace(strValue); } return value; } @@ -469,6 +488,45 @@ public class ConfigurationInterpolator } /** + * Interpolates a string value that seems to be a single variable. + * + * @param strValue the string to be interpolated + * @return the resolved value or null if resolving failed + */ + private Object resolveSingleVariable(String strValue) + { + return resolve(extractVariableName(strValue)); + } + + /** + * Checks whether a value to be interpolated seems to be a single variable. + * In this case, it is resolved directly without using the + * {@code StrSubstitutor}. Note that it is okay if this method returns a + * false positive: In this case, resolving is going to fail, and standard + * mechanism is used. + * + * @param strValue the value to be interpolated + * @return a flag whether this value seems to be a single variable + */ + private static boolean looksLikeSingleVariable(String strValue) + { + return strValue.startsWith(VAR_START) && strValue.endsWith(VAR_END); + } + + /** + * Extracts the variable name from a value that consists of a single + * variable. + * + * @param strValue the value + * @return the extracted variable name + */ + private static String extractVariableName(String strValue) + { + return strValue.substring(VAR_START.length(), + strValue.length() - VAR_END.length()); + } + + /** * Creates a new instance based on the properties in the given specification * object. * Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/InterpolationTestHelper.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/InterpolationTestHelper.java?rev=1745634&r1=1745633&r2=1745634&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/InterpolationTestHelper.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/InterpolationTestHelper.java Thu May 26 19:12:33 2016 @@ -20,6 +20,7 @@ import static org.junit.Assert.assertEqu import static org.junit.Assert.fail; import java.awt.event.KeyEvent; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -61,11 +62,10 @@ public class InterpolationTestHelper assertEquals("check first entry was interpolated", "/home/applicationRoot/1", arrayInt[0]); - config.addProperty("path", "/temp,C:\\Temp,/usr/local/tmp"); + config.addProperty("path", Arrays.asList("/temp", "C:\\Temp","/usr/local/tmp")); config.setProperty("path.current", "${path}"); assertEquals("Interpolation with multi-valued property", - String.valueOf(config.getProperty("path")), - config.getString("path.current")); + "/temp", config.getString("path.current")); } /** Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/TestAbstractConfigurationBasicFeatures.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/TestAbstractConfigurationBasicFeatures.java?rev=1745634&r1=1745633&r2=1745634&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/TestAbstractConfigurationBasicFeatures.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/TestAbstractConfigurationBasicFeatures.java Thu May 26 19:12:33 2016 @@ -461,6 +461,38 @@ public class TestAbstractConfigurationBa } /** + * Tests whether a property can reference an array using interpolation. + * This is related to CONFIGURATION-633. + */ + @Test + public void testInterpolateArray() + { + PropertiesConfiguration config = new PropertiesConfiguration(); + String[] values = {"some", "test", "values"}; + final String keyArray = "testArray"; + config.addProperty(keyArray, values); + config.addProperty(KEY_PREFIX, "${" + keyArray + "}"); + + assertArrayEquals("Wrong property", values, config.getStringArray(KEY_PREFIX)); + } + + /** + * Tests whether a property can reference a list using interpolation. + * This is related to CONFIGURATION-633. + */ + @Test + public void testInterpolateList() + { + PropertiesConfiguration config = new PropertiesConfiguration(); + List values = Arrays.asList("some", "test", "values"); + final String keyList = "testList"; + config.addProperty(keyList, values); + config.addProperty(KEY_PREFIX, "${" + keyList + "}"); + + assertEquals("Wrong property", values, config.getList(String.class, KEY_PREFIX)); + } + + /** * Tests getList() for single non-string values. */ @Test Modified: commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/interpol/TestConfigurationInterpolator.java URL: http://svn.apache.org/viewvc/commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/interpol/TestConfigurationInterpolator.java?rev=1745634&r1=1745633&r2=1745634&view=diff ============================================================================== --- commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/interpol/TestConfigurationInterpolator.java (original) +++ commons/proper/configuration/trunk/src/test/java/org/apache/commons/configuration2/interpol/TestConfigurationInterpolator.java Thu May 26 19:12:33 2016 @@ -77,7 +77,7 @@ public class TestConfigurationInterpolat * @param value the value of this variable * @return the test lookup object */ - private static Lookup setUpTestLookup(final String var, final String value) + private static Lookup setUpTestLookup(final String var, final Object value) { Lookup lookup = EasyMock.createMock(Lookup.class); EasyMock.expect(lookup.lookup(EasyMock.anyObject(String.class))) @@ -487,6 +487,53 @@ public class TestConfigurationInterpolat } /** + * Tests a property value consisting of multiple variables. + */ + @Test + public void testInterpolationMultipleVariables() + { + String value = "The ${subject} jumps over ${object}."; + interpolator.addDefaultLookup(setUpTestLookup("subject", "quick brown fox")); + interpolator.addDefaultLookup(setUpTestLookup("object", "the lazy dog")); + assertEquals("Wrong result", "The quick brown fox jumps over the lazy dog.", + interpolator.interpolate(value)); + } + + /** + * Tests an interpolation that consists of a single variable only. The + * variable's value should be returned verbatim. + */ + @Test + public void testInterpolationSingleVariable() + { + Object value = 42; + interpolator.addDefaultLookup(setUpTestLookup(TEST_NAME, value)); + assertEquals("Wrong result", value, + interpolator.interpolate("${" + TEST_NAME + "}")); + } + + /** + * Tests a variable declaration which lacks the trailing closing bracket. + */ + @Test + public void testInterpolationVariableIncomplete() + { + String value = "${" + TEST_NAME; + interpolator.addDefaultLookup(setUpTestLookup(TEST_NAME, "someValue")); + assertEquals("Wrong result", value, interpolator.interpolate(value)); + } + + /** + * Tests that an empty variable definition does not cause problems. + */ + @Test + public void testInterpolateEmptyVariable() + { + String value = "${}"; + assertEquals("Wrong result", value, interpolator.interpolate(value)); + } + + /** * Tries to obtain an instance from a null specification. */ @Test(expected = IllegalArgumentException.class)