Fala pessoal, tudo bem?
Eu estava olhando o meu projeto e eu percebi que tenho 20 funcionalidades “idênticas” onde estou tendo mais de 60 telas… gostaria de fazer algo mais genérico…
Eu estou apanhando um pouco… Por exemplo, o meu DAO, por ser genérico, tem que receber a Classe que ele vai fazer as coisas… Existe alguma forma do VRaptor entregar para ele qual classe é? (Estava pensando em passar o nome dela por parâmetro no “/path”)
Por exemplo:
o link /tabelas/arquivo/novo iria exibir o formulario para a inserção de um novo arquivo…
meu @Path ficaria assim:
@Get("/tabelas/{funcionalidade}/novo")
Existe alguma forma de fazer isso?
o VRaptor não vai conseguir injetar a classe no seu DAO genérico do jeito que vc quer, mas vc pode criar os específicos e anotá-los com @Component.
vc pode criar um Controller genérico e os controllers específicos herdando dele, e só os específicos anotados com @Resource.
se vc fizer o @Get("/tabelas/{funcionalidade}/novo") vc que vai ter que fazer o trabalho de despachar a requisição pro lugar certo… e o VRaptor já faz isso pra vc.
Na verdade eu gostaria de ter somente 3 JSPs, 1 Controller e 1 DAO. Para todas as 20 funcionalidades…
Mas eu precisava de alguma forma de saber qual funcionalidade está sendo chamada…
E o conteúdo varia de acordo com as tabelas… Mas ai eu não posso usar a passagem de parâmetros para a JSP através do retorno do método… E sim pelo result.include…
Não acho que isso seja legal, mas enfim:
@Path("/tabelas/{funcionalidade}/novo")
public void novo(String funcionalidade) {
//lógica bizarra pra descobrir como fazer...
}
dá pra vc receber uma Class<?>, se vc criar um converter:
@Convert(Class.class)
public class ClassConverter implements Converter<Class> { // do vraptor
public Class convert(String value, ...) {
//converta a string para a class da sua funcionalidade
}
}
@Path("/tabelas/{funcionalidade}/novo")
public void novo(Class funcionalidade) {
...
}
se vc chamar a URI /tabelas/CadastroMagico/novo, no converter vc teria disponível a string value = “CadastroMagico”.
Have fun 
Só uma curiosidade… Se eu tentar receber essa class no construtor… dá certo se eu usar o converter?
Acredito que não tem nada a ver… Mas vale a pena tentar… 
Por que eu queria poder enviar para o construtor do controller qual a funcionalidade…
A verdade é que as funcionalidades são MUITO iguais… só muda o título e a tabela aonde o hibernate vai buscar as informações…
até dá…
mas não vai ser com o converter…
crie esse componente:
@Component
public class Maroto {
public Maroto(HttpServletRequest request) {
this.classe = transformaEmClasse(request.getParameter("funcionalidade"));
}
//getClasse
//transformaEmClasse
}
e receba esse componente no construtor do controller…
vc até pode fazer esse componente ser um ComponentFactory e receber a Class no controller, só é um pouco mais bizarro 
Para eu receber essa funcionalidade pelo HttpServletRequest, eu preciso informá-la por um input hidden ou o VRaptor também entende se eu passá-la pela URL, assim:
/tabelas/{funcionalidade}/novo
se vc passar pela url tb funciona
Fiz os testes aqui e funciona tudo direitinho… mas eu estou com problemas para usar o result.redirectTo();
Pois aparentemente ele não carrega o valor da funcionalidade… É isso mesmo? Eu perco o valor que estava antes?
ele não vai perder, se vc fizer um redirect para uma lógica anotada com @Path("…/{funcionalidade}/…")
Edit: falei besteira… ele vai perder sim =/
o VRaptor preenche esses parâmetros da url com o que vc passou por parâmetro no redirectTo…
dá pra fazer isso funcionar, mas vc vai ter que sobrescrever um componente do VRaptor.
é algo parecido com isso:
só que ao invés de tenant.name seria a funcionalidade.
com esse componente vc nem precisa colocar o “/tabela/{funcionalidade}” antes de todos paths
Mas então, como que eu vou informar qual a é a funcionalidade corrente?
Eu consegui da seguinte forma:
No meu factory de Funcionalidade eu vejo se o que veio é vazio e ele devolve a última preenchida…
Funciona, mas me interessei por esse componente…
então, se vc der uma olhada no método urlFor do gist que eu te passei, ele coloca o tenantPrefix(), usando o tenant.name que está na request atual.
é só vc mudar isso pra pegar a “funcionalidade” da request atual.