Já tentei adaptar algumas das soluções que achei no fórum mas todas sem sucesso
Tenho um projeto organizado da seguinte forma:
projeto: módulo onde fica toda a lógica de negócio projeto-web: cuida da apresentação utilizando o módulo “projeto”
Dentro do módulo projeto tenho as seguintes classes:
public interface Autor {
}
public class AutorUm implements Autor {
}
public class AutorDois implements Autor {
}
public class Documento {
private Autor autor;
public Autor getAutor() {
return autor;
}
public void setAutor(Autor autor) {
this.autor = autor;
}
}
E no módulo responsável pela apresentação (projeto-web - onde se encontra o VRaptor) tenho o seguinte:
@Resource
public class DocumentoController {
public void criarNovoDocumento(Documento documento) {
//lógica...
}
}
@Resource
public class Usuario {
private String nome;
private String senha;
private Autor autor;
}
Quando o usuário loga no sistema, ele pode ser um autor do tipo Um ou do tipo Dois.
O problema acontece justamente quando invoco o método criarNovoDocumento do Controller, lançando uma exception parecida com:
br.com.caelum.iogi.exceptions.InvalidTypeException: Cannot instantiate abstract type interface Autor
Trouxe aqui uma representação simplificada do contexto todo, mas minha duvida é a seguinte: por que o VRaptor está tentando instanciar a interface? Ele não deveria simplesmente pegar a instância de Documento (passada no método criarNovoDocumento) e chamar o setAutor passando o valor convertido do campo autor na JSP?
Já tentei usar um Converter e um ComponentFactory e até seguir os passos de alguns outros tópicos que encontrei aqui e nada até o momento.
Então cara, esse é só um projeto de estudo no qual estou experimentando várias coisas juntas, mas enfim… por enquanto o tipo de autor é settado durante o login mesmo, se o nome de usuário for usuarioum, por exemplo, uma instância de UsuarioUm é settada ao atributo autor da classe Usuario e assim também funciona para o UsuarioDois, mais ou menos assim:
@Resource
public class UsuarioController {
@Post
public void login(Usuario usuario) {
if (usuario.getNome().equals("usuarioum")) {
usuario.setAutor(new AutorUm());
} else if (usuario.getNome().equals("usuariodois")) {
usuario.setAutor(new AutorDois());
}
/*[...]*/
}
}
E na hora de montar a JSP eu atribuo o autor do usuário logado ao value do campo da JSP.
Bem estranho mesmo essa estrutura, mas não consegui bolar uma outra forma de implementar isso ainda
Até pensei em settar o autor do documento no método criarNovoDocumento do Controller, mas também existe um caso em que um usuário logado não pode ser o autor de um documento, ao invés disso ele precisa selecionar um autor numa combo, que nesse caso seria exibida no lugar o input text
Se não fosse por esse caso, poderia colocar o usuário logado como autor do documento sem problemas, mas e nesse caso da combo?
Acho que entendi o que quiz dizer, mas nesse caso especifico cada implementação de autor representa uma entidade diferente no sistema, como por exemplo:
Digamos que AutorUm seja uma pessoa física e AutorDois um comitê formado por varias pessoas e que a interface Autor, implementada por ambas as classes, possua dois métodos getNome() e getAssinatura() que em AutorUm devolve apenas o nome da pessoa para ambos os métodos, mas que em AutorDois devolve o nome do comitê para o método getNome() e o nome de seus integrantes para o método getAssinatura().
Assim quando eu tiver um documento no qual o autor é do tipo AutorUm e os métodos documento.getAutor().getNome() e documento.getAutor().getAssinatura() forem respectivamente chamados o resultado seria algo como:
Autor: nome da pessoa
Assinatura: nome da pessoa
Já no caso de um documento com um autor do tipo dois:
Autor: comitê um
Assinatura: nome primeira pessoa
nome segunda pessoa
nome terceira pessoa
[…]
Ter apenas uma classe concreta para representar os autores ainda funcionaria nesse caso?
Realmente tentando explicar agora o processo pareceu meio estranho, vou ver se consigo repensar esse design, mas desde já muito obrigado pela ajuda e paciência.
O que você disse Lucas faz todo sentido, não sei por que fiquei fissurado nas interfaces e não percebi isso ;-(
Mas só por curiosidade, o VRaptor sempre tentará instanciar um objeto para então settar seus atributos? Mesmo se eu passar um objeto inteiro (através de uma combo por exemplo)?