aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc R. Hoffmann <hoffmann@mountainminds.com>2014-12-26 17:47:32 +0100
committerMarc R. Hoffmann <hoffmann@mountainminds.com>2014-12-26 17:51:04 +0100
commit0092055e81f99968780cc7ad347d44c056ec4ff5 (patch)
treed9256510195bf514e8191d1c2c5d0d941546db67
parent0d72a8280e28e445c1470e12f44c3434b9d7b56b (diff)
downloadjacoco-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'.
-rw-r--r--org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/ConfigLoaderTest.java16
-rw-r--r--org.jacoco.agent.rt.test/src/org/jacoco/agent/rt/internal/agent-subst-test.properties5
-rw-r--r--org.jacoco.agent.rt/src/org/jacoco/agent/rt/internal/ConfigLoader.java35
-rw-r--r--org.jacoco.doc/docroot/doc/changes.html7
-rw-r--r--org.jacoco.doc/docroot/doc/offline.html10
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