前回は,アノテーションプロセッサの基本的な使い方について解説しました。今回は本格的にアノテーション処理を行う時に必要な準備に関して紹介します。
メッセージの出力
アノテーションプロセッサはjavacコマンドによって実行することは前回説明しました。せっかくjavacコマンドで実行するのですから,出力もjavacコマンドと同様にしたいところです。
たとえば,アノテーションの処理中に何らかのエラーが見つかった場合,javacコマンドのコンパイルエラーと同様に出力したくなりますよね。このような用途に使えるのが,javax.annotation.processing.Messagerインタフェースです。
ここでは,先週使用したInfoアノテーションとInfoProcessorクラスにMessagerインタフェースを組み込んでいきましょう。
Messagerオブジェクトを取得するには,javax.annotation.processing.ProcessingEnvironmentインタフェースのgetMessagerメソッドを使用します。しかし,その前にProcessingEnvironmentオブジェクトはどこから取得するのかと思われるかもしれません。
ProcessingEnvironmentオブジェクトはjavax.annotation.processing.AbstractProcessorクラスのprocessingEnvフィールドで定義されています。processingEnvフィールドのアクセス修飾子はprotectedなので,AbstractProcessorクラスを派生させたアノテーションプロセッサであれば,processingEnvフィールドにアクセスすることができます。
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes("Info")
public class InfoProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnvironment) {
// Messager オブジェクトの取得
Messager messager = processingEnv.getMessager();
for(TypeElement annotation : annotations) {
// annotation が使用されている要素を取得
Set elements
= roundEnvironment.getElementsAnnotatedWith(annotation);
for (Element element: elements) {
// Info アノテーションを取得
Info info = element.getAnnotation(Info.class);
try {
messager.printMessage(
Diagnostic.Kind.NOTE,
"Info at " + element
+ "\n value: " + info.value());
} catch (IncompleteAnnotationException ex) {
messager.printMessage(
Diagnostic.Kind.ERROR,
"Info アノテーションに value 要素がありません",
element);
}
}
}
return true;
}
}
赤字で記述してある部分がMessageオブジェクトを取得している部分です。