Repository: struts Updated Branches: refs/heads/master 91d6691b0 -> 8135abeca
WW-4698 Implements System & ENV variables substitution Project: http://git-wip-us.apache.org/repos/asf/struts/repo Commit: http://git-wip-us.apache.org/repos/asf/struts/commit/8135abec Tree: http://git-wip-us.apache.org/repos/asf/struts/tree/8135abec Diff: http://git-wip-us.apache.org/repos/asf/struts/diff/8135abec Branch: refs/heads/master Commit: 8135abeca732b996f8e39eb27e59d79563dc4959 Parents: 91d6691 Author: Lukasz Lenart <lukaszlen...@apache.org> Authored: Wed Oct 12 11:23:24 2016 +0200 Committer: Lukasz Lenart <lukaszlen...@apache.org> Committed: Wed Oct 12 11:23:24 2016 +0200 ---------------------------------------------------------------------- .../config/providers/EnvsValueSubstitutor.java | 27 ++++++++++++++ .../config/providers/ValueSubstitutor.java | 7 ++++ .../providers/XWorkConfigurationProvider.java | 2 ++ .../providers/XmlConfigurationProvider.java | 12 +++++++ core/src/main/resources/struts-default.xml | 2 ++ .../config/providers/ConfigurationTestBase.java | 3 +- .../providers/EnvsValueSubstitutorTest.java | 30 ++++++++++++++++ ...nfigurationProviderEnvsSubstitutionTest.java | 37 ++++++++++++++++++++ .../providers/xwork-test-envs-substitution.xml | 17 +++++++++ 9 files changed, 135 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/main/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutor.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutor.java new file mode 100644 index 0000000..8c21b9c --- /dev/null +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutor.java @@ -0,0 +1,27 @@ +package com.opensymphony.xwork2.config.providers; + +import org.apache.commons.lang3.text.StrSubstitutor; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class EnvsValueSubstitutor implements ValueSubstitutor { + + private static final Logger LOG = LogManager.getLogger(EnvsValueSubstitutor.class); + + protected StrSubstitutor strSubstitutor; + + public EnvsValueSubstitutor() { + strSubstitutor = new StrSubstitutor(System.getenv()); + strSubstitutor.setVariablePrefix("${ENV."); + strSubstitutor.setVariableSuffix('}'); + strSubstitutor.setValueDelimiter(":"); + } + + @Override + public String substitute(String value) { + LOG.debug("Substituting value {} with proper ENV value", value); + + String substituted = StrSubstitutor.replaceSystemProperties(value); + return strSubstitutor.replace(substituted); + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/main/java/com/opensymphony/xwork2/config/providers/ValueSubstitutor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/ValueSubstitutor.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/ValueSubstitutor.java new file mode 100644 index 0000000..4f45cf1 --- /dev/null +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/ValueSubstitutor.java @@ -0,0 +1,7 @@ +package com.opensymphony.xwork2.config.providers; + +public interface ValueSubstitutor { + + String substitute(String value); + +} http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java index 0141e62..5ef5c4e 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XWorkConfigurationProvider.java @@ -180,6 +180,8 @@ public class XWorkConfigurationProvider implements ConfigurationProvider { .factory(ExcludedPatternsChecker.class, DefaultExcludedPatternsChecker.class, Scope.PROTOTYPE) .factory(AcceptedPatternsChecker.class, DefaultAcceptedPatternsChecker.class, Scope.PROTOTYPE) + + .factory(ValueSubstitutor.class, EnvsValueSubstitutor.class, Scope.SINGLETON) ; props.setProperty(StrutsConstants.STRUTS_ENABLE_DYNAMIC_METHOD_INVOCATION, Boolean.FALSE.toString()); http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java index 4e76bb2..69bc8d2 100644 --- a/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java +++ b/core/src/main/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProvider.java @@ -98,6 +98,7 @@ public class XmlConfigurationProvider implements ConfigurationProvider { private Map<String, Element> declaredPackages = new HashMap<>(); private FileManager fileManager; + private ValueSubstitutor valueSubstitutor; public XmlConfigurationProvider() { this("xwork.xml", true); @@ -141,6 +142,11 @@ public class XmlConfigurationProvider implements ConfigurationProvider { this.fileManager = fileManagerFactory.getFileManager(); } + @Inject(required = false) + public void setValueSubstitutor(ValueSubstitutor valueSubstitutor) { + this.valueSubstitutor = valueSubstitutor; + } + /** * Returns an unmodifiable map of DTD mappings * @@ -270,6 +276,12 @@ public class XmlConfigurationProvider implements ConfigurationProvider { } else if ("constant".equals(nodeName)) { String name = child.getAttribute("name"); String value = child.getAttribute("value"); + + if (valueSubstitutor != null) { + LOG.debug("Substituting value [{}] using [{}]", value, valueSubstitutor.getClass().getName()); + value = valueSubstitutor.substitute(value); + } + props.setProperty(name, value, childNode); } else if (nodeName.equals("unknown-handler-stack")) { List<UnknownHandlerConfig> unknownHandlerStack = new ArrayList<UnknownHandlerConfig>(); http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/main/resources/struts-default.xml ---------------------------------------------------------------------- diff --git a/core/src/main/resources/struts-default.xml b/core/src/main/resources/struts-default.xml index 4e5ae12..fd9a085 100644 --- a/core/src/main/resources/struts-default.xml +++ b/core/src/main/resources/struts-default.xml @@ -173,6 +173,8 @@ <bean type="com.opensymphony.xwork2.security.ExcludedPatternsChecker" name="struts" class="com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker" scope="prototype" /> <bean type="com.opensymphony.xwork2.security.AcceptedPatternsChecker" name="struts" class="com.opensymphony.xwork2.security.DefaultAcceptedPatternsChecker" scope="prototype" /> + <bean type="com.opensymphony.xwork2.config.providers.ValueSubstitutor" class="com.opensymphony.xwork2.config.providers.EnvsValueSubstitutor" scope="singleton"/> + <package name="struts-default" abstract="true" strict-method-invocation="true"> <result-types> <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/> http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationTestBase.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationTestBase.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationTestBase.java index f5cd83a..960c77e 100644 --- a/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationTestBase.java +++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/ConfigurationTestBase.java @@ -36,8 +36,7 @@ public abstract class ConfigurationTestBase extends XWorkTestCase { container = configuration.getContainer(); XmlConfigurationProvider prov = new XmlConfigurationProvider(filename, true); - prov.setObjectFactory(container.getInstance(ObjectFactory.class)); - prov.setFileManagerFactory(container.getInstance(FileManagerFactory.class)); + container.inject(prov); prov.init(configuration); prov.loadPackages(); return prov; http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/test/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutorTest.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutorTest.java new file mode 100644 index 0000000..9e637e1 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/EnvsValueSubstitutorTest.java @@ -0,0 +1,30 @@ +package com.opensymphony.xwork2.config.providers; + +import org.apache.struts2.StrutsInternalTestCase; + + +public class EnvsValueSubstitutorTest extends StrutsInternalTestCase { + + public void testSimpleValue() throws Exception { + // given + String expected = System.getenv("USER"); + ValueSubstitutor substitutor = new EnvsValueSubstitutor(); + + // when + String actual = substitutor.substitute("${ENV.USER}"); + + // then + assertEquals(expected, actual); + } + + public void testNoSubstitution() throws Exception { + // given + ValueSubstitutor substitutor = new EnvsValueSubstitutor(); + + // when + String actual = substitutor.substitute("val1"); + + // then + assertEquals("val1", actual); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderEnvsSubstitutionTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderEnvsSubstitutionTest.java b/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderEnvsSubstitutionTest.java new file mode 100644 index 0000000..53308f2 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/config/providers/XmlConfigurationProviderEnvsSubstitutionTest.java @@ -0,0 +1,37 @@ +package com.opensymphony.xwork2.config.providers; + +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import org.apache.struts2.StrutsConstants; + +public class XmlConfigurationProviderEnvsSubstitutionTest extends ConfigurationTestBase { + + public void testSubstitution() throws ConfigurationException { + final String filename = "com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml"; + ConfigurationProvider provider = buildConfigurationProvider(filename); + + configurationManager.addContainerProvider(provider); + configurationManager.reload(); + configuration = configurationManager.getConfiguration(); + container = configuration.getContainer(); + + String foo = container.getInstance(String.class, "foo"); + assertEquals("bar", foo); + + String user = container.getInstance(String.class, "user"); + assertEquals(System.getenv("USER"), user); + + String home = container.getInstance(String.class, "home"); + assertEquals("Current HOME = " + System.getenv("HOME"), home); + + String os = container.getInstance(String.class, "os"); + assertEquals("Current OS = " + System.getProperty("os.name"), os); + + String unknown = container.getInstance(String.class, "unknown"); + assertEquals("Unknown = default", unknown); + + String devMode = container.getInstance(String.class, StrutsConstants.STRUTS_DEVMODE); + assertEquals("false", devMode); + } + +} http://git-wip-us.apache.org/repos/asf/struts/blob/8135abec/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml ---------------------------------------------------------------------- diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml new file mode 100644 index 0000000..13f2bfb --- /dev/null +++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml @@ -0,0 +1,17 @@ +<!DOCTYPE xwork PUBLIC + "-//Apache Struts//XWork 2.5//EN" + "http://struts.apache.org/dtds/xwork-2.5.dtd" + > + +<xwork> + + <constant name="foo" value="bar"/> + + <constant name="user" value="${ENV.USER}"/> + <constant name="home" value="Current HOME = ${ENV.HOME}"/> + <constant name="os" value="Current OS = ${os.name}"/> + <constant name="unknown" value="Unknown = ${ENV.UNKNOWN:default}"/> + + <constant name="struts.devMode" value="${ENV.STRUTS_DEV_MODE:false}"/> + +</xwork>