StringResolver { public static String substVars(String val, Map props1, Map props2, List<String> propsToHide) throws IllegalArgumentException { StringBuffer sbuf = new StringBuffer(); int i = 0; int j, k; while (true) { j = val.indexOf(DELIM_START, i); if (j == -1) { if (i == 0) { return val; } else { sbuf.append(val.substring(i, val.length())); return sbuf.toString(); } } else { sbuf.append(val.substring(i, j)); k = indexOfDelimStop(val, j); if (k == -1) { throw new IllegalArgumentException('[' + val + "] has no closing brace. Opening brace at position [" + j + "]"); } else { String expression = val.substring(j, k + DELIM_STOP_LEN); j += DELIM_START_LEN; String key = val.substring(j, k); if (key.contains(DELIM_START)) { key = substVars(key, props1, props2); } String replacement = getSystemProperty(key, null); if (replacement == null && props1 != null) { if (props1 instanceof Properties) { replacement = ((Properties) props1).getProperty(key); } else { Object replacementSource = props1.get(key); if (replacementSource != null) { replacement = replacementSource.toString(); } } } if (replacement == null && props2 != null) { if (props2 instanceof Properties) { replacement = ((Properties) props2).getProperty(key); } else { Object replacementSource = props2.get(key); if (replacementSource != null) { replacement = replacementSource.toString(); } } } if (replacement != null) { if (propsToHide != null && propsToHide.contains(key)) { replacement = Misc.hide(replacement); } if (!replacement.equals(expression)) { String recursiveReplacement = substVars(replacement, props1, props2); sbuf.append(recursiveReplacement); } else { sbuf.append(replacement); } } i = k + DELIM_STOP_LEN; } } } } StringResolver(); static String getSystemProperty(String key, String def); static String substVars(String val, Map props1, Map props2, List<String> propsToHide); static String substVars(String val, Map props1, Map props2); static String substVars(String val, Map props); static boolean needsResolution(String string);  }
@Test public void resolveSimple() { String result = StringResolver.substVars("blalblalab ${key1}", properties); assertEquals("blalblalab value1", result); }
@Test public void resolveRecursively() { String result = StringResolver.substVars("blalblalab ${key4}", properties); assertEquals("blalblalab value1.value2.value1", result); }
@Test public void resolveRecursivelyAvoidStackOverflow() { String result = StringResolver.substVars("blalblalab ${key5}", properties); assertEquals("blalblalab ${key5}", result); }
@Test public void resolveComplexRecursively() { String result = StringResolver.substVars("blalblalab ${key1_${key2}}", properties); assertEquals("blalblalab value101", result); }
@Test public void resolveComplexProperty() { String result = StringResolver.substVars(properties.getProperty("testMultiResolve"), properties); assertEquals("one,two,three_value1value1,my_value2.value1,StageSpecifics_value1.value2.value1", result); }