Salve, galera!
Não sei se aqui é o espaço ideal para discutir isso, mas a questão é que há um tempo venho querendo contribuir com o vRaptor, tanto por uma questão de aprendizado pessoal quanto pelo fato de eu o considerar um dos melhores frameworks MVC para Java.
Há um recurso novo no mais recente release dele que é a anotação @Load nos parâmetros dos métodos dos controladores, que faz com que uma entidade com um atributo “id” seja automagicamente carregada do banco de dados, dispensando a necessidade de criar mais código, como um DAO, para essa tarefa.
Por debaixo dos panos, o que o framework faz é recuperar o parâmetro “id” da entidade e, através de um EntityManager, mandar um “find” e recuperá-la.
Achei muito bacana, porém vejo que há situações em que seria necessário fazer mais que simplesmente chamar um “em.find()”. Por exemplo, nas situações em que é necessário preencher alguma dependência dessa entidade, ou realizar algum processamento sobre ela.
Um bom exemplo disso é essa discussão no blog da Caelum, sobre o uso do padrão Repository, que exigiria injetar uma classe que implementasse esse padrão na entidade recuperada, mais ou menos assim:
[code]public class XuxuRepository {
@PersistenceContext
private EntityManager em;
public Xuxu buscar(Object id) {
Xuxu xuxu = em.find(Xuxu.class, id);
xuxu.setRepository(this);
return xuxu;
}
}[/code]
O que eu pensei em implementar seria uma outra anotação, que chamei de @LoadWith, que receberia como parâmetro um “.class” de uma classe-fábrica, talvez implementando uma interface específica e que, instanciando-a, delegaria a ela a carga dessa entidade. Ficaria mais ou menos assim:
[code]// assumindo que cada classe dessa se encontra em um arquivo separado, com os devidos “imports” e demais firulas
public interface Loader<T> {
T load(Object id);
}
public @interface LoadWith {
Class<?> value();
}
public class XuxuLoader implements Loader<Xuxu> {
private XuxuRepository repository; // como ele veio parar aqui já é uma outra história...
Xuxu load(Object id) {
return repository.buscar(id);
}
}
[/code]
E num método de um controlador qualquer:
[code]@Resource
public class XuxuController {
public void detalhar(@LoadWith(XuxuLoader.class) Xuxu xuxu);
}[/code]
A questão é que eu tenho dificuldade de imaginar como implementar isso… porque eu não tenho experiência ainda com contribuição para projetos de código aberto. :oops:
Eu sei que a classe responsável pera mágica é essa aqui. Mas estou com dificuldade em compreender exatamente como o método intercept() funciona, e como refatorá-lo para essa nova funcionalidade.
Como posso começar?