先月はアノテーションを処理するためのクラスや,処理に使用する補助的なクラスなどを紹介しました。
アノテーションを処理するにはjavax.annotation.processing.Processorインタフェースを使用し,プログラムの要素はjavax.lang.elementパッケージおよびjavax.lang.typeパッケージで定義されたインタフェース群を使用することはわかりました。しかし,実際にアノテーションを処理しろといわれても,どうやってやればいいのか途方に暮れてしまうのではないでしょうか。
そこで,今月はサンプルを使用しながら,実際にアノテーションを処理していくことにします。
今週は,特定のクラスからインタフェースを作成するアノテーションプロセッサを作っていきます。
はじめに処理をするアノテーションについて説明しておきます。
このサンプルで使用するアノテーションはAbstractionアノテーションとAbstractionMethodアノテーションです。両方ともマーカアノテーションであり,要素は持ちません。
Abstractionアノテーションがクラスを修飾し,AbstractionMethodアノテーションがメソッドを修飾します。例えば,以下のように使用します。
@Abstraction
public class Sample {
private String value;
public Sample() {}
@AbstractionMethod
public void setValue(String value) {
this.value = value;
}
@AbstractionMethod
public String getValue() {
return value;
}
}
Abstractionアノテーションが修飾したクラスを基にインタフェースを作成し,AbstractionMethodアノテーションで修飾したメソッドをインタフェースで定義します。つまり,以下のようなインタフェースを自動生成することになります。
public interface ISample {
public void setValue(java.lang.String value);
public java.lang.String getValue();
}
ではアノテーションプロセッサを作成していきましょう。ここではAbstractionアノテーションを処理するので,AbstractionProcessorクラスとしました。パッケージはnet.javainthebox.annotationとしました。同様にAbstractionアノテーション,AbstractionMethodアノテーションもnet.javainthebox.annotationパッケージとしています。
まず,アノテーションプロセッサの基本的な部分を作ってしまいましょう。前々回に紹介したようにアノテーションプロセッサはjavax.annotation.processing.AbstractProcessorクラスのサブクラスとして定義し,processメソッドをオーバーライドします。
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes({
"net.javainthebox.annotation.Abstraction",
"net.javainthebox.annotation.AbstractionMethod"
})
public class AbstractionProc extends AbstractProcessor {
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnvironment) {
}
}
ここでは,Java SE 6で作成するので,javax.annotation.processing.SupportedSourceVersionアノテーションにはjavax.lang.model.SourceVersioon.RELEASE_6を指定しました。また,処理するアノテーションはAbstractionアノテーションとAbstractionMethodアノテーションなので,javax.annotation.processing.SupportAnnotationTypesには赤字で示したように2つのアノテーションを列挙しています。