Olá Pessoal, tudo bem com vocês?
Eu estou desenvolvendo um Plugin para o Eclipse(Helios), cujo objetivo é interpretar as anotações de um projeto-alvo e gerar arquivos dentro do mesmo, a partir dessas informações.
Por exemplo: Digamos que, ao clicar com o botão direito em cima de um projeto, o plugin apareça como uma opção de menu . Após clicar nessa opção, o plugin interpretaria todas as anotações do tipo @AnnotationX presentes no projeto-alvo, e geraria arquivos de acordo com as informações que ele encontraria nessas annotations.
Para carregar as classes do projeto-alvo, eu utilizo um URLClassLoader com o classpath dele. Com isso eu consigo carregar os objetos Class através do Classloader, mas aí que ocorre o problema: Quando tento manipular o @AnnotationX via reflection, eu não consigo capturar as informações que haviam nela pq eu não consigo atribuir a mesma para um tipo conhecido no meu projeto
AnnotationX minhaAnotacao = (AnnotationX) annotation; <- Ocorre um ClassCastException.
A minha pergunta então é a seguinte:
Tanto o projeto-alvo, quanto o meu plugin, irão conter um .jar com esse mesmo conjunto de anotações que eu defini. Logo, a anotação que o usuário vai definir no projeto dele, vai ser a mesma (fisicamente) que estará no meu plugin.
Existe alguma forma de eu realizar esse Cast? Sugestões??
Obrigado!!!
Não existe forma de dar esse cast.
Mas você não deve carregar as classes dessa forma. A maneira ideal de fazer isso é usar a API Java do eclipse para pegar as estruturas de classes que ele monta… e não pegar o .class compilado e tentar dar um load…
Vai ser um pouco mais complicado, mas é a maneira ideal…
Obrigado @rogelgarcia,
Então eu posso pegar os annotations de um método via API do eclipse?
Abs.
Sim… o eclipse tem APIs que retornam a estrutura da classe… mesmo antes de ela virar um .class.
Com essa estrutura você consegue pegar as informações que deseja.
Alguns códigos que podem te ajudar (tive que recortar de uns códigos que eu tenho aqui … mas acho que te dá uma luz):
IJavaProject jproject = (consiga o IJavaProject de algum lugar);
IPackageFragment[] pkgs = jproject.getPackageFragments();
for (IPackageFragment pkg : pkgs) {
ICompilationUnit[] compUnits = pkg.getCompilationUnits();
for (ICompilationUnit compUnit : compUnits) {
CompilationUnit ast = getAst(compUnit);
Com esse objeto ast aí… vc pega tudo da classe… exemplo:
for(AbstractTypeDeclaration type : (List<AbstractTypeDeclaration>)ast.types())
if(type instanceof TypeDeclaration) {
TypeDeclaration td = (TypeDeclaration)type;
if(td.resolveBinding().getKey().equals("Classe que eu quero")) { //esse resolveBinding() acho que você nao precisará executar...
Para transformar um ICompulationUnit em um CompilationUnit:
public static CompilationUnit getAst(ICompilationUnit compUnit, boolean resolveBindings) {
ASTParser astParser = ASTParser.newParser(AST.JLS3);
astParser.setResolveBindings(true);
astParser.setBindingsRecovery(true);
astParser.setStatementsRecovery(true);
astParser.setSource(compUnit);
return (CompilationUnit) astParser.createAST(null);
//return SharedASTProvider.getAST(compUnit, SharedASTProvider.WAIT_YES, new NullProgressMonitor());
}