Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Sugestão] Refatoração para tratamento do acesso a campos privados. Tratando o

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;
    }

https://github.com/phenriqued/alura-transformator

1 resposta
solução!

Olá Pedro! Como vai?

Achei sua sugestão de refatoração muito interessante! A ideia de fazer o método validate retornar um booleano é uma ótima forma de garantir que apenas os campos correspondentes e acessíveis sejam manipulados. Isso pode ajudar a evitar exceções indesejadas e tornar o código mais robusto.

Bons estudos!