Here are some trails you could use to do such a job.
Read an object's property value given its name:
public static Object readProperty(String name, Object object) throws Exception {
Class<?> clazz = object.getClass();
do {
try {
Field field = clazz.getDeclaredField(name);
return field.get(object);
} catch (NoSuchFieldException e) {
clazz = clazz.getSuperclass();
}
} while (clazz != null);
return null;
}
Regex matching your pattern, capturing the property name (visualization by Debuggex):
\$\{([^}]+)\}
Iterating over matches in Java:
String input = "Hi ${name}, There's been ${days} days since you logged in on ${site}.";
String regex = "\\$\\{([^}]+)\\}";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(input);
while (matcher.find()) {
String name = matcher.group(1);
// name contains now the property name
// add the logic here: replace occurrences of "${" + name + "}" by the real value
}