T instance;
try {
Constructor<T> constructor = fixedFormatRecordClass.getConstructor();
instance = constructor.newInstance();
} catch (NoSuchMethodException e) {
throw new FixedFormatException(format("%s is missing a default constructor which is nessesary to be loaded through %s", fixedFormatRecordClass.getName(), getClass().getName()));
} catch (Exception e) {
throw new FixedFormatException(format("unable to create instance of %s", fixedFormatRecordClass.getName()), e);
}
//look for setter annotations and read data from the 'data' string
Method[] allMethods = fixedFormatRecordClass.getMethods();
for (Method method : allMethods) {
String methodName = stripMethodPrefix(method.getName());
Field fieldAnnotation = method.getAnnotation(Field.class);
Fields fieldsAnnotation = method.getAnnotation(Fields.class);
if (fieldAnnotation != null) {
Object loadedData = readDataAccordingFieldAnnotation(data, method, fieldAnnotation);
foundData.put(methodName, loadedData);
} else if (fieldsAnnotation != null) {
//assert that the fields annotation contains minimum one field anno
if (fieldsAnnotation.value() == null || fieldsAnnotation.value().length == 0) {
throw new FixedFormatException(format("%s annotation must contain minimum one %s annotation", Fields.class.getName(), Field.class.getName()));
}
Object loadedData = readDataAccordingFieldAnnotation(data, method, fieldsAnnotation.value()[0]);
foundData.put(methodName, loadedData);
}
}
Set<String> keys = foundData.keySet();
for (String key : keys) {
String setterMethodName = "set" + key;
Object foundDataObj = foundData.get(key);
if (foundDataObj != null) {
Class datatype = foundData.get(key).getClass();
Method method;
try {
method = fixedFormatRecordClass.getMethod(setterMethodName, datatype);
} catch (NoSuchMethodException e) {
throw new FixedFormatException(format("setter method named %s.%s(%s) does not exist", fixedFormatRecordClass.getName(), setterMethodName, datatype));
}
try {
method.invoke(instance, foundData.get(key));
} catch (Exception e) {
throw new FixedFormatException(format("could not invoke method %s.%s(%s)", fixedFormatRecordClass.getName(), setterMethodName, datatype), e);
}
}
}
return instance;