This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push: new 6f356df Support for default values in property value expressions 6f356df is described below commit 6f356df24241db9f655c8adb0c51aea95a2ab05d Author: bohmber <bom...@apache.org> AuthorDate: Mon Mar 2 20:25:30 2020 +0100 Support for default values in property value expressions --- .../org/apache/tomcat/util/IntrospectionUtils.java | 60 ++++++++++++++++------ .../apache/tomcat/util/TestIntrospectionUtils.java | 37 ++++++++++++- webapps/docs/changelog.xml | 5 ++ webapps/docs/config/systemprops.xml | 5 +- 4 files changed, 87 insertions(+), 20 deletions(-) diff --git a/java/org/apache/tomcat/util/IntrospectionUtils.java b/java/org/apache/tomcat/util/IntrospectionUtils.java index 2d17a72..aa2f40c 100644 --- a/java/org/apache/tomcat/util/IntrospectionUtils.java +++ b/java/org/apache/tomcat/util/IntrospectionUtils.java @@ -219,12 +219,21 @@ public final class IntrospectionUtils { } /** - * Replace ${NAME} with the property value. + * Replaces ${NAME} in the value with the value of the property 'NAME'. + * Replaces ${NAME:DEFAULT} with the value of the property 'NAME:DEFAULT', + * if the property 'NAME:DEFAULT' is not set, + * the expression is replaced with the value of the property 'NAME', + * if the property 'NAME' is not set, + * the expression is replaced with 'DEFAULT'. + * If the property is not set and there is no default the value will be + * returned unmodified. + * * @param value The value * @param staticProp Replacement properties * @param dynamicProp Replacement properties * @param classLoader Class loader associated with the code requesting the * property + * * @return the replacement value */ public static String replaceProperties(String value, @@ -256,25 +265,21 @@ public final class IntrospectionUtils { continue; } String n = value.substring(pos + 2, endName); - String v = null; - if (staticProp != null) { - v = (String) staticProp.get(n); - } - if (v == null && dynamicProp != null) { - for (PropertySource propertySource : dynamicProp) { - if (propertySource instanceof SecurePropertySource) { - v = ((SecurePropertySource) propertySource).getProperty(n, classLoader); - } else { - v = propertySource.getProperty(n); - } - if (v != null) { - break; + String v = getProperty(n, staticProp, dynamicProp, classLoader); + if (v == null) { + // {name:default} + int col = n.indexOf(':'); + if (col != -1) { + String dV = n.substring(col+1); + n = n.substring(0, col); + v = getProperty(n, staticProp, dynamicProp, classLoader); + if (v == null) { + v = dV; } + } else { + v = "${" + n + "}"; } } - if (v == null) - v = "${" + n + "}"; - sb.append(v); prev = endName + 1; } @@ -284,6 +289,27 @@ public final class IntrospectionUtils { return sb.toString(); } + private static String getProperty(String name, Hashtable<Object, Object> staticProp, + PropertySource[] dynamicProp, ClassLoader classLoader) { + String v = null; + if (staticProp != null) { + v = (String) staticProp.get(name); + } + if (v == null && dynamicProp != null) { + for (PropertySource propertySource : dynamicProp) { + if (propertySource instanceof SecurePropertySource) { + v = ((SecurePropertySource) propertySource).getProperty(name, classLoader); + } else { + v = propertySource.getProperty(name); + } + if (v != null) { + break; + } + } + } + return v; + } + /** * Reverse of Introspector.decapitalize. * @param name The name diff --git a/test/org/apache/tomcat/util/TestIntrospectionUtils.java b/test/org/apache/tomcat/util/TestIntrospectionUtils.java index 64864f6..ef27174 100644 --- a/test/org/apache/tomcat/util/TestIntrospectionUtils.java +++ b/test/org/apache/tomcat/util/TestIntrospectionUtils.java @@ -16,6 +16,8 @@ */ package org.apache.tomcat.util; +import java.util.Properties; + import org.junit.Assert; import org.junit.Test; @@ -101,12 +103,45 @@ public class TestIntrospectionUtils { StandardContext.class, "javax.management.NotificationBroadcaster")); } - // And one to check that non-matches return false + // And one to check that non-matches return false @Test public void testIsInstanceStandardContext12() { Assert.assertFalse(IntrospectionUtils.isInstance( StandardContext.class, "com.example.Other")); } + + + @Test + public void testReplaceProperties() { + Properties properties = new Properties(); + + Assert.assertEquals("no-expression", IntrospectionUtils.replaceProperties( + "no-expression", properties, null, null)); + + Assert.assertEquals("${normal}", IntrospectionUtils.replaceProperties( + "${normal}", properties, null, null)); + + properties.setProperty("normal", "value1"); + Assert.assertEquals("value1", IntrospectionUtils.replaceProperties( + "${normal}", properties, null, null)); + + Assert.assertEquals("abcvalue1xyz", IntrospectionUtils.replaceProperties( + "abc${normal}xyz", properties, null, null)); + + properties.setProperty("prop_with:colon", "value2"); + Assert.assertEquals("value2", IntrospectionUtils.replaceProperties( + "${prop_with:colon}", properties, null, null)); + + Assert.assertEquals("value1", IntrospectionUtils.replaceProperties( + "${normal:default}", properties, null, null)); + + properties.remove("normal"); + Assert.assertEquals("default", IntrospectionUtils.replaceProperties( + "${normal:default}", properties, null, null)); + + Assert.assertEquals("abc${normal}xyz", IntrospectionUtils.replaceProperties( + "abc${normal}xyz", properties, null, null)); + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 649bb9c..8864446 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -127,6 +127,11 @@ system property, replaced by the <code>cookieName</code> attribute on the SSO valve. (remm) </update> + <fix> + Add support for default values when using <code>${...}</code> property + replacement in configuration files. Based on a pull request provided by + Bernd Bohmann. (markt) + </fix> </changelog> </subsection> <subsection name="Coyote"> diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml index fb3c6ea..2fc5a33 100644 --- a/webapps/docs/config/systemprops.xml +++ b/webapps/docs/config/systemprops.xml @@ -45,8 +45,9 @@ <code>org.apache.tomcat.util.IntrospectionUtils.PropertySource</code>. Required to have a public constructor with no arguments.</p> <p>Use this to add a property source, that will be invoked when - <code>${parameter}</code> denoted parameters are found in the XML files - that Tomcat parses.</p> + <code>${parameter:default-value}</code> denoted parameters (with + optional default values) are found in the XML files that Tomcat + parses.</p> <p>Property replacement from the specified property source on the JVM system properties can also be done using the <code>REPLACE_SYSTEM_PROPERTIES</code> system property.</p> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org