2012-05-14 28 views
12

Tengo muchas clases de controlador que manejan tipos de mensajes específicos. Para registrar todos estos manejadores, necesito saber cuáles existen. Actualmente, están todos anotados con una anotación específica, y utilizo un procesador de anotación Java 6 para obtenerlos todos, y hago una clase Register que contiene una instancia de cada uno de los tipos anotados.¿Cómo puedo examinar todo el árbol de fuentes con un procesador de anotaciones?

Esto funciona muy bien si todo el árbol se está construyendo a la vez, pero si solo se está construyendo una de las clases anotadas (cuando guardo el archivo en Eclipse, por ejemplo), el procesador solo ve ese tipo y construye un registro incompleto ¿Cómo puedo examinar los otros tipos en este escenario?

+0

¿Qué procesador de anotaciones está utilizando? –

+0

Uno lo escribí yo mismo, usando la API Java 6 (extendiendo javax.annotation.processing.AbstractProcessor) –

+0

+1. De mis propias investigaciones esto no está disponible, pero si lo es, realmente me gustaría saberlo. –

Respuesta

6

He resuelto esto bastante bien por ahora. Lo que hice fue un poco hackey, pero básicamente para cada clase anotada que veo, agrego su nombre a un HashSet. Luego uso Filer.getResource() para abrir un archivo en el que grabé todas las clases comentadas previamente, y también las agregué al HashSet. Luego genero la clase de registro y escribo todo el HashSet en el mismo recurso con Filer.createResource(). Esto causará problemas si elimino un tipo anotado, ya que aún se grabará en ese archivo, pero puedo simplemente limpiar el proyecto o eliminar ese archivo para resolverlo.

EDITAR: Además, creo que al pasar los "elementos de origen" apropiados a Filer.createSource() debería permitir que Eclipse rastree esas dependencias correctamente, pero no es así. Quizás sea un error de Eclipse.

+0

¿tiene este código compartido en alguna parte? Estoy interesado en tu enfoque. –

+0

Este es código propiedad de la compañía, pero si alguna vez escribo algo así para un proyecto personal, estará disponible –

+0

He escrito una [biblioteca genérica] (https://github.com/sentinelt/evo-classindex) para esta. Encontré esta página, porque mi biblioteca sufre el mismo problema ... –

1

Como era de esperar, los procesadores de anotaciones en tiempo de compilación solo procesan los archivos que se compilan. Eclipse utiliza la compilación incremental para ahorrar tiempo, por lo que la respuesta corta es que no puede esperar que su procesador de anotación vea todos los tipos en una sola pasada.

Una solución es cambiar su arquitectura para admitir la compilación incremental. Por ejemplo, para cada HandlerClass con anotaciones, genere una clase RegisterHandlerClass que registre esa clase de controlador.

Dicho esto, parece que lo que está haciendo sería mejor hacerlo en tiempo de ejecución, quizás con la ayuda de una herramienta como Reflections.

+1

Este es el código de Android, y parece que la mayoría de esos marcos no funcionan en Android; en cualquier caso, me gustaría evitar el escaneo classpath si es posible. Si fui a la ruta RegisterHandlerClass, ¿cómo sería exactamente eso ayuda? ¿Cómo podría obtener esas clases para registrar la clase de controlador apropiado, sin tener un "registro de registros" por así decirlo? –

+0

Si el problema es que Handler Classes no se está cargando, entonces mi idea de RegisterHandlerClass tampoco funcionará. En su lugar, podría crear un archivo de recursos por Handler Class y colocarlos en el mismo directorio y luego escanear ese directorio en tiempo de ejecución. –

Cuestiones relacionadas