1 /******************************************************************************* 2 * Copyright (c) 2009, 2015 Mountainminds GmbH & Co. KG and Contributors 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * Marc R. Hoffmann - initial API and implementation 10 * 11 *******************************************************************************/ 12 package org.jacoco.agent.rt.internal; 13 14 import java.io.IOException; 15 import java.io.InputStream; 16 import java.util.Map; 17 import java.util.Properties; 18 import java.util.regex.Matcher; 19 import java.util.regex.Pattern; 20 21 /** 22 * Internal utility to load runtime configuration from a classpath resource and 23 * from system properties. System property keys are prefixed with 24 * <code>jacoco.</code>. If the same property is defined twice the system 25 * property takes precedence. 26 */ 27 final class ConfigLoader { 28 29 private static final String SYS_PREFIX = "jacoco-agent."; 30 31 private static final Pattern SUBST_PATTERN = Pattern 32 .compile("\\$\\{([^\\}]+)\\}"); 33 34 static Properties load(final String resource, final Properties system) { 35 final Properties result = new Properties(); 36 loadResource(resource, result); 37 loadSystemProperties(system, result); 38 substSystemProperties(result, system); 39 return result; 40 } 41 42 private static void loadResource(final String resource, 43 final Properties result) { 44 final InputStream file = Offline.class.getResourceAsStream(resource); 45 if (file != null) { 46 try { 47 result.load(file); 48 } catch (final IOException e) { 49 throw new RuntimeException(e); 50 } 51 } 52 } 53 54 private static void loadSystemProperties(final Properties system, 55 final Properties result) { 56 for (final Map.Entry<Object, Object> entry : system.entrySet()) { 57 final String keystr = entry.getKey().toString(); 58 if (keystr.startsWith(SYS_PREFIX)) { 59 result.put(keystr.substring(SYS_PREFIX.length()), 60 entry.getValue()); 61 } 62 } 63 } 64 65 private static void substSystemProperties(final Properties result, 66 final Properties system) { 67 for (final Map.Entry<Object, Object> entry : result.entrySet()) { 68 final String oldValue = (String) entry.getValue(); 69 final StringBuilder newValue = new StringBuilder(); 70 final Matcher m = SUBST_PATTERN.matcher(oldValue); 71 int pos = 0; 72 while (m.find()) { 73 newValue.append(oldValue.substring(pos, m.start())); 74 final String sub = system.getProperty(m.group(1)); 75 newValue.append(sub == null ? m.group(0) : sub); 76 pos = m.end(); 77 } 78 newValue.append(oldValue.substring(pos)); 79 entry.setValue(newValue.toString()); 80 } 81 } 82 83 private ConfigLoader() { 84 } 85 86 } 87