AndroidのLogを改良しよう2
Unityで遊ぼうかと思ったけど、需要ありそうな気がするのでこっち優先する. 今日は、javaのソースコードレベルのアノテーションを調べて実験してみる。
RetentionPolicy.SOURCE
javaのアノテーションを記述する際にリテンションポリシーを3種設定することができる。
- RetentionPolicy.CLASS
- デフォルトで指定される。classファイルには含まれるが、vmにロードされるときには棄却される
- RetentionPolicy.RUNTIME
- 実行時にも参照が可能。classファイルにも、vmロード時にも入っている.
- RetentionPolicy.SOURCE
- classファイルにも含まれない。classファイル生成時にか参照できない.
RetentionPolicy.SOURCE < RetentionPolicy.CLASS < RetensionPolicy.RUNTIMEの順で強度の強いアノテーションとなる.
今回目指すのは、Lombokのような@Getter @Setterとうつだけで、getter/setterのソースコードが生成されるようなタイプ. つまりRetentionPolicy.SOURCEを用いる。
参考: - http://docs.oracle.com/javase/7/docs/api/java/lang/annotation/RetentionPolicy.html
AbstractProcessor
javaでAnnotationからソースを生成するには、AbstractProcessorを利用するようだ.
以下のような構成.
lib
├── build.gradle
└── src
└── main
├── AndroidManifest.xml
├── java
│ └── me
│ └── mattak
│ └── footprint
│ ├── Footprint.java
│ └── processor
│ └── FootprintProcessor.java
└── resources
└── META-INF
└── services
└── javax.annotation.processing.Processor
ポイントは, resources/META-INF/services/javax.annotation.processing.ProcessorにAbstractProcessorを継承したProcessorの場所を記述することらしい。
javax.annotation.processing.Processor
me.mattak.footprint.processor.FootprintProcessor
ためしにProcessor内で何か出力してみる.
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes({"*"})
public class FootprintProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
Messager messager = processingEnv.getMessager();
for (TypeElement te : annotations) {
for (Element e : roundEnv.getElementsAnnotatedWith(te)) {
messager.printMessage(Diagnostic.Kind.NOTE, "Printing: " + e.toString());
System.out.println("[annotation] " + e + "," + annotations);
}
}
return true;
}
}
このプロジェクトをimportしてなにかannotationをつけてみると、きちんとメッセージが出力された。
$ gradle clean assemble ~/project/Footprint [master]
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Relying on packaging to define the extension of the main artifact has been deprecated and is scheduled to be removed in Gradle 2.0
:example:clean
:lib:clean
:example:compileDebugNdk
:example:preBuild
:example:preDebugBuild
:example:checkDebugManifest
:example:preReleaseBuild
:lib:compileJava
:lib:processResources
:lib:classes
:lib:jar
:example:prepareComAndroidSupportAppcompatV71800Library
:example:prepareDebugDependencies
:example:compileDebugAidl
:example:compileDebugRenderscript
:example:generateDebugBuildConfig
:example:mergeDebugAssets
:example:generateDebugResValues UP-TO-DATE
:example:generateDebugResources
:example:mergeDebugResources
:example:processDebugManifest
:example:processDebugResources
:example:generateDebugSources
:example:compileDebugJava
注:Printing: me.mattak.footprint.example.MainActivity
[annotation] me.mattak.footprint.example.MainActivity,[me.mattak.footprint.Footprint]
注:Printing: me.mattak.footprint.example.TestFile
[annotation] me.mattak.footprint.example.TestFile,[me.mattak.footprint.Footprint]
:example:preDexDebug
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
:example:dexDebug
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
:example:processDebugJavaRes UP-TO-DATE
:example:validateDebugSigning
:example:packageDebug
:example:assembleDebug
:example:checkReleaseManifest
:example:prepareReleaseDependencies
:example:compileReleaseAidl
:example:compileReleaseRenderscript
:example:generateReleaseBuildConfig
:example:mergeReleaseAssets
:example:generateReleaseResValues UP-TO-DATE
:example:generateReleaseResources
:example:mergeReleaseResources
:example:processReleaseManifest
:example:processReleaseResources
:example:generateReleaseSources
:example:compileReleaseJava
注:Printing: me.mattak.footprint.example.MainActivity
[annotation] me.mattak.footprint.example.MainActivity,[me.mattak.footprint.Footprint]
注:Printing: me.mattak.footprint.example.TestFile
[annotation] me.mattak.footprint.example.TestFile,[me.mattak.footprint.Footprint]
:example:lintVitalRelease
:example:compileReleaseNdk
:example:preDexRelease
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
:example:dexRelease
Picked up _JAVA_OPTIONS: -Dfile.encoding=UTF-8
:example:processReleaseJavaRes UP-TO-DATE
:example:packageRelease
:example:assembleRelease
:example:assemble
:lib:assemble
BUILD SUCCESSFUL
Total time: 51.852 secs
とりあえず、RetentionPolicy.SOURCEのannotationの作用確認ができた。 ここから、元ソースにどうやってコードを介入させるのかよくわからんので、また調べて書く。