in archaius2-core/src/main/java/com/netflix/archaius/ConfigMapper.java [60:191]
public <T> void mapConfig(T injectee, final Config config, IoCContainer ioc) throws MappingException {
Configuration configAnnot = injectee.getClass().getAnnotation(Configuration.class);
if (configAnnot == null) {
return;
}
Class<T> injecteeType = (Class<T>) injectee.getClass();
String prefix = configAnnot.prefix();
// Extract parameters from the object. For each parameter
// look for either file 'paramname' or method 'getParamnam'
String[] params = configAnnot.params();
if (params.length > 0) {
Map<String, String> map = new HashMap<String, String>();
for (String param : params) {
try {
Field f = injecteeType.getDeclaredField(param);
f.setAccessible(true);
map.put(param, f.get(injectee).toString());
} catch (NoSuchFieldException e) {
try {
Method method = injecteeType.getDeclaredMethod(
"get" + Character.toUpperCase(param.charAt(0)) + param.substring(1));
method.setAccessible(true);
map.put(param, method.invoke(injectee).toString());
} catch (Exception e1) {
throw new MappingException(e1);
}
} catch (Exception e) {
throw new MappingException(e);
}
}
prefix = StrSubstitutor.replace(prefix, map, "${", "}");
}
// Interpolate using any replacements loaded into the configuration
prefix = config.getStrInterpolator().create(ConfigStrLookup.from(config)).resolve(prefix);
if (!prefix.isEmpty() && !prefix.endsWith("."))
prefix += ".";
// Iterate and set fields
if (configAnnot.allowFields()) {
for (Field field : injecteeType.getDeclaredFields()) {
if ( Modifier.isFinal(field.getModifiers())
|| Modifier.isTransient(field.getModifiers())
|| Modifier.isStatic(field.getModifiers())) {
continue;
}
String name = field.getName();
Class<?> type = field.getType();
Object value = null;
if (type.isInterface()) {
// TODO: Do Class.newInstance() if objName is a classname
String objName = config.getString(prefix + name, null);
if (objName != null) {
value = ioc.getInstance(objName, type);
}
}
else {
value = config.get(type, prefix + name, null);
}
if (value != null) {
try {
field.setAccessible(true);
field.set(injectee, value);
} catch (Exception e) {
throw new MappingException("Unable to inject field " + injectee.getClass() + "." + name + " with value " + value, e);
}
}
}
}
// map to setter methods
if (configAnnot.allowSetters()) {
for (Method method : injectee.getClass().getDeclaredMethods()) {
// Only support methods with one parameter
// Ex. setTimeout(int timeout);
if (method.getParameterCount() != 1) {
continue;
}
// Extract field name from method name
// Ex. setTimeout => timeout
String name = method.getName();
if (name.startsWith("set") && name.length() > 3) {
name = name.substring(3,4).toLowerCase() + name.substring(4);
}
// Or from builder
// Ex. withTimeout => timeout
else if (name.startsWith("with") && name.length() > 4) {
name = name.substring(4,1).toLowerCase() + name.substring(5);
}
else {
continue;
}
method.setAccessible(true);
Class<?> type = method.getParameterTypes()[0];
Object value = null;
if (type.isInterface()) {
String objName = config.getString(prefix + name, null);
if (objName != null) {
value = ioc.getInstance(objName, type);
}
}
else {
value = config.get(type, prefix + name, null);
}
if (value != null) {
try {
method.invoke(injectee, value);
} catch (Exception e) {
throw new MappingException("Unable to inject field " + injectee.getClass() + "." + name + " with value " + value, e);
}
}
}
}
if (!configAnnot.postConfigure().isEmpty()) {
try {
Method m = injecteeType.getMethod(configAnnot.postConfigure());
m.invoke(injectee);
} catch (Exception e) {
throw new MappingException("Unable to invoke postConfigure method " + configAnnot.postConfigure(), e);
}
}
}