Repository: deltaspike Updated Branches: refs/heads/master f8896e3f8 -> db8560c41
DELTASPIKE-1167 Patch from Valentin Maechler to add support for variable replacement in an environment aware way. Project: http://git-wip-us.apache.org/repos/asf/deltaspike/repo Commit: http://git-wip-us.apache.org/repos/asf/deltaspike/commit/db8560c4 Tree: http://git-wip-us.apache.org/repos/asf/deltaspike/tree/db8560c4 Diff: http://git-wip-us.apache.org/repos/asf/deltaspike/diff/db8560c4 Branch: refs/heads/master Commit: db8560c419cb8411dc77a634e52b3557a807be23 Parents: f8896e3 Author: John D. Ament <[email protected]> Authored: Wed Jul 13 06:39:21 2016 -0400 Committer: John D. Ament <[email protected]> Committed: Wed Jul 13 06:39:21 2016 -0400 ---------------------------------------------------------------------- .../core/api/config/ConfigResolver.java | 135 ++++++++++++------- .../core/api/config/ConfigResolverContext.java | 64 +++++++++ .../test/api/config/ConfigResolverTest.java | 25 +++- .../test/api/config/TestConfigSource.java | 6 + 4 files changed, 175 insertions(+), 55 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/deltaspike/blob/db8560c4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java index 778614b..5a54abb 100644 --- a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolver.java @@ -174,7 +174,10 @@ public final class ConfigResolver public static String getPropertyValue(String key, String defaultValue, boolean evaluateVariables) { - String value = getPropertyValue(key, evaluateVariables); + String value = getPropertyValue( + key, + new ConfigResolverContext() + .setEvaluateVariables(evaluateVariables)); return fallbackToDefaultIfEmpty(key, value, defaultValue); } @@ -189,7 +192,9 @@ public final class ConfigResolver */ public static String getPropertyValue(String key) { - return getPropertyValue(key, true); + return getPropertyValue( + key, + new ConfigResolverContext().setEvaluateVariables(true)); } /** @@ -203,51 +208,10 @@ public final class ConfigResolver */ public static String getPropertyValue(String key, boolean evaluateVariables) { - ConfigSource[] appConfigSources = getConfigSources(); - - String value; - for (ConfigSource configSource : appConfigSources) - { - value = configSource.getPropertyValue(key); - - if (value != null) - { - LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.", - new Object[]{filterConfigValueForLog(key, value), key, configSource.getConfigName()}); - - if (evaluateVariables) - { - // recursively resolve any ${varName} in the value - int startVar = 0; - while ((startVar = value.indexOf("${", startVar)) >= 0) - { - int endVar = value.indexOf("}", startVar); - if (endVar <= 0) - { - break; - } - String varName = value.substring(startVar + 2, endVar); - if (varName.isEmpty()) - { - break; - } - String variableValue = getPropertyValue(varName, true); - if (variableValue != null) - { - value = value.replace("${" + varName + "}", variableValue); - } - startVar++; - } - } - - return filterConfigValue(key, value); - } - - LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.", - new Object[]{key, configSource.getConfigName()}); - } - - return null; + return getPropertyValue( + key, + new ConfigResolverContext() + .setEvaluateVariables(evaluateVariables)); } /** @@ -271,12 +235,18 @@ public final class ConfigResolver */ public static String getProjectStageAwarePropertyValue(String key) { + ConfigResolverContext configResolverContext = + new ConfigResolverContext() + .setProjectStageAware(true) + .setEvaluateVariables(true); + ProjectStage ps = getProjectStage(); - String value = getPropertyValue(key + '.' + ps); + String value = getPropertyValue(key + '.' + ps, configResolverContext); if (value == null) { - value = getPropertyValue(key); + configResolverContext.setProjectStageAware(false); + value = getPropertyValue(key, configResolverContext); } return value; @@ -377,6 +347,73 @@ public final class ConfigResolver return fallbackToDefaultIfEmpty(key, value, defaultValue); } + + private static String getPropertyValue(String key, ConfigResolverContext configResolverContext) + { + ConfigSource[] appConfigSources = getConfigSources(); + + String value; + for (ConfigSource configSource : appConfigSources) + { + value = configSource.getPropertyValue(key); + + if (value != null) + { + LOG.log(Level.FINE, "found value {0} for key {1} in ConfigSource {2}.", + new Object[]{filterConfigValueForLog(key, value), key, configSource.getConfigName()}); + + if (configResolverContext.isEvaluateVariables()) + { + value = resolveVariables(value, configResolverContext); + } + + return filterConfigValue(key, value); + } + + LOG.log(Level.FINER, "NO value found for key {0} in ConfigSource {1}.", + new Object[]{key, configSource.getConfigName()}); + } + + return null; + } + + /** + * recursively resolve any ${varName} in the value + */ + private static String resolveVariables(String value, ConfigResolverContext configResolverContext) + { + int startVar = 0; + while ((startVar = value.indexOf("${", startVar)) >= 0) + { + int endVar = value.indexOf("}", startVar); + if (endVar <= 0) + { + break; + } + String varName = value.substring(startVar + 2, endVar); + if (varName.isEmpty()) + { + break; + } + + String variableValue; + if (configResolverContext.isProjectStageAware()) + { + variableValue = getProjectStageAwarePropertyValue(varName); + } + else + { + variableValue = getPropertyValue(varName, true); + } + + if (variableValue != null) + { + value = value.replace("${" + varName + "}", variableValue); + } + startVar++; + } + return value; + } /** * Resolve all values for the given key. http://git-wip-us.apache.org/repos/asf/deltaspike/blob/db8560c4/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java new file mode 100644 index 0000000..21418db --- /dev/null +++ b/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/api/config/ConfigResolverContext.java @@ -0,0 +1,64 @@ +/* + * 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.deltaspike.core.api.config; + +class ConfigResolverContext +{ + + private boolean projectStageAware; + private boolean evaluateVariables; + private boolean propertyAware; + + public ConfigResolverContext() + { + } + + public ConfigResolverContext setEvaluateVariables(final boolean evaluateVariables) + { + this.evaluateVariables = evaluateVariables; + return this; + } + + public boolean isEvaluateVariables() + { + return evaluateVariables; + } + + public ConfigResolverContext setProjectStageAware(final boolean projectStageAware) + { + this.projectStageAware = projectStageAware; + return this; + } + + public boolean isProjectStageAware() + { + return projectStageAware; + } + + public ConfigResolverContext setPropertyAware(final boolean propertyAware) + { + this.propertyAware = propertyAware; + return this; + } + + public boolean isPropertyAware() + { + return propertyAware; + } +} http://git-wip-us.apache.org/repos/asf/deltaspike/blob/db8560c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java index 66c288a..54e47ac 100644 --- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java +++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/ConfigResolverTest.java @@ -70,15 +70,15 @@ public class ConfigResolverTest ProjectStageProducer.setProjectStage(ProjectStage.UnitTest); Assert.assertNull(ConfigResolver.getProjectStageAwarePropertyValue("notexisting", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getProjectStageAwarePropertyValue("testkey2", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3")); Assert.assertEquals("", ConfigResolver.getProjectStageAwarePropertyValue("testkey3")); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getProjectStageAwarePropertyValue("testkey3", DEFAULT_VALUE)); @@ -96,15 +96,15 @@ public class ConfigResolverTest Assert.assertNull(ConfigResolver.getPropertyAwarePropertyValue("notexisting", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey")); Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor")); Assert.assertEquals("unittestvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey", "dbvendor", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey2")); Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor")); Assert.assertEquals("testvalue", ConfigResolver.getPropertyAwarePropertyValue("testkey2", "dbvendor", null)); - Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3", null)); + Assert.assertEquals("testvalue", ConfigResolver.getPropertyValue("testkey3")); Assert.assertEquals("", ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor")); Assert.assertEquals(DEFAULT_VALUE, ConfigResolver.getPropertyAwarePropertyValue("testkey3", "dbvendor", DEFAULT_VALUE)); @@ -195,6 +195,19 @@ public class ConfigResolverTest setTestConfigSourceValue(key, null); Assert.assertNull(resolver.getValue()); } + + @Test + public void testProjectStageAwarePropertyValueReference() { + final String expected = + "projectStageAware-exampleEntry-1-is-tomato-UnitTest"; + + final String projectStageAwareExampleEntry1 = + ConfigResolver.getProjectStageAwarePropertyValue( + "deltaspike.test.exampleEntry-2", + ""); + + Assert.assertEquals(expected, projectStageAwareExampleEntry1); + } private void setTestConfigSourceValue(String key, String value) { http://git-wip-us.apache.org/repos/asf/deltaspike/blob/db8560c4/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java ---------------------------------------------------------------------- diff --git a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java index e5e4e28..4798f67 100644 --- a/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java +++ b/deltaspike/core/api/src/test/java/org/apache/deltaspike/test/api/config/TestConfigSource.java @@ -91,6 +91,12 @@ public class TestConfigSource implements ConfigSource props.put("deltaspike.test.projectstagefallback.UnitTest", ""); props.put("deltaspike.test.projectstagefallback", "Value without ProjectStage"); + + // ProjectStage aware property value with resolved reference + props.put("deltaspike.test.exampleEntry-1", "tomato"); + props.put("deltaspike.test.exampleEntry-1.UnitTest", "tomato-UnitTest"); + props.put("deltaspike.test.exampleEntry-2", "default-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}"); + props.put("deltaspike.test.exampleEntry-2.UnitTest", "projectStageAware-exampleEntry-1-is-${deltaspike.test.exampleEntry-1}"); } @Override
