2012-05-12 3 views
5

アノテーションプロセッサを初めて作成するときに、これをプログラムで呼び出す必要があります。出来ますか?プログラムでアノテーションプロセッサを呼び出す

私はプロセッサのための小さなコードを書かれている:私はプロセスメソッドを呼び出したい場合は

@SupportedAnnotationTypes({"app.dev.ems.support.annotation.HBMModel"}) 
public class HBMModelProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { 
     Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(HBMModel.class); 
     System.out.println(elements); 
     return true; 
    } 

} 

は今、私はこれをどのように行うことができますか?

HBMModelProcessor modelProcessor = new HBMModelProcessor(); 
modelProcessor.process(annotations, roundEnv) 

どのような情報も私には非常に役立ちます。

ありがとうございました。

答えて

1

あなたはこのように、同じプロセス内で、プログラムで注釈プロセッサとJavaコンパイラを呼び出すことができます。

import com.sun.tools.javac.processing.PrintingProcessor; 
import fi.jumi.actors.generator.JavaSourceFromString; 
import org.junit.*; 
import org.junit.rules.TemporaryFolder; 

import javax.annotation.processing.Processor; 
import javax.tools.*; 
import javax.tools.JavaCompiler.CompilationTask; 
import java.io.IOException; 
import java.util.Arrays; 

import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.Matchers.is; 

public class ExampleTest { 

    @Rule 
    public final TemporaryFolder tempDir = new TemporaryFolder(); 

    @Test 
    public void example() throws IOException { 
     JavaFileObject src = new JavaSourceFromString(
       "com.example.GuineaPig", 
       "package com.example;\n" + 
       "public interface GuineaPig {\n" + 
       " void foo();\n" + 
       "}" 
     ); 
     compile(new PrintingProcessor(), src); 
    } 

    private void compile(Processor processor, JavaFileObject... compilationUnits) throws IOException { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); 
     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null); 
     fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tempDir.getRoot())); 

     CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, Arrays.asList(compilationUnits)); 
     task.setProcessors(Arrays.asList(
       processor 
     )); 
     boolean success = task.call(); 
     for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) { 
      System.err.println(diagnostic); 
     } 
     assertThat("compile succeeded", success, is(true)); 
    } 
} 

をあなたはsetProcessorsへの呼び出しを削除すると、それが上のMETA-INF/services/javax.annotation.processing.Processorファイルに基づいて自動的に注釈プロセッサを検出しますクラスパス。

3

これはmy answer to a similar questionへのリンクです。

あなたの質問にあなたが示唆する方法で注釈処理を行うことができますが、どうにかしてannotationsroundEnvを生成する必要があります。

注釈処理の意図された使用は、コンパイル中です。 2段階のコンパイルプロセスをお勧めします。

  1. 通常の方法でアノテーションプロセッサと関連ファイルをコンパイルします。
  2. (注釈処理をサポートするコンパイラを使用して)他のファイルをコンパイルします。あなたは、コンパイラにいくつかの引数を持っていることがあります。プロセッサパス、プロセッサのクラス名を、など

コンパイラはannotationsroundEnv変数とあなたのプロセッサのインスタンスを生成します。 (ほとんどのコンパイラでは、あなたのプロセッサは公開されていて、publicコンストラクタが必要です)。コンパイラはprocessメソッドを呼び出します。

+0

返信いただきありがとうございます。だから、これらの2つの変数 'annotations'と' roundEnv'を得る方法はありませんか? –

+0

もちろん、 'annotations'と' roundEnv'を得る方法があります。 'annotations = new HashSet ();注釈。あなたのプロセッサを単体テストしようとしていますか?(あなたの注釈* /);および 'roundEnv = new RoundEnvironment(){/ * implementation * /}あなたはおそらく嘲笑フレームワークを使用することができます。 – emory

+0

@emory、私はアノテーションプロセッサをユニットテストしたいと思っています。これは最初のGoogleエントリなので、サンプルを歓迎します。 – Snicolas

関連する問題