do {
Field[] fields = objectToConfigureClass.getDeclaredFields();
for (Field field : fields) {
try {
if (field.isAnnotationPresent(Configuration.class)) {
Configuration configurationAnnotation = field.getAnnotation(Configuration.class);
String expression = "".equals(configurationAnnotation.value()) ? field.getName() : configurationAnnotation.value();
field.setAccessible(true);
Class<?> fieldType = field.getType();
if (hasValue(expression)) {
ConfigurationValue node = findElementOrThrowException(expression);
if (fieldType.isAssignableFrom(List.class)) {
field.set(objectToConfigure, evaluateToList(getCollectionFieldType(field), expression));
} else if (fieldType.isAssignableFrom(Map.class)) {
field.set(objectToConfigure, evaluateToMap(getMapKeyFieldType(field), getMapValueFieldType(field), expression));
} else {
field.set(objectToConfigure, processAndConvert(fieldType, expression));
}
} else {
if (hasAnnotationDefaults(configurationAnnotation)) {
if (configurationAnnotation.defaultValueFactory().equals(Configuration.EmptyValueFactory.class)) {
field.set(objectToConfigure, ValueConverterRegistry.convert(fieldType, fieldType, new CPrimitive(configurationAnnotation.defaultValue())));
} else {
ConfigurationDefaultValueFactory valueFactory = configurationAnnotation.defaultValueFactory().newInstance();
field.set(objectToConfigure, valueFactory.getDefaultValue());
}
} else if (configurationAnnotation.required()) {
throw new ConstrettoException("Missing value or default value for expression [" + expression + "] for field [" + field.getName() + "], in class [" + objectToConfigure.getClass().getName() + "] with tags " + currentTags + ".");
}
}
} else if (field.isAnnotationPresent(Tags.class)) {
field.setAccessible(true);