diff options
author | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2014-12-26 17:47:32 +0100 |
---|---|---|
committer | Marc R. Hoffmann <hoffmann@mountainminds.com> | 2014-12-26 17:51:04 +0100 |
commit | 0092055e81f99968780cc7ad347d44c056ec4ff5 (patch) | |
tree | d9256510195bf514e8191d1c2c5d0d941546db67 | |
parent | 0d72a8280e28e445c1470e12f44c3434b9d7b56b (diff) | |
download | jacoco-0092055e81f99968780cc7ad347d44c056ec4ff5.tar.gz |
GitHub #262: Variable replacement for offline agent configuration.
For offline agent configuration properties can now contain variables in
${name} format which will be replaced with system properties at runtime.
Based on original PR by user 'debugger'.
5 files changed, 70 insertions, 3 deletions
diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java index a704a2b2..5cd05c9a 100644 --- a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java @@ -55,4 +55,20 @@ public class ConfigLoaderTest { assertEquals("testid", config.get("sessionid")); } + @Test + public void testSubstituteProperties() { + Properties system = new Properties(); + system.setProperty("user.home", "/home/jacoco"); + system.setProperty("java.version", "1.5.0"); + Properties config = ConfigLoader.load( + "/org/jacoco/agent/rt/internal/agent-subst-test.properties", + system); + + assertEquals("no$replace}", config.get("key0")); + assertEquals("/home/jacoco/coverage/jacoco-1.5.0.exec", + config.get("key1")); + assertEquals("$/home/jacoco", config.get("key2")); + assertEquals("/home/jacoco}}", config.get("key3")); + assertEquals("${does.not.exist}", config.get("key4")); + } } diff --git a/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/agent-subst-test.properties b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/agent-subst-test.properties new file mode 100644 index 00000000..62588a1f --- /dev/null +++ b/org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/agent-subst-test.properties @@ -0,0 +1,5 @@ +key0=no$replace} +key1=${user.home}/coverage/jacoco-${java.version}.exec +key2=$${user.home} +key3=${user.home}}} +key4=${does.not.exist}
\ No newline at end of file diff --git a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/ConfigLoader.java b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/ConfigLoader.java index f1f2216c..4ba97969 100644 --- a/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/ConfigLoader.java +++ b/org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/ConfigLoader.java @@ -15,6 +15,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Internal utility to load runtime configuration from a classpath resource and @@ -26,10 +28,19 @@ final class ConfigLoader { private static final String SYS_PREFIX = "jacoco-agent."; + private static final Pattern SUBST_PATTERN = Pattern + .compile("\\$\\{([^\\}]+)\\}"); + static Properties load(final String resource, final Properties system) { final Properties result = new Properties(); + loadResource(resource, result); + loadSystemProperties(system, result); + substSystemProperties(result, system); + return result; + } - // 1. Try to load resource + private static void loadResource(final String resource, + final Properties result) { final InputStream file = Offline.class.getResourceAsStream(resource); if (file != null) { try { @@ -38,8 +49,10 @@ final class ConfigLoader { throw new RuntimeException(e); } } + } - // 2. Override with system properties + private static void loadSystemProperties(final Properties system, + final Properties result) { for (final Map.Entry<Object, Object> entry : system.entrySet()) { final String keystr = entry.getKey().toString(); if (keystr.startsWith(SYS_PREFIX)) { @@ -47,8 +60,24 @@ final class ConfigLoader { entry.getValue()); } } + } - return result; + private static void substSystemProperties(final Properties result, + final Properties system) { + for (final Map.Entry<Object, Object> entry : result.entrySet()) { + final String oldValue = (String) entry.getValue(); + final StringBuilder newValue = new StringBuilder(); + final Matcher m = SUBST_PATTERN.matcher(oldValue); + int pos = 0; + while (m.find()) { + newValue.append(oldValue.substring(pos, m.start())); + final String sub = system.getProperty(m.group(1)); + newValue.append(sub == null ? m.group(0) : sub); + pos = m.end(); + } + newValue.append(oldValue.substring(pos)); + entry.setValue(newValue.toString()); + } } private ConfigLoader() { diff --git a/org.jacoco.doc/docroot/doc/changes.html b/org.jacoco.doc/docroot/doc/changes.html index 0a1af5e0..4e808f21 100644 --- a/org.jacoco.doc/docroot/doc/changes.html +++ b/org.jacoco.doc/docroot/doc/changes.html @@ -20,6 +20,13 @@ <h2>Snapshot Build @qualified.bundle.version@ (@build.date@)</h2> +<h3>New Features</h3> +<ul> + <li>For offline instrumemtation agent configuration supports system properties + replacements. Implementation based on pull request of GitHub user 'debugger' + (GitHub <a href="https://github.com/jacoco/jacoco/issues/262">#226</a>).</li> +</ul> + <h2>Release 0.7.2 (2014/09/12)</h2> <h3>Fixed Bugs</h3> diff --git a/org.jacoco.doc/docroot/doc/offline.html b/org.jacoco.doc/docroot/doc/offline.html index a6d31b67..9b390384 100644 --- a/org.jacoco.doc/docroot/doc/offline.html +++ b/org.jacoco.doc/docroot/doc/offline.html @@ -61,6 +61,16 @@ "<code>jacoco-agent.destfile</code>".</li> </ul> +<p> + In both cases configuration values may contain variables in the format + <code>${<i>name</i>}</code> which are resolved with system property values + at runtime. For example: +</p> + +<pre class="source"> +destfile=${user.home}/jacoco.exec +</pre> + <h2>Class Loading and Initialization</h2> <p> Unlike with on-the-fly instrumentation offline instrumented classes get a |