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>

Reply via email to