2012-05-14 10 views
12

Ho molte classi di gestori che gestiscono tipi di messaggi specifici. Per registrare tutti questi gestori, ho bisogno di sapere quali esistono. Attualmente sono tutti annotati con un'annotazione specifica e io uso un processore di annotazioni Java 6 per ottenerli tutti e creare una classe Register che contenga un'istanza di ciascuno dei tipi annotati.Come posso esaminare l'intero albero dei sorgenti con un processore di annotazioni?

Questo funziona perfettamente se l'intero albero viene creato contemporaneamente, ma se viene costruita una sola delle classi annotate (quando salvo il file in Eclipse, ad esempio), il processore vede solo quel tipo e le build un registro incompleto. Come posso esaminare gli altri tipi in questo scenario?

+0

Quale processore di annotazione stai utilizzando? –

+0

Uno mi sono scritto, utilizzando l'API Java 6 (estensione javax.annotation.processing.AbstractProcessor) –

+0

+1. Dalle mie indagini questo non è disponibile, ma se lo fosse, mi piacerebbe davvero saperlo. –

risposta

6

L'ho risolto abbastanza bene per ora. Quello che ho fatto è un piccolo hackey, ma fondamentalmente per ogni classe annotata che vedo, aggiungo il suo nome ad un HashSet. Quindi utilizzo Filer.getResource() per aprire un file in cui sono state registrate tutte le classi annotate precedentemente visualizzate e le ho aggiunte anche all'HashSet. Quindi creo la classe di registro e scrivo l'intero HashSet alla stessa risorsa con Filer.createResource(). Ciò causerà problemi se elimino un tipo annotato, poiché verrà comunque registrato in quel file, ma posso semplicemente pulire il progetto o eliminare quel file per risolverlo.

EDIT: Inoltre, credo che il passaggio degli "elementi di origine" appropriati a Filer.createSource() dovrebbe consentire a Eclipse di tracciare correttamente tali dipendenze, ma non lo fa. Forse è un bug di Eclipse.

+0

ti capita di avere questo codice condiviso ovunque? Sono interessato al tuo approccio. –

+0

Questo è un codice di proprietà dell'azienda, ma se mai scriverò qualcosa del genere per un progetto personale sarà disponibile –

+0

Ho scritto una [biblioteca generica] (https://github.com/sentinelt/evo-classindex) per Questo. Ho trovato questa pagina, perché la mia biblioteca soffre dello stesso problema ... –

1

Non sorprende che i processori di annotazione in fase di compilazione elaborino solo i file in fase di compilazione. Eclipse utilizza la compilazione incrementale per risparmiare tempo, quindi la risposta breve è che non è possibile aspettarsi che il proprio processore di annotazioni visualizzi tutti i tipi in un'unica passata.

Una soluzione è modificare l'architettura per supportare la compilazione incrementale. Ad esempio, per ogni annotazione HandlerClass, generare una classe RegisterHandlerClass che registri quella classe del gestore.

Detto questo, sembra che ciò che si sta facendo sarebbe meglio farlo in fase di esecuzione, magari con l'aiuto di uno strumento come Reflections.

+1

Questo è il codice Android, e sembra che molti di questi framework non funzionino su Android; in ogni caso, vorrei evitare la scansione del classpath se possibile. Se ho seguito la rotta RegisterHandlerClass, come sarebbe esattamente questo? Come potrei ottenere che quelle classi registrino la classe di handler appropriata, senza avere un "registro dei registri" per così dire? –

+0

Se il problema è che le classi di Handler non vengono caricate, anche la mia idea RegisterHandlerClass non funzionerà. Potresti invece creare un file di risorse per Classe di Handler e inserirli tutti nella stessa directory e quindi scansionare quella directory in fase di runtime. –