|
Tutorial Annotation JDK 1.5: traitement au moment du build
|  |
1- Les annotations Développeur et Todo
Un développeur est identifié par son prénom et nom de famille.
package com.btc.tutorial.todo;
import java.lang.annotation.*;
@Retention(RetentionPolicy.CLASS)
@Target ({ElementType.ANNOTATION_TYPE})
public @interface Développeur {
String prénom();
String nomDeFamille();
}
|
| Fichier: Développeur.java |
L'annotation Todo possède une valeur enumérée (nouveauté JDK 1.5) et une référence sur une annotation du type Développeur.
Les enum sont une nouveauté du JDK 1.5.
package com.btc.tutorial.todo;
public @interface Todo {
public enum Severité{ CRITIQUE, IMPORTANT, TRIVIALE, DOCUMENTATION };
Severité severité() default Severité.IMPORTANT;
String quoi();
Développeur qui();
} |
| Fichier: Todo.java |
2- Spécification des anotations dans la classe Entreprise
Nous ajoutons une annotation Todo sur la classe et une autre sur une méthode.
Remarquez la syntaxe de la déclaration Développeur imbriquée dans l'annotation Todo.
package com.btc.tutorial.todo;
@Todo (
severité=Todo.Severité.CRITIQUE,
quoi="Ajouter la liste des employés",
qui = @Développeur (prénom = "Thibault", nomDeFamille="Cuvillier")
)
public class Entreprise {
private String nom;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
@Todo (
quoi="Corriger ce code incompréhensible!",
qui = @Développeur (prénom = "Thibault", nomDeFamille="Cuvillier")
)
public void horreur() {
int i = 0;
i = ++i+i++;
}
} |
| Fichier: Todo.java |
3- Accéder aux annotation avec APT
apt est un nouveau utilitaire du JDK 1.5. Il permet de déclencher du code Java permettant de traiter les annotations placées dans les sources.
Pour traiter les annotations Todo de notre exemple, nous devons fournir une fabrique (factory) permettant de créer des Processeurs d'annotation.
Les processeurs d'annotation accèdent aux éléments annotés du code Java par un visiteur. Le visiteur possède une série de méthode déclenchées selon le type de l'élément: classe, méthode, constructeur ou autre.
package com.btc.tutorial.todo;
import com.sun.mirror.declaration.*;
import com.sun.mirror.util.*;
import com.sun.mirror.apt.*;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.type.*;
import com.sun.mirror.util.*;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
import static java.util.Collections.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
import java.util.*;
// Cette classe permet de créer des processeurs d'annotation.
public class TodoFabrique implements AnnotationProcessorFactory {
// Taiter les annotations du package com.btc.tutorial.todo
private static final Collection supportedAnnotations
= unmodifiableCollection(Arrays.asList("com.btc.tutorial.todo.*"));
// Options (voir la doc pour + d'info)
private static final Collection supportedOptions = emptySet();
public Collection supportedAnnotationTypes() {
return supportedAnnotations;
}
public Collection supportedOptions() {
return supportedOptions;
}
// Récupérer le processeur d'annotation
public AnnotationProcessor getProcessorFor(
Set atds,
AnnotationProcessorEnvironment env) {
return new TodoProcesseur(env);
}
// La classe traitant les annotations
private static class TodoProcesseur implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
TodoProcesseur(AnnotationProcessorEnvironment env) {
this.env = env;
}
// Traiter les annotations d'une classe
public void process() {
for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
System.out.println("process called: accept");
// Lancer un visiteur
typeDecl.accept(getDeclarationScanner(new TodoVisiteur(),NO_OP));
}
}
// Le visiteur qui se promène sur le code Java
private static class TodoVisiteur extends SimpleDeclarationVisitor {
// Déclenchée lors de la déclaration d'une classe ayant une annotation Todo
public void visitClassDeclaration(ClassDeclaration d) {
Todo todo = d.getAnnotation(Todo.class);
if( todo == null ) return;
System.out.println(todo.qui().prénom() + " " +
todo.qui().nomDeFamille() + " doit " +
todo.quoi() + " dans la classe " +
d.getQualifiedName());
}
// Déclenchée lors de la déclaration d'une méthode ayant une annotation Todo
public void visitMethodDeclaration(MethodDeclaration methodDeclaration) {
Todo todo = methodDeclaration.getAnnotation(Todo.class);
if( todo == null ) return;
System.out.println(todo.qui().prénom() + " " +
todo.qui().nomDeFamille() + " doit " +
todo.quoi() + " dans la méthode " +
methodDeclaration.getSimpleName());
}
}
}
}
|
| Fichier: TodoFabrique.java |
Votre visiteur peut ainsi générer des fichiers sources ou fichiers de configuration à partir des annotations.
Voici la commande permettant de lancer l'outil apt:
apt -factory com.btc.tutorial.todo.TodoFabrique -cp classes src\com\btc\tutorial\todo\Entreprise.java
- -factory com.btc.tutorial.todo.TodoFabrique: la fabrique d'annotation
- -cp classes: le classpath permettant de trouver la fabrique
- Les derniers arguments sont les fichiers Java à traiter
Documentation SUN sur apt et l'API de traitement des annotations.
Résultat:
$ apt -factory com.btc.tutorial.todo.TodoFabrique -cp classes src\com\btc\tutorial\todo\Entreprise.java
process called: accept
Thibault Cuvillier doit Ajouter la liste des employés dans la classe com.btc.tutorial.todo.Entreprise
Thibault Cuvillier doit Corriger ce code incompréhensible! dans la méthode horreur
$
Pour compléter ce tutorial, vous pouvez lire des articles sur le sujet 
|