No projeto atual no método transform
da classe Transformator
, há o método validate
que por sua vez tem .setAccessible(true);
que garante que os campos sejam acessíveis antes da tentativa de atribuição do targetField.set(targetClass, sourceField.get(input));
e quando os campos privados não são iguais não fica acessível resultando no IllegalAccessException.
Caso você queira tratar ou refatorar eu proponho introduzir no método validate
que este retorne um boolean e haja uma condição targetField.set(targetClass, sourceField.get(input));
. Assim, garante que a atribuição de valores seja realizada apenas em campos correspondentes e acessíveis.
Projeto Atual
public <I, O> O transform(I input) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<?> source = input.getClass();
Class<?> target = Class.forName(source.getName() + "DTO");
O targetClass = (O) target.getDeclaredConstructor().newInstance();
Field[] sourceFields = source.getDeclaredFields();
Field[] targetFields = target.getDeclaredFields();
Arrays.stream(sourceFields).forEach(sourceField ->
Arrays.stream(targetFields).forEach(targetField -> {
validate(sourceField, targetField);
try {
targetField.set(targetClass, sourceField.get(input));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}));
return targetClass;
}
private void validate(Field sourceField, Field targetField) {
if (sourceField.getName().equals(targetField.getName())
&& sourceField.getType().equals(targetField.getType())) {
sourceField.setAccessible(true);
targetField.setAccessible(true);
}
}
}
Refatorando o código:
public <I, O> O transformer(I input) throws Exception {
Class<?> source = input.getClass();
Class<?> target = Class.forName(source.getName().concat("DTO"));
O targetClass = (O) target.getDeclaredConstructor().newInstance();
Field[] sourceFields = source.getDeclaredFields();
Field[] targetFields = target.getDeclaredFields();
Arrays.stream(sourceFields).forEach(sourceField ->
Arrays.stream(targetFields).forEach(targetField -> {
try{
if(validate(sourceField, targetField)){
targetField.set(targetClass, sourceField.get(input));
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}));
return targetClass;
}
private boolean validate(Field sourceField, Field targetField){
if(sourceField.getName().equals(targetField.getName()) &&
sourceField.getType().equals(targetField.getType())){
sourceField.setAccessible(true);
targetField.setAccessible(true);
return true;
}
return false;
}